更多提醒

This commit is contained in:
snltty
2024-07-20 15:32:21 +08:00
parent 7a039d4b1c
commit ec0da6b0d4
91 changed files with 702 additions and 558 deletions

View File

@@ -48,18 +48,15 @@ jobs:
env: env:
GITHUB_TOKEN: '${{ secrets.ACTIONS_TOKEN }}' GITHUB_TOKEN: '${{ secrets.ACTIONS_TOKEN }}'
with: with:
tag_name: v1.1.2.2 tag_name: v1.1.2.3
release_name: v1.1.2.2.${{ steps.date.outputs.today }} release_name: v1.1.2.3.${{ steps.date.outputs.today }}
draft: false draft: false
prerelease: false prerelease: false
body: | body: |
1. 更新配置同步方式,以版本同步 1. 修复虚拟网卡添加路由错误
2. 设备列表搜索,按 设备名/设备IP/虚拟网卡IP/端口转发端口和IP 搜索 2. 自动更新,客户端和服务端
3. 端口转发配置复制可以将A转发到B的配置复制给C转发到B 3. 更多的消息提醒,需要重启时提醒
4. 服务器代理穿透配置复制 4. 请更新服务端
5. 修复虚拟网卡添加路由错误
6. 自动更新,管理所有客户端更新
7. 请更新服务端
- name: upload win x64 - name: upload win x64
id: upload-win-x64 id: upload-win-x64

View File

@@ -15,8 +15,8 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl> <PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl> <RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<Version>1.1.2</Version> <Version>1.1.2</Version>
<AssemblyVersion>1.1.2.2</AssemblyVersion> <AssemblyVersion>1.1.2.3</AssemblyVersion>
<FileVersion>1.1.2.2</FileVersion> <FileVersion>1.1.2.3</FileVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType> <DebugType>full</DebugType>

View File

@@ -22,8 +22,8 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl> <PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl> <RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>snltty service</PackageReleaseNotes> <PackageReleaseNotes>snltty service</PackageReleaseNotes>
<AssemblyVersion>1.1.2.2</AssemblyVersion> <AssemblyVersion>1.1.2.3</AssemblyVersion>
<FileVersion>1.1.2.2</FileVersion> <FileVersion>1.1.2.3</FileVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -17,8 +17,8 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl> <PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl> <RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker tunnel</PackageReleaseNotes> <PackageReleaseNotes>linker tunnel</PackageReleaseNotes>
<AssemblyVersion>1.1.2.2</AssemblyVersion> <AssemblyVersion>1.1.2.3</AssemblyVersion>
<FileVersion>1.1.2.2</FileVersion> <FileVersion>1.1.2.3</FileVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -10,8 +10,6 @@ using System.Net.Sockets;
using System.Security.Authentication; using System.Security.Authentication;
using System.Text; using System.Text;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using System.Runtime.InteropServices;
using System.IO;
namespace linker.tunnel.transport namespace linker.tunnel.transport
{ {
@@ -664,7 +662,6 @@ namespace linker.tunnel.transport
{ {
if (OperatingSystem.IsWindows() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) if (OperatingSystem.IsWindows() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{ {
TestQuic();
if (QuicListener.IsSupported == false) if (QuicListener.IsSupported == false)
{ {
LoggerHelper.Instance.Error($"msquic not supported, need win11+,or linux, or try to restart linker"); LoggerHelper.Instance.Error($"msquic not supported, need win11+,or linux, or try to restart linker");
@@ -729,28 +726,7 @@ namespace linker.tunnel.transport
} }
} }
} }
private void TestQuic()
{
if (OperatingSystem.IsWindows())
{
if (QuicListener.IsSupported == false)
{
try
{
if (File.Exists("msquic-openssl.dll"))
{
LoggerHelper.Instance.Info($"copy msquic-openssl.dll -> msquic.dll");
File.Move("msquic-openssl.dll", "msquic.dll", true);
}
}
catch (Exception)
{
}
}
}
}
sealed class ListenAsyncToken sealed class ListenAsyncToken
{ {
/// <summary> /// <summary>
@@ -773,10 +749,5 @@ namespace linker.tunnel.transport
} }
} }
enum ListenStep : byte
{
Auth = 0,
Forward = 1
}
} }
} }

View File

@@ -157,6 +157,14 @@ span.split-pad10 {
color: red; color: red;
} }
.green {
color: green;
}
.yellow {
color: #e68906
}
.scrollbar, .scrollbar,
.scrollbar-1, .scrollbar-1,
.scrollbar-4, .scrollbar-4,
@@ -214,6 +222,9 @@ span.split-pad10 {
--el-color-primary-dark-2: var(--el-color-success-dark-2) !important; --el-color-primary-dark-2: var(--el-color-success-dark-2) !important;
} }
.el-table .cell {
overflow: visible !important;
}
.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar { .el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar {
background: #f5f5f5 background: #f5f5f5

View File

@@ -56,8 +56,11 @@ export default {
setup(props) { setup(props) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();
const updaterCurrent = ref({Version: '', Status: 0, Length: 0, Current: 0}); const updaterCurrent = ref({Version: '', Msg: [], DateTime: '', Status: 0, Length: 0, Current: 0});
const updaterServer = ref({Version: '', Status: 0, Length: 0, Current: 0}); const updaterServer = ref({Version: '', Status: 0, Length: 0, Current: 0});
const updaterMsg = computed(()=>{
return `${updaterCurrent.value.Version}->${updaterCurrent.value.DateTime}\n${updaterCurrent.value.Msg.map((value,index)=>`${index+1}${value}`).join('\n')}`;
});
const state = reactive({ const state = reactive({
show: false, show: false,
@@ -75,10 +78,12 @@ export default {
const _getUpdaterCurrent = ()=>{ const _getUpdaterCurrent = ()=>{
getUpdaterCurrent().then((res)=>{ getUpdaterCurrent().then((res)=>{
updaterCurrent.value.DateTime = res.DateTime;
updaterCurrent.value.Version = res.Version; updaterCurrent.value.Version = res.Version;
updaterCurrent.value.Status = res.Status; updaterCurrent.value.Status = res.Status;
updaterCurrent.value.Length = res.Length; updaterCurrent.value.Length = res.Length;
updaterCurrent.value.Current = res.Current; updaterCurrent.value.Current = res.Current;
updaterCurrent.value.Msg = res.Msg;
setTimeout(()=>{ setTimeout(()=>{
_getUpdaterCurrent(); _getUpdaterCurrent();
},1000); },1000);
@@ -111,8 +116,8 @@ export default {
} }
if(updaterServer.value.Status <= 2) { if(updaterServer.value.Status <= 2) {
return state.version != updaterCurrent.value.Version return state.version != updaterCurrent.value.Version
? `不是最新版本(${updaterCurrent.value.Version}),建议更新` ? `不是最新版本(${updaterCurrent.value.Version}),建议更新\n${updaterMsg.value}`
: '是最新版本,但我无法阻止你喜欢更新' : `是最新版本,但我无法阻止你喜欢更新\n${updaterMsg.value}`
} }
return { return {
3:'正在下载', 3:'正在下载',
@@ -216,12 +221,8 @@ export default {
} }
a.download{ a.download{
&.green{color:green}
&.red{color:red}
&.yellow{color:#e68906}
.el-icon{ .el-icon{
font-weight:bold; font-weight:bold;
&.yellow{color:#e68906}
&.loading{ &.loading{
animation:loading 1s linear infinite; animation:loading 1s linear infinite;
} }

View File

@@ -2,8 +2,6 @@ import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
// import VConsole from 'vconsole';
// new VConsole();
const app = createApp(App); const app = createApp(App);
@@ -14,17 +12,4 @@ import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/display.css' 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 {
ArrowDown, Top, Bottom, Delete, Plus, Select, Refresh, Search
} from '@element-plus/icons-vue'
app.component(ArrowDown.name, ArrowDown);
app.component(Top.name, Top);
app.component(Bottom.name, Bottom);
app.component(Delete.name, Delete);
app.component(Plus.name, Plus);
app.component(Select.name, Select);
app.component(Refresh.name, Refresh);
app.component(Search.name, Search);
app.use(ElementPlus, { size: 'default' }).use(router).mount('#app'); app.use(ElementPlus, { size: 'default' }).use(router).mount('#app');

View File

@@ -54,9 +54,11 @@
import { reactive, watch,computed } from 'vue'; import { reactive, watch,computed } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { useConnections, useForwardConnections, useTuntapConnections } from './connections'; import { useConnections, useForwardConnections, useTuntapConnections } from './connections';
import { Delete } from '@element-plus/icons-vue';
export default { export default {
props: ['modelValue'], props: ['modelValue'],
emits: ['change','update:modelValue'], emits: ['change','update:modelValue'],
components: {Delete},
setup(props, { emit }) { setup(props, { emit }) {
const connections = useConnections(); const connections = useConnections();
@@ -97,5 +99,4 @@ export default {
<style lang="stylus" scoped> <style lang="stylus" scoped>
.head{padding-bottom:1rem} .head{padding-bottom:1rem}
.green{color:green}
</style> </style>

View File

@@ -18,7 +18,7 @@
<p class="flex"> <p class="flex">
<span>{{ scope.row.IP }}</span> <span>{{ scope.row.IP }}</span>
<span class="flex-1"></span> <span class="flex-1"></span>
<a href="javascript:;" class="download" title="下载更新" @click="handleUpdate(scope.row)" :title="updateText(scope.row)" :class="updateColor(scope.row)"> <a href="javascript:;" class="download" @click="handleUpdate(scope.row)" :title="updateText(scope.row)" :class="updateColor(scope.row)">
<span> <span>
<span>{{scope.row.Version}}</span> <span>{{scope.row.Version}}</span>
<template v-if="updater.list[scope.row.MachineId]"> <template v-if="updater.list[scope.row.MachineId]">
@@ -65,16 +65,21 @@ export default {
const updater = useUpdater(); const updater = useUpdater();
const serverVersion = computed(()=>globalData.value.signin.Version); const serverVersion = computed(()=>globalData.value.signin.Version);
const updaterVersion = computed(()=>updater.value.current.Version); const updaterVersion = computed(()=>updater.value.current.Version);
const updaterMsg = computed(()=>{
return `${updaterVersion.value}->${updater.value.current.DateTime}\n${updater.value.current.Msg.map((value,index)=>`${index+1}${value}`).join('\n')}`;
});
const updateText = (row)=>{ const updateText = (row)=>{
if(!updater.value.list[row.MachineId]){ if(!updater.value.list[row.MachineId]){
return '未检测到更新'; return '未检测到更新';
} }
if(updater.value.list[row.MachineId].Status <= 2) { if(updater.value.list[row.MachineId].Status <= 2) {
return row.Version != serverVersion.value return row.Version != serverVersion.value
? `与服务器版本(${serverVersion.value})不一致,建议更新` ? `与服务器版本(${serverVersion.value})不一致,建议更新`
: updaterVersion.value != row.Version : updaterVersion.value != row.Version
? `不是最新版本(${updaterVersion.value}),建议更新` : '是最新版本,但我无法阻止你喜欢更新' ? `不是最新版本(${updaterVersion.value}),建议更新\n${updaterMsg.value}`
: `是最新版本,但我无法阻止你喜欢更新\n${updaterMsg.value}`
} }
return { return {
3:'正在下载', 3:'正在下载',
@@ -170,12 +175,8 @@ a{
a.download{ a.download{
margin-left:.6rem margin-left:.6rem
&.green{color:green}
&.red{color:red}
&.yellow{color:#e68906}
.el-icon{ .el-icon{
vertical-align:middle;font-weight:bold; vertical-align:middle;font-weight:bold;
&.yellow{color:#e68906}
&.loading{ &.loading{
animation:loading 1s linear infinite; animation:loading 1s linear infinite;
} }

View File

@@ -25,7 +25,7 @@
</ul> </ul>
</div> </div>
</template> </template>
<template v-else-if="!scope.row.isSelf"> <template v-else>
<div> <div>
<ul class="list sforward"> <ul class="list sforward">
<template v-if="sforward.list && sforward.list.length > 0"> <template v-if="sforward.list && sforward.list.length > 0">
@@ -48,7 +48,6 @@
</ul> </ul>
</div> </div>
</template> </template>
<template v-else>--</template>
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
@@ -83,6 +82,5 @@ a{
text-decoration: underline; text-decoration: underline;
font-weight:bold; font-weight:bold;
} }
span.green,a.green{color:green}
span.error{color:red} span.error{color:red}
</style> </style>

View File

@@ -100,13 +100,13 @@
import { onMounted, onUnmounted, reactive, watch } from 'vue'; import { onMounted, onUnmounted, reactive, watch } from 'vue';
import { getForwardInfo, removeForwardInfo, addForwardInfo ,getForwardIpv4,testTargetForwardInfo,testListenForwardInfo } from '@/apis/forward' import { getForwardInfo, removeForwardInfo, addForwardInfo ,getForwardIpv4,testTargetForwardInfo,testListenForwardInfo } from '@/apis/forward'
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import {WarnTriangleFilled} from '@element-plus/icons-vue' import {WarnTriangleFilled,Delete} from '@element-plus/icons-vue'
import { injectGlobalData } from '@/provide'; import { injectGlobalData } from '@/provide';
import { useForward } from './forward'; import { useForward } from './forward';
export default { export default {
props: ['data','modelValue'], props: ['data','modelValue'],
emits: ['update:modelValue'], emits: ['update:modelValue'],
components:{WarnTriangleFilled}, components:{WarnTriangleFilled,Delete},
setup(props, { emit }) { setup(props, { emit }) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();

View File

@@ -5,15 +5,7 @@
<Tunnel @edit="handleTunnelEdit" @refresh="handleTunnelRefresh" @connections="handleTunnelConnections"></Tunnel> <Tunnel @edit="handleTunnelEdit" @refresh="handleTunnelRefresh" @connections="handleTunnelConnections"></Tunnel>
<Tuntap @edit="handleTuntapEdit" @refresh="handleTuntapRefresh"></Tuntap> <Tuntap @edit="handleTuntapEdit" @refresh="handleTuntapRefresh"></Tuntap>
<Forward @edit="_handleForwardEdit" @sedit="handleSForwardEdit"></Forward> <Forward @edit="_handleForwardEdit" @sedit="handleSForwardEdit"></Forward>
<el-table-column label="操作" width="54" fixed="right"> <Oper @refresh="handlePageRefresh"></Oper>
<template #default="scope">
<el-popconfirm v-if="scope.row.showDel" confirm-button-text="确认" cancel-button-text="取消" title="删除不可逆,是否确认?" @confirm="handleDel(scope.row.MachineId)">
<template #reference>
<el-button type="danger" size="small"><el-icon><Delete /></el-icon></el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table> </el-table>
<div class="page t-c"> <div class="page t-c">
<div class="page-wrap"> <div class="page-wrap">
@@ -36,6 +28,7 @@
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, onUnmounted, computed } from 'vue' import { reactive, onMounted, onUnmounted, computed } from 'vue'
import Oper from './Oper.vue'
import Device from './Device.vue' import Device from './Device.vue'
import DeviceEdit from './DeviceEdit.vue' import DeviceEdit from './DeviceEdit.vue'
import Tuntap from './Tuntap.vue' import Tuntap from './Tuntap.vue'
@@ -57,7 +50,7 @@ import { provideSforward } from './sforward'
import { provideDevices } from './devices' import { provideDevices } from './devices'
import { provideUpdater } from './updater' import { provideUpdater } from './updater'
export default { export default {
components: {Device,DeviceEdit,Tunnel,TunnelEdit,ConnectionsEdit, Tuntap,TuntapEdit, Forward,ForwardEdit,ForwardCopy,SForwardEdit,SForwardCopy }, components: {Oper,Device,DeviceEdit,Tunnel,TunnelEdit,ConnectionsEdit, Tuntap,TuntapEdit, Forward,ForwardEdit,ForwardCopy,SForwardEdit,SForwardCopy },
setup(props) { setup(props) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();
@@ -164,8 +157,6 @@ export default {
.home-list-wrap{ .home-list-wrap{
padding:1rem; padding:1rem;
.green{color:green;}
.page{padding-top:1rem} .page{padding-top:1rem}
.page-wrap{ .page-wrap{
display:inline-block; display:inline-block;

View File

@@ -0,0 +1,86 @@
<template>
<el-table-column label="操作" width="74" fixed="right">
<template #default="scope">
<el-dropdown size="small">
<div class="dropdown">
<!-- <span class="badge">1</span> -->
<span>操作</span>
<el-icon class="el-icon--right">
<ArrowDown />
</el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-if="scope.row.showReboot" @click="handleExit(scope.row.MachineId,scope.row.MachineName)"><el-icon><SwitchButton /></el-icon> 重启</el-dropdown-item>
<el-dropdown-item v-if="scope.row.showDel" @click="handleDel(scope.row.MachineId,scope.row.MachineName)"><el-icon><Delete /></el-icon> 删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
</template>
<script>
import { signInDel } from '@/apis/signin';
import { exit } from '@/apis/updater';
import { Delete,SwitchButton,ArrowDown } from '@element-plus/icons-vue'
import { ElMessageBox } from 'element-plus';
export default {
emits:['refresh'],
components:{Delete,SwitchButton,ArrowDown},
setup (props,{emit}) {
const handleDel = (machineId,machineName)=>{
ElMessageBox.confirm(`确认删除[${machineName}]?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
signInDel(machineId).then(()=>{
emit('refresh');
});
}).catch(() => {});
}
const handleExit = (machineId,machineName)=>{
ElMessageBox.confirm(`确认关闭[${machineName}]?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
exit(machineId).then(()=>{
emit('refresh');
})
}).catch(() => {});
}
return {handleDel,handleExit}
}
}
</script>
<style lang="stylus" scoped>
.dropdown{
border:1px solid #ddd;
padding:.4rem;
font-size:1.3rem;
border-radius:.4rem;
position:relative;
.el-icon{
vertical-align:middle;
}
.badge{
position:absolute;
right:-1rem;
top:-50%;
border-radius:10px;
background-color:#f1ae05;
color:#fff;
padding:.2rem .6rem;
font-size:1.2rem;
}
}
</style>

View File

@@ -89,13 +89,13 @@
import { onMounted, onUnmounted, reactive, watch } from 'vue'; import { onMounted, onUnmounted, reactive, watch } from 'vue';
import { getSForwardInfo, removeSForwardInfo, addSForwardInfo,testLocalSForwardInfo } from '@/apis/sforward' import { getSForwardInfo, removeSForwardInfo, addSForwardInfo,testLocalSForwardInfo } from '@/apis/sforward'
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import {WarnTriangleFilled} from '@element-plus/icons-vue' import {WarnTriangleFilled,Delete} from '@element-plus/icons-vue'
import { injectGlobalData } from '@/provide'; import { injectGlobalData } from '@/provide';
import { useSforward } from './sforward'; import { useSforward } from './sforward';
export default { export default {
props: ['data','modelValue'], props: ['data','modelValue'],
emits: ['update:modelValue'], emits: ['update:modelValue'],
components:{WarnTriangleFilled}, components:{WarnTriangleFilled,Delete},
setup(props, { emit }) { setup(props, { emit }) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();

View File

@@ -2,17 +2,18 @@
<el-table-column prop="tunnel" label="隧道" width="90"> <el-table-column prop="tunnel" label="隧道" width="90">
<template #default="scope"> <template #default="scope">
<div v-if="tunnel.list[scope.row.MachineId]"> <div v-if="tunnel.list[scope.row.MachineId]">
<p> <a href="javascript:;" class="a-line"
<a href="javascript:;" class="a-line" @click="handleTunnel(tunnel.list[scope.row.MachineId])"> :class="{yellow:tunnel.list[scope.row.MachineId].NeedReboot}"
:title="tunnel.list[scope.row.MachineId].NeedReboot?'需要重启':''"
@click="handleTunnel(tunnel.list[scope.row.MachineId])">
<span>网关 : {{tunnel.list[scope.row.MachineId].RouteLevel}} + {{tunnel.list[scope.row.MachineId].RouteLevelPlus}}</span> <span>网关 : {{tunnel.list[scope.row.MachineId].RouteLevel}} + {{tunnel.list[scope.row.MachineId].RouteLevelPlus}}</span>
</a> </a>
</p>
</div> </div>
<p> <div>
<a href="javascript:;" class="a-line" @click="handleConnections(scope.row.MachineId)"> <a href="javascript:;" class="a-line" @click="handleConnections(scope.row.MachineId)">
<span>连接数 : {{connectionCount(scope.row.MachineId)}}</span> <span>连接数 : {{connectionCount(scope.row.MachineId)}}</span>
</a> </a>
</p> </div>
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
@@ -54,6 +55,6 @@ export default {
} }
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.green{color:green;}
.el-switch.is-disabled{opacity :1;} .el-switch.is-disabled{opacity :1;}
</style> </style>

View File

@@ -82,6 +82,5 @@ export default {
} }
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.green{color:green;}
.el-switch.is-disabled{opacity :1;} .el-switch.is-disabled{opacity :1;}
</style> </style>

View File

@@ -9,7 +9,7 @@
<template v-if="tuntap.list[scope.row.MachineId].Error"> <template v-if="tuntap.list[scope.row.MachineId].Error">
<el-popover placement="top" title="msg" width="20rem" trigger="hover" :content="tuntap.list[scope.row.MachineId].Error"> <el-popover placement="top" title="msg" width="20rem" trigger="hover" :content="tuntap.list[scope.row.MachineId].Error">
<template #reference> <template #reference>
<strong class="error">{{ tuntap.list[scope.row.MachineId].IP }}</strong> <strong class="red">{{ tuntap.list[scope.row.MachineId].IP }}</strong>
</template> </template>
</el-popover> </el-popover>
</template> </template>
@@ -67,8 +67,6 @@ export default {
} }
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.green{color:green;}
.error{color:red;}
.el-switch.is-disabled{opacity :1;} .el-switch.is-disabled{opacity :1;}
.el-input{ .el-input{
width:8rem; width:8rem;

View File

@@ -39,10 +39,11 @@ import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { reactive, ref, watch } from 'vue'; import { reactive, ref, watch } from 'vue';
import { useTuntap } from './tuntap'; import { useTuntap } from './tuntap';
import { Delete, Plus } from '@element-plus/icons-vue'
export default { export default {
props: ['modelValue'], props: ['modelValue'],
emits: ['change','update:modelValue'], emits: ['change','update:modelValue'],
components: {Delete,Plus},
setup(props, { emit }) { setup(props, { emit }) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();
@@ -117,6 +118,5 @@ export default {
} }
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.green{color:green;}
.el-switch.is-disabled{opacity :1;} .el-switch.is-disabled{opacity :1;}
</style> </style>

View File

@@ -25,6 +25,7 @@ export const provideDevices = () => {
devices.page.Count = res.Count; devices.page.Count = res.Count;
for (let j in res.List) { for (let j in res.List) {
res.List[j].showDel = machineId.value != res.List[j].MachineId && res.List[j].Connected == false; res.List[j].showDel = machineId.value != res.List[j].MachineId && res.List[j].Connected == false;
res.List[j].showReboot = res.List[j].Connected;
res.List[j].isSelf = machineId.value == res.List[j].MachineId; res.List[j].isSelf = machineId.value == res.List[j].MachineId;
} }
devices.page.List = res.List.sort((a, b) => b.Connected - a.Connected); devices.page.List = res.List.sort((a, b) => b.Connected - a.Connected);
@@ -41,6 +42,7 @@ export const provideDevices = () => {
item.LastSignIn = res.List[j].LastSignIn; item.LastSignIn = res.List[j].LastSignIn;
item.Args = res.List[j].Args; item.Args = res.List[j].Args;
item.showDel = machineId.value != res.List[j].MachineId && res.List[j].Connected == false; item.showDel = machineId.value != res.List[j].MachineId && res.List[j].Connected == false;
item.showReboot = res.List[j].Connected;
item.isSelf = machineId.value == res.List[j].MachineId; item.isSelf = machineId.value == res.List[j].MachineId;
} }
} }

View File

@@ -8,18 +8,21 @@ export const provideUpdater = () => {
const updater = ref({ const updater = ref({
timer: 0, timer: 0,
list: {}, list: {},
current: { Version: '', Status: 0, Length: 0, Current: 0 } current: { Version: '', Msg: [], DateTime: '', Status: 0, Length: 0, Current: 0 }
}); });
provide(updaterSymbol, updater); provide(updaterSymbol, updater);
const _getUpdater = () => { const _getUpdater = () => {
if (globalData.value.api.connected) { if (globalData.value.api.connected) {
getUpdater().then((res) => { getUpdater().then((res) => {
console.log(res);
const self = Object.values(res).filter(c => !!c.Version)[0]; const self = Object.values(res).filter(c => !!c.Version)[0];
if (self) { if (self) {
updater.value.current.DateTime = self.DateTime;
updater.value.current.Version = self.Version; updater.value.current.Version = self.Version;
updater.value.current.Status = self.Status; updater.value.current.Status = self.Status;
updater.value.current.Length = self.Length; updater.value.current.Length = self.Length;
updater.value.current.Current = self.Current; updater.value.current.Current = self.Current;
updater.value.current.Msg = self.Msg;
} }
updater.value.list = res; updater.value.list = res;
updater.value.timer = setTimeout(_getUpdater, 800); updater.value.timer = setTimeout(_getUpdater, 800);

View File

@@ -45,11 +45,12 @@ import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { computed, inject, onMounted, reactive } from 'vue' import { computed, inject, onMounted, reactive } from 'vue'
import Version from './Version.vue'; import Version from './Version.vue';
import { Delete,Plus } from '@element-plus/icons-vue';
export default { export default {
label:'打洞排除IP', label:'打洞排除IP',
name:'excludeIP', name:'excludeIP',
order:3, order:3,
components:{Version}, components:{Version,Delete,Plus},
setup(props) { setup(props) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();
const state = reactive({ const state = reactive({

View File

@@ -83,11 +83,12 @@ import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { computed, inject, onMounted, reactive } from 'vue' import { computed, inject, onMounted, reactive } from 'vue'
import Version from './Version.vue'; import Version from './Version.vue';
import { Delete,Plus,Top,Bottom } from '@element-plus/icons-vue';
export default { export default {
label:'中继服务器', label:'中继服务器',
name:'relayServers', name:'relayServers',
order:4, order:4,
components:{Version}, components:{Version,Delete,Plus,Top,Bottom},
setup(props) { setup(props) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();
const state = reactive({ const state = reactive({

View File

@@ -52,11 +52,12 @@ import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { computed, inject, reactive } from 'vue' import { computed, inject, reactive } from 'vue'
import Version from './Version.vue'; import Version from './Version.vue';
import { Delete,Plus,Select } from '@element-plus/icons-vue';
export default { export default {
label:'信标服务器', label:'信标服务器',
name:'signInServers', name:'signInServers',
order:0, order:0,
components:{Version}, components:{Version,Delete,Plus,Select },
setup(props) { setup(props) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();
const state = reactive({ const state = reactive({

View File

@@ -46,11 +46,12 @@ import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { computed, inject, onMounted, reactive } from 'vue' import { computed, inject, onMounted, reactive } from 'vue'
import Version from './Version.vue'; import Version from './Version.vue';
import { Delete,Plus,Top,Bottom } from '@element-plus/icons-vue';
export default { export default {
label:'打洞协议', label:'打洞协议',
name:'transports', name:'transports',
order:2, order:2,
components:{Version}, components:{Version, Delete,Plus,Top,Bottom},
setup(props) { setup(props) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();
const state = reactive({ const state = reactive({

View File

@@ -78,13 +78,14 @@
import { setTunnelServers,getTunnelTypes } from '@/apis/tunnel'; import { setTunnelServers,getTunnelTypes } from '@/apis/tunnel';
import { injectGlobalData } from '@/provide'; import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { computed, inject, onMounted, reactive } from 'vue' import { computed, onMounted, reactive } from 'vue'
import Version from './Version.vue'; import Version from './Version.vue';
import { Delete,Plus,Top,Bottom } from '@element-plus/icons-vue';
export default { export default {
label:'端口服务器', label:'端口服务器',
name:'tunnelServers', name:'tunnelServers',
order:1, order:1,
components:{Version}, components:{Version,Delete,Plus,Top,Bottom},
setup(props) { setup(props) {
const globalData = injectGlobalData(); const globalData = injectGlobalData();
const list = ((globalData.value.config.Running.Tunnel || {Servers:[]}).Servers || []).sort((a,b)=>a.Disabled - b.Disabled); const list = ((globalData.value.config.Running.Tunnel || {Servers:[]}).Servers || []).sort((a,b)=>a.Disabled - b.Disabled);

View File

@@ -25,8 +25,8 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl> <PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl> <RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker</PackageReleaseNotes> <PackageReleaseNotes>linker</PackageReleaseNotes>
<AssemblyVersion>1.1.2.2</AssemblyVersion> <AssemblyVersion>1.1.2.3</AssemblyVersion>
<FileVersion>1.1.2.2</FileVersion> <FileVersion>1.1.2.3</FileVersion>
</PropertyGroup> </PropertyGroup>

View File

@@ -1,5 +1,4 @@
using linker.client.capi; using linker.config;
using linker.config;
using linker.libs; using linker.libs;
using linker.libs.api; using linker.libs.api;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;

View File

@@ -1,5 +1,4 @@
using linker.client.capi; using linker.config;
using linker.config;
using linker.startup; using linker.startup;
using linker.libs; using linker.libs;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;

View File

@@ -1,7 +1,7 @@
using linker.libs.api; using linker.libs.api;
using System.Reflection; using System.Reflection;
namespace linker.client.capi namespace linker.plugins.capi
{ {
public interface IApiClientController : IApiController public interface IApiClientController : IApiController
{ {

View File

@@ -1,7 +1,7 @@
using linker.server; using linker.plugins.messenger;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace linker.client namespace linker.plugins.client
{ {
/// <summary> /// <summary>
/// 登入对象 /// 登入对象

View File

@@ -1,15 +1,16 @@
using linker.client.args; using linker.client.config;
using linker.client.config;
using linker.config; using linker.config;
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using linker.server;
using linker.libs; using linker.libs;
using linker.libs.extends; using linker.libs.extends;
using MemoryPack; using MemoryPack;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using linker.plugins.client.args;
using linker.plugins.server;
using linker.plugins.messenger;
namespace linker.client namespace linker.plugins.client
{ {
/// <summary> /// <summary>
/// 登入 /// 登入
@@ -19,20 +20,20 @@ namespace linker.client
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly RunningConfig runningConfig; private readonly RunningConfig runningConfig;
private readonly FileConfig config; private readonly FileConfig config;
private readonly TcpServer tcpServer;
private readonly MessengerSender messengerSender; private readonly MessengerSender messengerSender;
private readonly MessengerResolver messengerResolver;
private readonly SignInArgsTransfer signInArgsTransfer; private readonly SignInArgsTransfer signInArgsTransfer;
private readonly RunningConfigTransfer runningConfigTransfer; private readonly RunningConfigTransfer runningConfigTransfer;
private string configKey = "signServers"; private string configKey = "signServers";
public ClientSignInTransfer(ClientSignInState clientSignInState, RunningConfig runningConfig, FileConfig config, TcpServer tcpServer, MessengerSender messengerSender, SignInArgsTransfer signInArgsTransfer, RunningConfigTransfer runningConfigTransfer) public ClientSignInTransfer(ClientSignInState clientSignInState, RunningConfig runningConfig, FileConfig config, MessengerSender messengerSender, MessengerResolver messengerResolver, SignInArgsTransfer signInArgsTransfer, RunningConfigTransfer runningConfigTransfer)
{ {
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;
this.runningConfig = runningConfig; this.runningConfig = runningConfig;
this.config = config; this.config = config;
this.tcpServer = tcpServer;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.messengerResolver = messengerResolver;
this.signInArgsTransfer = signInArgsTransfer; this.signInArgsTransfer = signInArgsTransfer;
this.runningConfigTransfer = runningConfigTransfer; this.runningConfigTransfer = runningConfigTransfer;
@@ -131,7 +132,7 @@ namespace linker.client
Socket socket = new Socket(remote.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); Socket socket = new Socket(remote.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.KeepAlive(); socket.KeepAlive();
await socket.ConnectAsync(remote).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false); await socket.ConnectAsync(remote).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
clientSignInState.Connection = await tcpServer.BeginReceive(socket).ConfigureAwait(false); clientSignInState.Connection = await messengerResolver.BeginReceiveClient(socket).ConfigureAwait(false);
return true; return true;
} }
@@ -169,6 +170,16 @@ namespace linker.client
clientSignInState.Connection?.Disponse(6); clientSignInState.Connection?.Disponse(6);
return false; return false;
} }
/// <summary>
/// 登出
/// </summary>
public void SignOut()
{
if (clientSignInState.Connected)
clientSignInState.Connection.Disponse(5);
}
/// <summary> /// <summary>
/// 获取服务器版本 /// 获取服务器版本
/// </summary> /// </summary>
@@ -189,14 +200,7 @@ namespace linker.client
clientSignInState.Version = "v1.0.0.0"; clientSignInState.Version = "v1.0.0.0";
} }
} }
/// <summary>
/// 登出
/// </summary>
public void SignOut()
{
if (clientSignInState.Connected)
clientSignInState.Connection.Disponse(5);
}
/// <summary> /// <summary>
/// 修改客户端名称 /// 修改客户端名称

View File

@@ -2,12 +2,10 @@
using linker.startup; using linker.startup;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Reflection; using System.Reflection;
using linker.client.args;
using linker.client.config;
using linker.config; using linker.config;
using linker.client.config.messenger; using linker.plugins.client.args;
namespace linker.client namespace linker.plugins.client
{ {
/// <summary> /// <summary>
/// 客户端插件 /// 客户端插件
@@ -17,16 +15,11 @@ namespace linker.client
public StartupLevel Level => StartupLevel.Bottom; public StartupLevel Level => StartupLevel.Bottom;
public string Name => "client"; public string Name => "client";
public bool Required => true; public bool Required => true;
public string[] Dependent => new string[] { "firewall", "signin", "serialize" }; public string[] Dependent => new string[] { "messenger", "firewall", "signin", "serialize", "config" };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;
public void AddClient(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies) public void AddClient(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
{ {
serviceCollection.AddSingleton<RunningConfig>();
serviceCollection.AddSingleton<RunningConfigTransfer>();
serviceCollection.AddSingleton<ConfigClientMessenger>();
serviceCollection.AddSingleton<RunningConfigApiController>();
serviceCollection.AddSingleton<SignInArgsTransfer>(); serviceCollection.AddSingleton<SignInArgsTransfer>();
serviceCollection.AddSingleton<ClientSignInState>(); serviceCollection.AddSingleton<ClientSignInState>();
@@ -46,7 +39,7 @@ namespace linker.client
public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies) public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
{ {
serviceCollection.AddSingleton<ConfigServerMessenger>();
} }
public void UseServer(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies) public void UseServer(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)
{ {

View File

@@ -1,4 +1,4 @@
namespace linker.client.args namespace linker.plugins.client.args
{ {
public interface ISignInArgs public interface ISignInArgs
{ {

View File

@@ -3,7 +3,7 @@ using linker.libs;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System; using System;
namespace linker.client.args namespace linker.plugins.client.args
{ {
public sealed class SignInArgsTransfer public sealed class SignInArgsTransfer
{ {
@@ -12,7 +12,7 @@ namespace linker.client.args
public SignInArgsTransfer(ServiceProvider serviceProvider, FileConfig config) public SignInArgsTransfer(ServiceProvider serviceProvider, FileConfig config)
{ {
var types = ReflectionHelper.GetInterfaceSchieves(typeof(ISignInArgs)); var types = ReflectionHelper.GetInterfaceSchieves(typeof(ISignInArgs));
startups = types.Select(c => serviceProvider.GetService(c) as ISignInArgs).Where(c=>c != null).ToList(); startups = types.Select(c => serviceProvider.GetService(c) as ISignInArgs).Where(c => c != null).ToList();
} }
public void Invoke(Dictionary<string, string> args) public void Invoke(Dictionary<string, string> args)

View File

@@ -1,8 +1,8 @@
using linker.config; using linker.config;
using linker.libs.api; using linker.libs.api;
using linker.libs.extends; using linker.libs.extends;
using linker.client.capi;
using linker.client.config; using linker.client.config;
using linker.plugins.capi;
namespace linker.plugins.config namespace linker.plugins.config
{ {

View File

@@ -1,4 +1,6 @@
using linker.config; using linker.client.config;
using linker.config;
using linker.plugins.config.messenger;
using linker.startup; using linker.startup;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Reflection; using System.Reflection;
@@ -11,19 +13,26 @@ namespace linker.plugins.config
public bool Required => true; public bool Required => true;
public StartupLevel Level => StartupLevel.Normal; public StartupLevel Level => StartupLevel.Normal;
public string[] Dependent => Array.Empty<string>(); public string[] Dependent => new string[] { "messenger", "signin", "serialize" };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;
public void AddClient(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies) public void AddClient(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
{ {
serviceCollection.AddSingleton<ConfigClientApiController>(); serviceCollection.AddSingleton<ConfigClientApiController>();
serviceCollection.AddSingleton<ConfigClientMessenger>();
serviceCollection.AddSingleton<RunningConfigApiController>();
serviceCollection.AddSingleton<RunningConfig>();
serviceCollection.AddSingleton<RunningConfigTransfer>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies) public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
{ {
serviceCollection.AddSingleton<ConfigServerMessenger>();
} }
public void UseClient(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies) public void UseClient(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)

View File

@@ -1,12 +1,13 @@
using linker.libs.api; using linker.libs.api;
using linker.client.capi;
using linker.libs.extends; using linker.libs.extends;
using linker.client.config;
using linker.plugins.capi;
namespace linker.client.config namespace linker.plugins.config
{ {
public sealed class RunningConfigApiController : IApiClientController public sealed class RunningConfigApiController : IApiClientController
{ {
private readonly RunningConfigTransfer runningConfigTransfer; private readonly RunningConfigTransfer runningConfigTransfer;
public RunningConfigApiController(RunningConfigTransfer runningConfigTransfer) public RunningConfigApiController(RunningConfigTransfer runningConfigTransfer)
{ {

View File

@@ -1,6 +1,7 @@
using linker.client.config.messenger; using linker.libs;
using linker.libs; using linker.plugins.client;
using linker.server; using linker.plugins.config.messenger;
using linker.plugins.messenger;
using MemoryPack; using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@@ -30,6 +31,7 @@ namespace linker.client.config
/// </summary> /// </summary>
public Memory<byte> Data { get; set; } public Memory<byte> Data { get; set; }
} }
/// <summary> /// <summary>
/// 配置同步 /// 配置同步
/// </summary> /// </summary>

View File

@@ -1,8 +1,9 @@
using linker.plugins.signin.messenger; using linker.client.config;
using linker.server; using linker.plugins.messenger;
using linker.plugins.signin.messenger;
using MemoryPack; using MemoryPack;
namespace linker.client.config.messenger namespace linker.plugins.config.messenger
{ {
public sealed class ConfigServerMessenger : IMessenger public sealed class ConfigServerMessenger : IMessenger
{ {

View File

@@ -1,4 +1,4 @@
namespace linker.client.config.messenger namespace linker.plugins.config.messenger
{ {
public enum ConfigMessengerIds : ushort public enum ConfigMessengerIds : ushort
{ {

View File

@@ -1,6 +1,5 @@
using linker.libs.api; using linker.libs.api;
using linker.libs.extends; using linker.libs.extends;
using linker.client.capi;
using linker.client.config; using linker.client.config;
using System.Net; using System.Net;
using linker.libs; using linker.libs;
@@ -8,9 +7,10 @@ using linker.plugins.forward.proxy;
using linker.tunnel.connection; using linker.tunnel.connection;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using linker.plugins.forward.messenger; using linker.plugins.forward.messenger;
using linker.server;
using linker.client;
using MemoryPack; using MemoryPack;
using linker.plugins.client;
using linker.plugins.capi;
using linker.plugins.messenger;
namespace linker.plugins.forward namespace linker.plugins.forward
{ {

View File

@@ -12,7 +12,7 @@ namespace linker.plugins.forward
public StartupLevel Level => StartupLevel.Normal; public StartupLevel Level => StartupLevel.Normal;
public string Name => "forward"; public string Name => "forward";
public bool Required => false; public bool Required => false;
public string[] Dependent => new string[] { "relay", "tunnel" }; public string[] Dependent => new string[] { "messenger", "relay", "tunnel", "signin", "serialize", "config" };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;

View File

@@ -1,10 +1,10 @@
using linker.client; using linker.client.config;
using linker.client.config;
using linker.libs; using linker.libs;
using linker.libs.extends; using linker.libs.extends;
using linker.plugins.client;
using linker.plugins.forward.messenger; using linker.plugins.forward.messenger;
using linker.plugins.forward.proxy; using linker.plugins.forward.proxy;
using linker.server; using linker.plugins.messenger;
using MemoryPack; using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net; using System.Net;

View File

@@ -1,6 +1,6 @@
using linker.client.config; using linker.client.config;
using linker.plugins.messenger;
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using linker.server;
using LiteDB; using LiteDB;
using MemoryPack; using MemoryPack;
using System.Net; using System.Net;

View File

@@ -2,7 +2,7 @@
using linker.libs.api; using linker.libs.api;
using linker.libs; using linker.libs;
using linker.config; using linker.config;
using linker.client.capi; using linker.plugins.capi;
namespace linker.plugins.logger namespace linker.plugins.logger
{ {

View File

@@ -6,7 +6,7 @@ using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
namespace linker.server namespace linker.plugins.messenger
{ {
public interface IConnectionReceiveCallback public interface IConnectionReceiveCallback
{ {
@@ -405,7 +405,7 @@ namespace linker.server
{ {
try try
{ {
await callback.Receive(this, packet, this.userToken).ConfigureAwait(false); await callback.Receive(this, packet, userToken).ConfigureAwait(false);
} }
catch (Exception) catch (Exception)
{ {
@@ -422,7 +422,7 @@ namespace linker.server
if (Environment.TickCount64 - ticks > 3000) if (Environment.TickCount64 - ticks > 3000)
{ {
pingStart = Environment.TickCount64; pingStart = Environment.TickCount64;
await SendPingPong(pingBytes).ConfigureAwait(false); await SendPingPong(pingBytes).ConfigureAwait(false);
} }
await Task.Delay(3000).ConfigureAwait(false); await Task.Delay(3000).ConfigureAwait(false);
@@ -442,7 +442,7 @@ namespace linker.server
data.Length.ToBytes(heartData); data.Length.ToBytes(heartData);
data.AsMemory().CopyTo(heartData.AsMemory(4)); data.AsMemory().CopyTo(heartData.AsMemory(4));
await semaphoreSlim.WaitAsync().ConfigureAwait(false); await semaphoreSlim.WaitAsync().ConfigureAwait(false);
try try
{ {
if (SourceStream != null) if (SourceStream != null)
@@ -451,7 +451,7 @@ namespace linker.server
} }
else else
{ {
await SourceSocket.SendAsync(heartData.AsMemory(0, length), cancellationTokenSource.Token).ConfigureAwait(false); await SourceSocket.SendAsync(heartData.AsMemory(0, length), cancellationTokenSource.Token).ConfigureAwait(false);
} }
} }
@@ -481,7 +481,7 @@ namespace linker.server
if (SourceStream != null) if (SourceStream != null)
await SourceStream.WriteAsync(data, cancellationTokenSourceWrite.Token).ConfigureAwait(false); await SourceStream.WriteAsync(data, cancellationTokenSourceWrite.Token).ConfigureAwait(false);
else else
await SourceSocket.SendAsync(data, cancellationTokenSourceWrite.Token).ConfigureAwait(false); await SourceSocket.SendAsync(data, cancellationTokenSourceWrite.Token).ConfigureAwait(false);
SendBytes += data.Length; SendBytes += data.Length;
ticks = Environment.TickCount64; ticks = Environment.TickCount64;
} }
@@ -505,7 +505,7 @@ namespace linker.server
} }
public override async Task<bool> SendAsync(byte[] data, int length) public override async Task<bool> SendAsync(byte[] data, int length)
{ {
return await SendAsync(data.AsMemory(0, length)).ConfigureAwait(false); return await SendAsync(data.AsMemory(0, length)).ConfigureAwait(false);
} }
public override async Task RelayAsync(byte bufferSize) public override async Task RelayAsync(byte bufferSize)
@@ -529,7 +529,7 @@ namespace linker.server
TryLimit(ref length); TryLimit(ref length);
while (length > 0) while (length > 0)
{ {
await Task.Delay(30).ConfigureAwait(false); await Task.Delay(30).ConfigureAwait(false);
TryLimit(ref length); TryLimit(ref length);
} }
} }

View File

@@ -1,4 +1,4 @@
namespace linker.server namespace linker.plugins.messenger
{ {
/// <summary> /// <summary>
/// 消息接口 /// 消息接口

View File

@@ -1,8 +1,15 @@
using linker.libs; using linker.libs;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Net.Security;
using System.Net.Sockets;
using System.Net;
using System.Reflection; using System.Reflection;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Buffers;
using linker.libs.extends;
namespace linker.server namespace linker.plugins.messenger
{ {
/// <summary> /// <summary>
/// 消息处理总线 /// 消息处理总线
@@ -17,12 +24,135 @@ namespace linker.server
private readonly MessengerSender messengerSender; private readonly MessengerSender messengerSender;
private readonly ServiceProvider serviceProvider; private readonly ServiceProvider serviceProvider;
private X509Certificate serverCertificate;
public MessengerResolver(MessengerSender messengerSender, ServiceProvider serviceProvider) public MessengerResolver(MessengerSender messengerSender, ServiceProvider serviceProvider)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.serviceProvider = serviceProvider; this.serviceProvider = serviceProvider;
} }
public void Init(string certificate, string password)
{
string path = Path.GetFullPath(certificate);
if (File.Exists(path))
{
serverCertificate = new X509Certificate(path, password);
}
else
{
LoggerHelper.Instance.Error($"file {path} not found");
Environment.Exit(0);
}
}
public async Task BeginReceiveServer(Socket socket)
{
try
{
if (socket == null || socket.RemoteEndPoint == null)
{
return;
}
socket.KeepAlive();
if (await ReceiveType(socket).ConfigureAwait(false) == 0)
{
return;
}
NetworkStream networkStream = new NetworkStream(socket, false);
SslStream sslStream = new SslStream(networkStream, true);
await sslStream.AuthenticateAsServerAsync(serverCertificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
IConnection connection = CreateConnection(sslStream, networkStream, socket, socket.LocalEndPoint as IPEndPoint, socket.RemoteEndPoint as IPEndPoint);
connection.BeginReceive(this, null, true);
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex);
}
}
public async Task<IConnection> BeginReceiveClient(Socket socket)
{
try
{
if (socket == null || socket.RemoteEndPoint == null)
{
return null;
}
socket.KeepAlive();
await socket.SendAsync(new byte[] { 1 }).ConfigureAwait(false);
NetworkStream networkStream = new NetworkStream(socket, false);
SslStream sslStream = new SslStream(networkStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
{
AllowRenegotiation = true,
EnabledSslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13
}).ConfigureAwait(false);
IConnection connection = CreateConnection(sslStream, networkStream, socket, socket.LocalEndPoint as IPEndPoint, socket.RemoteEndPoint as IPEndPoint);
connection.BeginReceive(this, null, true);
return connection;
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex);
}
return null;
}
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
private IConnection CreateConnection(SslStream stream, NetworkStream networkStream, Socket socket, IPEndPoint local, IPEndPoint remote)
{
return new TcpConnection(stream, networkStream, socket, local, remote)
{
ReceiveRequestWrap = new MessageRequestWrap(),
ReceiveResponseWrap = new MessageResponseWrap()
};
}
public Memory<byte> BuildSendData(byte[] data, IPEndPoint ep)
{
//给客户端返回他的IP+端口
data[0] = (byte)ep.AddressFamily;
ep.Address.TryWriteBytes(data.AsSpan(1), out int length);
((ushort)ep.Port).ToBytes(data.AsMemory(1 + length));
//防止一些网关修改掉它的外网IP
for (int i = 0; i < 1 + length + 2; i++)
{
data[i] = (byte)(data[i] ^ byte.MaxValue);
}
return data.AsMemory(0, 1 + length + 2);
}
private async Task<byte> ReceiveType(Socket socket)
{
byte[] sendData = ArrayPool<byte>.Shared.Rent(20);
try
{
await socket.ReceiveAsync(sendData.AsMemory(0, 1), SocketFlags.None).ConfigureAwait(false);
byte type = sendData[0];
if (type == 0)
{
Memory<byte> memory = BuildSendData(sendData, socket.RemoteEndPoint as IPEndPoint);
await socket.SendAsync(memory, SocketFlags.None).ConfigureAwait(false);
}
return type;
}
catch (Exception)
{
}
finally
{
ArrayPool<byte>.Shared.Return(sendData);
}
return 1;
}
/// <summary> /// <summary>
/// 加载所有消息处理器 /// 加载所有消息处理器
/// </summary> /// </summary>

View File

@@ -1,7 +1,7 @@
using linker.libs; using linker.libs;
using System.Collections.Concurrent; using System.Collections.Concurrent;
namespace linker.server namespace linker.plugins.messenger
{ {
/// <summary> /// <summary>
/// 消息发送器 /// 消息发送器

View File

@@ -1,34 +1,31 @@
using linker.config; using linker.config;
using linker.startup; using linker.startup;
using linker.libs;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Reflection; using System.Reflection;
namespace linker.server namespace linker.plugins.messenger
{ {
/// <summary> /// <summary>
/// 服务端插件 /// 服务端插件
/// </summary> /// </summary>
public sealed class ServerStartup : IStartup public sealed class MessengerStartup : IStartup
{ {
public StartupLevel Level => StartupLevel.Normal; public StartupLevel Level => StartupLevel.Normal;
public string Name => "server"; public string Name => "messenger";
public bool Required => true; public bool Required => true;
public string[] Dependent => new string[] { "serialize", "firewall", "signin" }; public string[] Dependent => new string[] { };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;
public void AddClient(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies) public void AddClient(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
{ {
serviceCollection.AddSingleton<MessengerSender>(); serviceCollection.AddSingleton<MessengerSender>();
serviceCollection.AddSingleton<MessengerResolver>(); serviceCollection.AddSingleton<MessengerResolver>();
serviceCollection.AddSingleton<TcpServer>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies) public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
{ {
serviceCollection.AddSingleton<MessengerSender>(); serviceCollection.AddSingleton<MessengerSender>();
serviceCollection.AddSingleton<MessengerResolver>(); serviceCollection.AddSingleton<MessengerResolver>();
serviceCollection.AddSingleton<TcpServer>();
} }
@@ -40,6 +37,7 @@ namespace linker.server
{ {
MessengerResolver messengerResolver = serviceProvider.GetService<MessengerResolver>(); MessengerResolver messengerResolver = serviceProvider.GetService<MessengerResolver>();
messengerResolver.LoadMessenger(assemblies); messengerResolver.LoadMessenger(assemblies);
messengerResolver.Init(config.Data.Server.Certificate, config.Data.Server.Password);
loaded = true; loaded = true;
} }
} }
@@ -50,26 +48,9 @@ namespace linker.server
{ {
MessengerResolver messengerResolver = serviceProvider.GetService<MessengerResolver>(); MessengerResolver messengerResolver = serviceProvider.GetService<MessengerResolver>();
messengerResolver.LoadMessenger(assemblies); messengerResolver.LoadMessenger(assemblies);
messengerResolver.Init(config.Data.Server.Certificate, config.Data.Server.Password);
loaded = true; loaded = true;
} }
LoggerHelper.Instance.Info($"start server");
try
{
//服务
TcpServer tcpServer = serviceProvider.GetService<TcpServer>();
tcpServer.Init(config.Data.Server.Certificate, config.Data.Server.Password);
if(config.Data.Server.ServicePort > 0)
{
tcpServer.Start(config.Data.Server.ServicePort);
}
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
LoggerHelper.Instance.Info($"server listen:{config.Data.Server.ServicePort}");
} }
} }
} }

View File

@@ -2,7 +2,7 @@
using System.Buffers; using System.Buffers;
using System.ComponentModel; using System.ComponentModel;
namespace linker.server namespace linker.plugins.messenger
{ {
/// <summary> /// <summary>
/// 请求数据包 /// 请求数据包

View File

@@ -1,11 +1,11 @@
using linker.client; using linker.config;
using linker.client.capi;
using linker.config;
using linker.plugins.relay.messenger; using linker.plugins.relay.messenger;
using linker.server;
using linker.libs.api; using linker.libs.api;
using linker.libs.extends; using linker.libs.extends;
using MemoryPack; using MemoryPack;
using linker.plugins.client;
using linker.plugins.capi;
using linker.plugins.messenger;
namespace linker.plugins.relay namespace linker.plugins.relay
{ {

View File

@@ -17,7 +17,7 @@ namespace linker.plugins.relay
public bool Required => false; public bool Required => false;
public string[] Dependent => new string[] { }; public string[] Dependent => new string[] { "messenger", "signin", "serialize", "config" };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;

View File

@@ -9,7 +9,7 @@ using System.Collections.Concurrent;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using MemoryPack; using MemoryPack;
using linker.client; using linker.plugins.client;
namespace linker.plugins.relay namespace linker.plugins.relay
{ {

View File

@@ -1,10 +1,11 @@
using linker.config; using linker.config;
using linker.plugins.relay.transport; using linker.plugins.relay.transport;
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using linker.server;
using linker.libs; using linker.libs;
using MemoryPack; using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using linker.plugins.server;
using linker.plugins.messenger;
namespace linker.plugins.relay.messenger namespace linker.plugins.relay.messenger
{ {

View File

@@ -1,6 +1,5 @@
using linker.config; using linker.config;
using linker.plugins.relay.messenger; using linker.plugins.relay.messenger;
using linker.server;
using linker.tunnel.connection; using linker.tunnel.connection;
using linker.libs; using linker.libs;
using linker.libs.extends; using linker.libs.extends;
@@ -11,6 +10,8 @@ using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using System.Security.Authentication; using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using linker.plugins.server;
using linker.plugins.messenger;
namespace linker.plugins.relay.transport namespace linker.plugins.relay.transport
{ {
@@ -20,15 +21,15 @@ namespace linker.plugins.relay.transport
public RelayType Type => RelayType.Linker; public RelayType Type => RelayType.Linker;
public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp; public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp;
private readonly TcpServer tcpServer; private readonly MessengerResolver messengerResolver;
private readonly MessengerSender messengerSender; private readonly MessengerSender messengerSender;
private X509Certificate2 certificate; private X509Certificate2 certificate;
public TransportSelfHost(TcpServer tcpServer, MessengerSender messengerSender, FileConfig config) public TransportSelfHost(MessengerResolver messengerResolver, MessengerSender messengerSender, FileConfig config)
{ {
this.tcpServer = tcpServer; this.messengerResolver = messengerResolver;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
string path = Path.GetFullPath(config.Data.Client.Certificate); string path = Path.GetFullPath(config.Data.Client.Certificate);
@@ -46,7 +47,7 @@ namespace linker.plugins.relay.transport
socket.KeepAlive(); socket.KeepAlive();
await socket.ConnectAsync(relayInfo.Server).WaitAsync(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false); await socket.ConnectAsync(relayInfo.Server).WaitAsync(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false);
IConnection connection = await tcpServer.BeginReceive(socket); IConnection connection = await messengerResolver.BeginReceiveClient(socket);
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{ {
Connection = connection, Connection = connection,
@@ -114,7 +115,7 @@ namespace linker.plugins.relay.transport
socket.KeepAlive(); socket.KeepAlive();
await socket.ConnectAsync(relayInfo.Server).WaitAsync(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false); await socket.ConnectAsync(relayInfo.Server).WaitAsync(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false);
IConnection connection = await tcpServer.BeginReceive(socket); IConnection connection = await messengerResolver.BeginReceiveClient(socket);
await messengerSender.SendOnly(new MessageRequestWrap await messengerSender.SendOnly(new MessageRequestWrap
{ {
Connection = connection, Connection = connection,

View File

@@ -1,7 +1,7 @@
using MemoryPack; using MemoryPack;
using System.Net; using System.Net;
namespace linker.serializes namespace linker.plugins.serializes
{ {
/// <summary> /// <summary>
/// MemoryPack 的 IPAddress序列化扩展 /// MemoryPack 的 IPAddress序列化扩展
@@ -25,7 +25,7 @@ namespace linker.serializes
span[0] = (byte)bytesWritten; span[0] = (byte)bytesWritten;
writer.WriteCollectionHeader(bytesWritten + 4); writer.WriteCollectionHeader(bytesWritten + 4);
writer.WriteSpan(span.Slice(0, bytesWritten+1)); writer.WriteSpan(span.Slice(0, bytesWritten + 1));
} }
public override void Deserialize(ref MemoryPackReader reader, scoped ref IPAddress value) public override void Deserialize(ref MemoryPackReader reader, scoped ref IPAddress value)

View File

@@ -2,7 +2,7 @@
using MemoryPack; using MemoryPack;
using System.Net; using System.Net;
namespace linker.serializes namespace linker.plugins.serializes
{ {
/// <summary> /// <summary>
/// MemoryPack 的 IPEndPoint序列化扩展 /// MemoryPack 的 IPEndPoint序列化扩展

View File

@@ -4,7 +4,7 @@ using MemoryPack;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Reflection; using System.Reflection;
namespace linker.serializes namespace linker.plugins.serializes
{ {
/// <summary> /// <summary>
/// MemoryPack 序列化扩展加载插件 /// MemoryPack 序列化扩展加载插件

View File

@@ -0,0 +1,53 @@
using linker.config;
using linker.startup;
using linker.libs;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
namespace linker.plugins.server
{
/// <summary>
/// 服务端插件
/// </summary>
public sealed class ServerStartup : IStartup
{
public StartupLevel Level => StartupLevel.Normal;
public string Name => "server";
public bool Required => true;
public string[] Dependent => new string[] {"messenger", "serialize", "firewall", "signin", "config" };
public StartupLoadType LoadType => StartupLoadType.Normal;
public void AddClient(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
{
}
public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
{
serviceCollection.AddSingleton<TcpServer>();
}
public void UseClient(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)
{
}
public void UseServer(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)
{
LoggerHelper.Instance.Info($"start server");
try
{
//服务
TcpServer tcpServer = serviceProvider.GetService<TcpServer>();
if (config.Data.Server.ServicePort > 0)
{
tcpServer.Start(config.Data.Server.ServicePort);
}
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
LoggerHelper.Instance.Info($"server listen:{config.Data.Server.ServicePort}");
}
}
}

View File

@@ -0,0 +1,127 @@
using linker.libs.extends;
using linker.plugins.messenger;
using System.Net;
using System.Net.Sockets;
namespace linker.plugins.server
{
public sealed class TcpServer
{
private Socket socket;
private Socket socketUdp;
private CancellationTokenSource cancellationTokenSource;
private readonly MessengerResolver messengerResolver;
public TcpServer(MessengerResolver messengerResolver)
{
this.messengerResolver = messengerResolver;
cancellationTokenSource = new CancellationTokenSource();
}
public void Start(int port)
{
if (socket == null)
{
socket = BindAccept(port);
}
}
private async Task BindUdp(int port)
{
socketUdp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socketUdp.Bind(new IPEndPoint(IPAddress.Any, port));
socketUdp.WindowsUdpBug();
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);
byte[] buffer = new byte[1024];
byte[] sendData = new byte[20];
while (true)
{
try
{
SocketReceiveFromResult result = await socketUdp.ReceiveFromAsync(buffer, SocketFlags.None, endPoint).ConfigureAwait(false);
IPEndPoint ep = result.RemoteEndPoint as IPEndPoint;
try
{
Memory<byte> memory = messengerResolver.BuildSendData(sendData, ep);
await socketUdp.SendToAsync(memory, ep).ConfigureAwait(false);
}
catch (Exception)
{
}
}
catch (Exception)
{
break;
}
}
}
private Socket BindAccept(int port)
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);
Socket socket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.IPv6Only(localEndPoint.AddressFamily, false);
socket.ReuseBind(localEndPoint);
socket.Listen(int.MaxValue);
SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs
{
UserToken = socket,
SocketFlags = SocketFlags.None,
};
acceptEventArg.Completed += IO_Completed;
StartAccept(acceptEventArg);
_ = BindUdp(port);
return socket;
}
private void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
acceptEventArg.AcceptSocket = null;
Socket token = (Socket)acceptEventArg.UserToken;
try
{
if (token.AcceptAsync(acceptEventArg) == false)
{
ProcessAccept(acceptEventArg);
}
}
catch (Exception)
{
token?.SafeClose();
}
}
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)
{
_ = messengerResolver.BeginReceiveServer(e.AcceptSocket);
StartAccept(e);
}
}
public void Stop()
{
cancellationTokenSource?.Cancel();
socket?.SafeClose();
socket = null;
}
public void Disponse()
{
Stop();
}
}
}

View File

@@ -1,11 +1,11 @@
using linker.libs.api; using linker.libs.api;
using linker.libs.extends; using linker.libs.extends;
using linker.client.capi;
using linker.client.config; using linker.client.config;
using linker.client;
using linker.server;
using MemoryPack; using MemoryPack;
using linker.plugins.sforward.messenger; using linker.plugins.sforward.messenger;
using linker.plugins.client;
using linker.plugins.capi;
using linker.plugins.messenger;
namespace linker.plugins.sforward namespace linker.plugins.sforward
{ {

View File

@@ -18,7 +18,7 @@ namespace linker.plugins.sforward
public StartupLevel Level => StartupLevel.Normal; public StartupLevel Level => StartupLevel.Normal;
public string[] Dependent => Array.Empty<string>(); public string[] Dependent => new string[] { "messenger", "signin", "serialize", "config" };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;

View File

@@ -1,13 +1,13 @@
using linker.client.config; using linker.client.config;
using linker.client;
using linker.libs; using linker.libs;
using linker.server;
using linker.plugins.sforward.messenger; using linker.plugins.sforward.messenger;
using MemoryPack; using MemoryPack;
using linker.plugins.sforward.config; using linker.plugins.sforward.config;
using System.Net.Sockets; using System.Net.Sockets;
using System.Net; using System.Net;
using linker.libs.extends; using linker.libs.extends;
using linker.plugins.client;
using linker.plugins.messenger;
namespace linker.plugins.sforward namespace linker.plugins.sforward
{ {

View File

@@ -2,13 +2,13 @@
using linker.plugins.sforward.config; using linker.plugins.sforward.config;
using linker.plugins.sforward.validator; using linker.plugins.sforward.validator;
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using linker.server;
using MemoryPack; using MemoryPack;
using linker.plugins.sforward.proxy; using linker.plugins.sforward.proxy;
using linker.config; using linker.config;
using LiteDB; using LiteDB;
using System.Net; using System.Net;
using linker.plugins.forward.messenger; using linker.plugins.forward.messenger;
using linker.plugins.messenger;
namespace linker.plugins.sforward.messenger namespace linker.plugins.sforward.messenger
{ {

View File

@@ -1,5 +1,5 @@
using linker.plugins.sforward.config; using linker.plugins.messenger;
using linker.server; using linker.plugins.sforward.config;
namespace linker.plugins.sforward.validator namespace linker.plugins.sforward.validator
{ {

View File

@@ -1,6 +1,6 @@
using linker.config; using linker.config;
using linker.plugins.messenger;
using linker.plugins.sforward.config; using linker.plugins.sforward.config;
using linker.server;
namespace linker.plugins.sforward.validator namespace linker.plugins.sforward.validator
{ {

View File

@@ -2,10 +2,10 @@
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using linker.libs.api; using linker.libs.api;
using linker.libs.extends; using linker.libs.extends;
using linker.client;
using linker.server;
using MemoryPack; using MemoryPack;
using linker.client.capi; using linker.plugins.client;
using linker.plugins.capi;
using linker.plugins.messenger;
namespace linker.plugins.signin namespace linker.plugins.signin
{ {

View File

@@ -13,7 +13,7 @@ namespace linker.plugins.signin
public bool Required => false; public bool Required => false;
public string[] Dependent => new string[] { }; public string[] Dependent => new string[] { "messenger", };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;

View File

@@ -1,11 +1,11 @@
using linker.store; using linker.store;
using linker.server;
using linker.libs; using linker.libs;
using LiteDB; using LiteDB;
using MemoryPack; using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net; using System.Net;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using linker.plugins.messenger;
namespace linker.plugins.signin.messenger namespace linker.plugins.signin.messenger
{ {

View File

@@ -1,8 +1,8 @@
using linker.client; using linker.config;
using linker.config;
using linker.server;
using linker.libs;
using MemoryPack; using MemoryPack;
using linker.plugins.client;
using linker.plugins.server;
using linker.plugins.messenger;
namespace linker.plugins.signin.messenger namespace linker.plugins.signin.messenger
{ {

View File

@@ -1,8 +1,6 @@
using linker.client; using linker.client.config;
using linker.client.config;
using linker.config; using linker.config;
using linker.plugins.tunnel.messenger; using linker.plugins.tunnel.messenger;
using linker.server;
using linker.tunnel.adapter; using linker.tunnel.adapter;
using linker.tunnel.transport; using linker.tunnel.transport;
using linker.libs; using linker.libs;
@@ -11,6 +9,8 @@ using System.Net;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using System.Buffers.Binary; using System.Buffers.Binary;
using linker.plugins.client;
using linker.plugins.messenger;
namespace linker.plugins.tunnel namespace linker.plugins.tunnel
{ {

View File

@@ -1,8 +1,5 @@
using linker.client; using linker.config;
using linker.client.capi;
using linker.config;
using linker.plugins.tunnel.messenger; using linker.plugins.tunnel.messenger;
using linker.server;
using linker.tunnel.adapter; using linker.tunnel.adapter;
using linker.tunnel.transport; using linker.tunnel.transport;
using linker.libs.api; using linker.libs.api;
@@ -11,6 +8,10 @@ using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using linker.client.config; using linker.client.config;
using linker.plugins.client;
using linker.plugins.server;
using linker.plugins.capi;
using linker.plugins.messenger;
namespace linker.plugins.tunnel namespace linker.plugins.tunnel
{ {

View File

@@ -1,12 +1,14 @@
using linker.client; using linker.client.config;
using linker.client.config;
using linker.config; using linker.config;
using linker.libs;
using linker.plugins.client;
using linker.plugins.messenger;
using linker.plugins.tunnel.messenger; using linker.plugins.tunnel.messenger;
using linker.server;
using linker.tunnel.adapter; using linker.tunnel.adapter;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using MemoryPack; using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net.Quic;
namespace linker.plugins.tunnel namespace linker.plugins.tunnel
{ {
@@ -35,20 +37,14 @@ namespace linker.plugins.tunnel
this.runningConfigTransfer = runningConfigTransfer; this.runningConfigTransfer = runningConfigTransfer;
this.tunnelAdapter = tunnelAdapter; this.tunnelAdapter = tunnelAdapter;
clientSignInState.NetworkEnabledHandle += (times) =>
{ InitRouteLevel();
GetRemoveRouteLevel(); InitExcludeIP();
};
clientSignInState.NetworkFirstEnabledHandle += () =>
{
SyncExcludeIP();
};
InitConfig(); InitConfig();
runningConfigTransfer.Setter(exipConfigKey, SettExcludeIPs); TestQuic();
runningConfigTransfer.Getter(exipConfigKey, () => MemoryPackSerializer.Serialize(GetExcludeIPs()));
} }
private void InitConfig() private void InitConfig()
{ {
bool updateVersion = false; bool updateVersion = false;
@@ -85,7 +81,7 @@ namespace linker.plugins.tunnel
/// </summary> /// </summary>
public void RefreshConfig() public void RefreshConfig()
{ {
GetRemoveRouteLevel(); GetRemoteRouteLevel();
} }
/// <summary> /// <summary>
/// 修改自己的网关层级信息 /// 修改自己的网关层级信息
@@ -95,7 +91,7 @@ namespace linker.plugins.tunnel
{ {
running.Data.Tunnel.RouteLevelPlus = tunnelTransportFileConfigInfo.RouteLevelPlus; running.Data.Tunnel.RouteLevelPlus = tunnelTransportFileConfigInfo.RouteLevelPlus;
running.Data.Update(); running.Data.Update();
GetRemoveRouteLevel(); GetRemoteRouteLevel();
} }
/// <summary> /// <summary>
/// 收到别人发给我的修改我的信息 /// 收到别人发给我的修改我的信息
@@ -108,7 +104,7 @@ namespace linker.plugins.tunnel
Interlocked.Increment(ref version); Interlocked.Increment(ref version);
return GetLocalRouteLevel(); return GetLocalRouteLevel();
} }
private void GetRemoveRouteLevel() private void GetRemoteRouteLevel()
{ {
TunnelTransportRouteLevelInfo config = GetLocalRouteLevel(); TunnelTransportRouteLevelInfo config = GetLocalRouteLevel();
messengerSender.SendReply(new MessageRequestWrap messengerSender.SendReply(new MessageRequestWrap
@@ -138,11 +134,28 @@ namespace linker.plugins.tunnel
{ {
MachineId = config.Data.Client.Id, MachineId = config.Data.Client.Id,
RouteLevel = config.Data.Client.Tunnel.RouteLevel, RouteLevel = config.Data.Client.Tunnel.RouteLevel,
RouteLevelPlus = running.Data.Tunnel.RouteLevelPlus RouteLevelPlus = running.Data.Tunnel.RouteLevelPlus,
NeedReboot = reboot
};
}
private void InitRouteLevel()
{
clientSignInState.NetworkEnabledHandle += (times) =>
{
GetRemoteRouteLevel();
}; };
} }
private void InitExcludeIP()
{
clientSignInState.NetworkFirstEnabledHandle += () =>
{
SyncExcludeIP();
};
runningConfigTransfer.Setter(exipConfigKey, SettExcludeIPs);
runningConfigTransfer.Getter(exipConfigKey, () => MemoryPackSerializer.Serialize(GetExcludeIPs()));
}
private void SyncExcludeIP() private void SyncExcludeIP()
{ {
runningConfigTransfer.Sync(exipConfigKey, MemoryPackSerializer.Serialize(running.Data.Tunnel.ExcludeIPs)); runningConfigTransfer.Sync(exipConfigKey, MemoryPackSerializer.Serialize(running.Data.Tunnel.ExcludeIPs));
@@ -163,5 +176,36 @@ namespace linker.plugins.tunnel
running.Data.Tunnel.ExcludeIPs = MemoryPackSerializer.Deserialize<ExcludeIPItem[]>(data.Span); running.Data.Tunnel.ExcludeIPs = MemoryPackSerializer.Deserialize<ExcludeIPItem[]>(data.Span);
running.Data.Update(); running.Data.Update();
} }
bool reboot = false;
private void TestQuic()
{
if (OperatingSystem.IsWindows())
{
if (QuicListener.IsSupported == false)
{
try
{
if (File.Exists("msquic-openssl.dll"))
{
LoggerHelper.Instance.Warning($"copy msquic-openssl.dll -> msquic.dllplease restart linker");
File.Move("msquic.dll", "msquic.dll.temp", true);
File.Move("msquic-openssl.dll", "msquic.dll", true);
reboot = true;
}
}
catch (Exception)
{
}
}
if (File.Exists("msquic.dll.temp"))
{
File.Delete("msquic.dll.temp");
}
}
}
} }
} }

View File

@@ -23,7 +23,7 @@ namespace linker.plugins.tunnel
public bool Required => false; public bool Required => false;
public string[] Dependent => new string[] { }; public string[] Dependent => new string[] { "messenger", "signin", "serialize", "config" };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;

View File

@@ -72,6 +72,8 @@ namespace linker.config
public string MachineId { get; set; } public string MachineId { get; set; }
public int RouteLevel { get; set; } = 0; public int RouteLevel { get; set; } = 0;
public int RouteLevelPlus { get; set; } = 0; public int RouteLevelPlus { get; set; } = 0;
public bool NeedReboot { get; set; }
} }

View File

@@ -1,11 +1,11 @@
using linker.config; using linker.config;
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using linker.server;
using linker.tunnel; using linker.tunnel;
using linker.tunnel.adapter; using linker.tunnel.adapter;
using linker.tunnel.transport; using linker.tunnel.transport;
using linker.libs; using linker.libs;
using MemoryPack; using MemoryPack;
using linker.plugins.messenger;
namespace linker.plugins.tunnel.messenger namespace linker.plugins.tunnel.messenger
{ {

View File

@@ -1,16 +1,16 @@
using linker.server; using linker.libs.api;
using linker.libs.api;
using linker.plugins.tuntap.vea; using linker.plugins.tuntap.vea;
using linker.client;
using linker.plugins.tuntap.messenger; using linker.plugins.tuntap.messenger;
using MemoryPack; using MemoryPack;
using linker.libs.extends; using linker.libs.extends;
using linker.client.capi;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using linker.config; using linker.config;
using linker.plugins.forward.proxy;
using linker.tunnel.connection; using linker.tunnel.connection;
using linker.plugins.tuntap.proxy; using linker.plugins.tuntap.proxy;
using linker.plugins.client;
using linker.plugins.server;
using linker.plugins.capi;
using linker.plugins.messenger;
namespace linker.plugins.tuntap namespace linker.plugins.tuntap
{ {

View File

@@ -16,7 +16,7 @@ namespace linker.plugins.tuntap
public StartupLevel Level => StartupLevel.Normal; public StartupLevel Level => StartupLevel.Normal;
public string Name => "tuntap"; public string Name => "tuntap";
public bool Required => false; public bool Required => false;
public string[] Dependent => new string[] { "relay", "tunnel" }; public string[] Dependent => new string[] {"messenger", "relay", "tunnel", "signin", "serialize", "config" };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;

View File

@@ -1,10 +1,8 @@
using linker.client; using linker.client.config;
using linker.client.config;
using linker.config; using linker.config;
using linker.plugins.tuntap.messenger; using linker.plugins.tuntap.messenger;
using linker.plugins.tuntap.proxy; using linker.plugins.tuntap.proxy;
using linker.plugins.tuntap.vea; using linker.plugins.tuntap.vea;
using linker.server;
using linker.libs; using linker.libs;
using MemoryPack; using MemoryPack;
using System.Buffers.Binary; using System.Buffers.Binary;
@@ -13,6 +11,8 @@ using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Net.Sockets; using System.Net.Sockets;
using linker.libs.extends; using linker.libs.extends;
using linker.plugins.client;
using linker.plugins.messenger;
namespace linker.plugins.tuntap namespace linker.plugins.tuntap
{ {

View File

@@ -1,6 +1,6 @@
using linker.plugins.signin.messenger; using linker.plugins.messenger;
using linker.plugins.signin.messenger;
using linker.plugins.tuntap.vea; using linker.plugins.tuntap.vea;
using linker.server;
using MemoryPack; using MemoryPack;
namespace linker.plugins.tuntap.messenger namespace linker.plugins.tuntap.messenger

View File

@@ -1,7 +1,4 @@
using linker.server; using linker.libs.api;
using linker.libs.api;
using linker.client;
using linker.client.capi;
using linker.config; using linker.config;
using linker.plugins.updater.messenger; using linker.plugins.updater.messenger;
using MemoryPack; using MemoryPack;
@@ -9,6 +6,9 @@ using System.Collections.Concurrent;
using linker.plugins.updater.config; using linker.plugins.updater.config;
using linker.libs.extends; using linker.libs.extends;
using linker.client.config; using linker.client.config;
using linker.plugins.client;
using linker.plugins.capi;
using linker.plugins.messenger;
namespace linker.plugins.updater namespace linker.plugins.updater
{ {

View File

@@ -1,8 +1,9 @@
using linker.client; using linker.client.config;
using linker.client.config;
using linker.config; using linker.config;
using linker.plugins.client;
using linker.plugins.messenger;
using linker.plugins.server;
using linker.plugins.updater.messenger; using linker.plugins.updater.messenger;
using linker.server;
using MemoryPack; using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@@ -78,7 +79,6 @@ namespace linker.plugins.updater
{ {
updaterHelper.Confirm(updateInfo, version); updaterHelper.Confirm(updateInfo, version);
} }
/// <summary> /// <summary>
/// 来自别的客户端的更新信息 /// 来自别的客户端的更新信息
/// </summary> /// </summary>

View File

@@ -36,10 +36,11 @@ namespace linker.plugins.updater
using HttpClient httpClient = new HttpClient(); using HttpClient httpClient = new HttpClient();
string str = await httpClient.GetStringAsync("http://gh.snltty.com:1808/https://github.com/snltty/linker/releases/latest").WaitAsync(TimeSpan.FromSeconds(15)); string str = await httpClient.GetStringAsync("http://gh.snltty.com:1808/https://github.com/snltty/linker/releases/latest").WaitAsync(TimeSpan.FromSeconds(15));
Match match = new Regex(@"/snltty/linker/tree/(v[\d.]+)").Match(str); string datetime = DateTime.Parse(new Regex("datetime=\"(.+)\"").Match(str).Groups[1].Value).ToString("yyyy-MM-dd HH:mm:ss");
string tag = match.Groups[1].Value; string tag = new Regex(@"/snltty/linker/tree/(v[\d.]+)").Match(str).Groups[1].Value;
string[] msg = new Regex(@"<li>(.+)</li>").Matches(str).Select(c => c.Groups[1].Value).ToArray(); string[] msg = new Regex(@"<li>(.+)</li>").Matches(str).Select(c => c.Groups[1].Value).ToArray();
updateInfo.DateTime = datetime;
updateInfo.Msg = msg; updateInfo.Msg = msg;
updateInfo.Version = tag; updateInfo.Version = tag;
@@ -243,6 +244,8 @@ namespace linker.plugins.updater
public string Version { get; set; } public string Version { get; set; }
[MemoryPackIgnore] [MemoryPackIgnore]
public string[] Msg { get; set; } public string[] Msg { get; set; }
[MemoryPackIgnore]
public string DateTime { get; set; }
public string MachineId { get; set; } public string MachineId { get; set; }
public UpdateStatus Status { get; set; } = UpdateStatus.None; public UpdateStatus Status { get; set; } = UpdateStatus.None;

View File

@@ -17,7 +17,7 @@ namespace linker.plugins.updater
public StartupLevel Level => StartupLevel.Normal; public StartupLevel Level => StartupLevel.Normal;
public string[] Dependent => Array.Empty<string>(); public string[] Dependent => new string[] { "messenger", "signin", "serialize", "config" };
public StartupLoadType LoadType => StartupLoadType.Normal; public StartupLoadType LoadType => StartupLoadType.Normal;

View File

@@ -1,7 +1,8 @@
using linker.config; using linker.config;
using linker.plugins.messenger;
using linker.plugins.server;
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using linker.plugins.updater.config; using linker.plugins.updater.config;
using linker.server;
using MemoryPack; using MemoryPack;
namespace linker.plugins.updater.messenger namespace linker.plugins.updater.messenger

View File

@@ -1,258 +0,0 @@
using linker.libs;
using linker.libs.extends;
using System.Buffers;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
namespace linker.server
{
public sealed class TcpServer
{
private Socket socket;
private Socket socketUdp;
private CancellationTokenSource cancellationTokenSource;
private X509Certificate serverCertificate;
private readonly IConnectionReceiveCallback connectionReceiveCallback;
public TcpServer(MessengerResolver connectionReceiveCallback)
{
cancellationTokenSource = new CancellationTokenSource();
this.connectionReceiveCallback = connectionReceiveCallback;
}
public void Init(string certificate, string password)
{
string path = Path.GetFullPath(certificate);
if (File.Exists(path))
{
serverCertificate = new X509Certificate(path, password);
}
else
{
LoggerHelper.Instance.Error($"file {path} not found");
Environment.Exit(0);
}
}
public void Start(int port)
{
if (socket == null)
{
socket = BindAccept(port);
}
}
private Socket BindAccept(int port)
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);
Socket socket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.IPv6Only(localEndPoint.AddressFamily, false);
socket.ReuseBind(localEndPoint);
socket.Listen(int.MaxValue);
SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs
{
UserToken = socket,
SocketFlags = SocketFlags.None,
};
acceptEventArg.Completed += IO_Completed;
StartAccept(acceptEventArg);
_ = BindUdp(port);
return socket;
}
private Memory<byte> BuildSendData(byte[] data, IPEndPoint ep)
{
//给客户端返回他的IP+端口
data[0] = (byte)ep.AddressFamily;
ep.Address.TryWriteBytes(data.AsSpan(1), out int length);
((ushort)ep.Port).ToBytes(data.AsMemory(1 + length));
//防止一些网关修改掉它的外网IP
for (int i = 0; i < 1 + length + 2; i++)
{
data[i] = (byte)(data[i] ^ byte.MaxValue);
}
return data.AsMemory(0, 1 + length + 2);
}
private async Task BindUdp(int port)
{
socketUdp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socketUdp.Bind(new IPEndPoint(IPAddress.Any, port));
socketUdp.WindowsUdpBug();
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);
byte[] buffer = new byte[1024];
byte[] sendData = new byte[20];
while (true)
{
try
{
SocketReceiveFromResult result = await socketUdp.ReceiveFromAsync(buffer, SocketFlags.None, endPoint).ConfigureAwait(false);
IPEndPoint ep = result.RemoteEndPoint as IPEndPoint;
try
{
Memory<byte> memory = BuildSendData(sendData, ep);
await socketUdp.SendToAsync(memory, ep).ConfigureAwait(false);
}
catch (Exception)
{
}
}
catch (Exception)
{
break;
}
}
}
private void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
acceptEventArg.AcceptSocket = null;
Socket token = (Socket)acceptEventArg.UserToken;
try
{
if (token.AcceptAsync(acceptEventArg) == false)
{
ProcessAccept(acceptEventArg);
}
}
catch (Exception)
{
token?.SafeClose();
}
}
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)
{
_ = BeginReceiveServer(e.AcceptSocket);
StartAccept(e);
}
}
private async Task<byte> ReceiveType(Socket socket)
{
byte[] sendData = ArrayPool<byte>.Shared.Rent(20);
try
{
await socket.ReceiveAsync(sendData.AsMemory(0, 1), SocketFlags.None).ConfigureAwait(false);
byte type = sendData[0];
if (type == 0)
{
Memory<byte> memory = BuildSendData(sendData, socket.RemoteEndPoint as IPEndPoint);
await socket.SendAsync(memory, SocketFlags.None).ConfigureAwait(false);
}
return type;
}
catch (Exception)
{
}
finally
{
ArrayPool<byte>.Shared.Return(sendData);
}
return 1;
}
private async Task BeginReceiveServer(Socket socket)
{
try
{
if (socket == null || socket.RemoteEndPoint == null)
{
return;
}
socket.KeepAlive();
if (await ReceiveType(socket).ConfigureAwait(false) == 0)
{
return;
}
NetworkStream networkStream = new NetworkStream(socket, false);
SslStream sslStream = new SslStream(networkStream, true);
await sslStream.AuthenticateAsServerAsync(serverCertificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
IConnection connection = CreateConnection(sslStream, networkStream, socket, socket.LocalEndPoint as IPEndPoint, socket.RemoteEndPoint as IPEndPoint);
connection.BeginReceive(connectionReceiveCallback, null, true);
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex);
}
}
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
public async Task<IConnection> BeginReceive(Socket socket)
{
try
{
if (socket == null || socket.RemoteEndPoint == null)
{
return null;
}
socket.KeepAlive();
await socket.SendAsync(new byte[] { 1 }).ConfigureAwait(false);
NetworkStream networkStream = new NetworkStream(socket, false);
SslStream sslStream = new SslStream(networkStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
{
AllowRenegotiation = true,
EnabledSslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13
}).ConfigureAwait(false);
IConnection connection = CreateConnection(sslStream, networkStream, socket, socket.LocalEndPoint as IPEndPoint, socket.RemoteEndPoint as IPEndPoint);
connection.BeginReceive(connectionReceiveCallback, null, true);
return connection;
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex);
}
return null;
}
public IConnection CreateConnection(SslStream stream, NetworkStream networkStream, Socket socket, IPEndPoint local, IPEndPoint remote)
{
return new TcpConnection(stream, networkStream, socket, local, remote)
{
ReceiveRequestWrap = new MessageRequestWrap(),
ReceiveResponseWrap = new MessageResponseWrap()
};
}
public void Stop()
{
cancellationTokenSource?.Cancel();
socket?.SafeClose();
socket = null;
}
public void Disponse()
{
Stop();
}
}
}