mirror of
https://github.com/snltty/linker.git
synced 2025-10-17 06:30:46 +08:00
更多提醒
This commit is contained in:
15
.github/workflows/dotnet.yml
vendored
15
.github/workflows/dotnet.yml
vendored
@@ -48,18 +48,15 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.ACTIONS_TOKEN }}'
|
||||
with:
|
||||
tag_name: v1.1.2.2
|
||||
release_name: v1.1.2.2.${{ steps.date.outputs.today }}
|
||||
tag_name: v1.1.2.3
|
||||
release_name: v1.1.2.3.${{ steps.date.outputs.today }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
body: |
|
||||
1. 更新配置同步方式,以版本同步
|
||||
2. 设备列表搜索,按 设备名/设备IP/虚拟网卡IP/端口转发端口和IP 搜索
|
||||
3. 端口转发配置复制,可以将A转发到B的配置复制给C转发到B
|
||||
4. 服务器代理穿透配置复制
|
||||
5. 修复虚拟网卡添加路由错误
|
||||
6. 自动更新,管理所有客户端更新
|
||||
7. 请更新服务端
|
||||
1. 修复虚拟网卡添加路由错误
|
||||
2. 自动更新,客户端和服务端
|
||||
3. 更多的消息提醒,需要重启时提醒
|
||||
4. 请更新服务端
|
||||
|
||||
- name: upload win x64
|
||||
id: upload-win-x64
|
||||
|
@@ -15,8 +15,8 @@
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
<Version>1.1.2</Version>
|
||||
<AssemblyVersion>1.1.2.2</AssemblyVersion>
|
||||
<FileVersion>1.1.2.2</FileVersion>
|
||||
<AssemblyVersion>1.1.2.3</AssemblyVersion>
|
||||
<FileVersion>1.1.2.3</FileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
|
@@ -22,8 +22,8 @@
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
<PackageReleaseNotes>snltty service</PackageReleaseNotes>
|
||||
<AssemblyVersion>1.1.2.2</AssemblyVersion>
|
||||
<FileVersion>1.1.2.2</FileVersion>
|
||||
<AssemblyVersion>1.1.2.3</AssemblyVersion>
|
||||
<FileVersion>1.1.2.3</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
@@ -17,8 +17,8 @@
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
<PackageReleaseNotes>linker tunnel</PackageReleaseNotes>
|
||||
<AssemblyVersion>1.1.2.2</AssemblyVersion>
|
||||
<FileVersion>1.1.2.2</FileVersion>
|
||||
<AssemblyVersion>1.1.2.3</AssemblyVersion>
|
||||
<FileVersion>1.1.2.3</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
@@ -10,8 +10,6 @@ using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using System.Text;
|
||||
using linker.tunnel.wanport;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
|
||||
namespace linker.tunnel.transport
|
||||
{
|
||||
@@ -664,7 +662,6 @@ namespace linker.tunnel.transport
|
||||
{
|
||||
if (OperatingSystem.IsWindows() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
|
||||
{
|
||||
TestQuic();
|
||||
if (QuicListener.IsSupported == false)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"msquic not supported, need win11+,or linux, or try to restart linker");
|
||||
@@ -729,27 +726,6 @@ 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
|
||||
{
|
||||
@@ -773,10 +749,5 @@ namespace linker.tunnel.transport
|
||||
}
|
||||
}
|
||||
|
||||
enum ListenStep : byte
|
||||
{
|
||||
Auth = 0,
|
||||
Forward = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -157,6 +157,14 @@ span.split-pad10 {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.green {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
color: #e68906
|
||||
}
|
||||
|
||||
.scrollbar,
|
||||
.scrollbar-1,
|
||||
.scrollbar-4,
|
||||
@@ -214,6 +222,9 @@ span.split-pad10 {
|
||||
--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 {
|
||||
background: #f5f5f5
|
||||
|
@@ -56,8 +56,11 @@ export default {
|
||||
setup(props) {
|
||||
|
||||
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 updaterMsg = computed(()=>{
|
||||
return `${updaterCurrent.value.Version}->${updaterCurrent.value.DateTime}\n${updaterCurrent.value.Msg.map((value,index)=>`${index+1}、${value}`).join('\n')}`;
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
show: false,
|
||||
@@ -75,10 +78,12 @@ export default {
|
||||
|
||||
const _getUpdaterCurrent = ()=>{
|
||||
getUpdaterCurrent().then((res)=>{
|
||||
updaterCurrent.value.DateTime = res.DateTime;
|
||||
updaterCurrent.value.Version = res.Version;
|
||||
updaterCurrent.value.Status = res.Status;
|
||||
updaterCurrent.value.Length = res.Length;
|
||||
updaterCurrent.value.Current = res.Current;
|
||||
updaterCurrent.value.Msg = res.Msg;
|
||||
setTimeout(()=>{
|
||||
_getUpdaterCurrent();
|
||||
},1000);
|
||||
@@ -111,8 +116,8 @@ export default {
|
||||
}
|
||||
if(updaterServer.value.Status <= 2) {
|
||||
return state.version != updaterCurrent.value.Version
|
||||
? `不是最新版本(${updaterCurrent.value.Version}),建议更新`
|
||||
: '是最新版本,但我无法阻止你喜欢更新'
|
||||
? `不是最新版本(${updaterCurrent.value.Version}),建议更新\n${updaterMsg.value}`
|
||||
: `是最新版本,但我无法阻止你喜欢更新\n${updaterMsg.value}`
|
||||
}
|
||||
return {
|
||||
3:'正在下载',
|
||||
@@ -216,12 +221,8 @@ export default {
|
||||
}
|
||||
|
||||
a.download{
|
||||
&.green{color:green}
|
||||
&.red{color:red}
|
||||
&.yellow{color:#e68906}
|
||||
.el-icon{
|
||||
font-weight:bold;
|
||||
&.yellow{color:#e68906}
|
||||
&.loading{
|
||||
animation:loading 1s linear infinite;
|
||||
}
|
||||
|
@@ -2,8 +2,6 @@ import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
// import VConsole from 'vconsole';
|
||||
// new VConsole();
|
||||
|
||||
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/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');
|
||||
|
@@ -54,9 +54,11 @@
|
||||
import { reactive, watch,computed } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { useConnections, useForwardConnections, useTuntapConnections } from './connections';
|
||||
import { Delete } from '@element-plus/icons-vue';
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
emits: ['change','update:modelValue'],
|
||||
components: {Delete},
|
||||
setup(props, { emit }) {
|
||||
|
||||
const connections = useConnections();
|
||||
@@ -97,5 +99,4 @@ export default {
|
||||
<style lang="stylus" scoped>
|
||||
|
||||
.head{padding-bottom:1rem}
|
||||
.green{color:green}
|
||||
</style>
|
@@ -18,7 +18,7 @@
|
||||
<p class="flex">
|
||||
<span>{{ scope.row.IP }}</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>{{scope.row.Version}}</span>
|
||||
<template v-if="updater.list[scope.row.MachineId]">
|
||||
@@ -65,16 +65,21 @@ export default {
|
||||
const updater = useUpdater();
|
||||
const serverVersion = computed(()=>globalData.value.signin.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)=>{
|
||||
if(!updater.value.list[row.MachineId]){
|
||||
return '未检测到更新';
|
||||
}
|
||||
|
||||
if(updater.value.list[row.MachineId].Status <= 2) {
|
||||
return row.Version != serverVersion.value
|
||||
? `与服务器版本(${serverVersion.value})不一致,建议更新`
|
||||
: updaterVersion.value != row.Version
|
||||
? `不是最新版本(${updaterVersion.value}),建议更新` : '是最新版本,但我无法阻止你喜欢更新'
|
||||
? `不是最新版本(${updaterVersion.value}),建议更新\n${updaterMsg.value}`
|
||||
: `是最新版本,但我无法阻止你喜欢更新\n${updaterMsg.value}`
|
||||
}
|
||||
return {
|
||||
3:'正在下载',
|
||||
@@ -170,12 +175,8 @@ a{
|
||||
|
||||
a.download{
|
||||
margin-left:.6rem
|
||||
&.green{color:green}
|
||||
&.red{color:red}
|
||||
&.yellow{color:#e68906}
|
||||
.el-icon{
|
||||
vertical-align:middle;font-weight:bold;
|
||||
&.yellow{color:#e68906}
|
||||
&.loading{
|
||||
animation:loading 1s linear infinite;
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="!scope.row.isSelf">
|
||||
<template v-else>
|
||||
<div>
|
||||
<ul class="list sforward">
|
||||
<template v-if="sforward.list && sforward.list.length > 0">
|
||||
@@ -48,7 +48,6 @@
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>--</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
@@ -83,6 +82,5 @@ a{
|
||||
text-decoration: underline;
|
||||
font-weight:bold;
|
||||
}
|
||||
span.green,a.green{color:green}
|
||||
span.error{color:red}
|
||||
</style>
|
@@ -100,13 +100,13 @@
|
||||
import { onMounted, onUnmounted, reactive, watch } from 'vue';
|
||||
import { getForwardInfo, removeForwardInfo, addForwardInfo ,getForwardIpv4,testTargetForwardInfo,testListenForwardInfo } from '@/apis/forward'
|
||||
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 { useForward } from './forward';
|
||||
export default {
|
||||
props: ['data','modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
components:{WarnTriangleFilled},
|
||||
components:{WarnTriangleFilled,Delete},
|
||||
setup(props, { emit }) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
|
@@ -5,15 +5,7 @@
|
||||
<Tunnel @edit="handleTunnelEdit" @refresh="handleTunnelRefresh" @connections="handleTunnelConnections"></Tunnel>
|
||||
<Tuntap @edit="handleTuntapEdit" @refresh="handleTuntapRefresh"></Tuntap>
|
||||
<Forward @edit="_handleForwardEdit" @sedit="handleSForwardEdit"></Forward>
|
||||
<el-table-column label="操作" width="54" fixed="right">
|
||||
<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>
|
||||
<Oper @refresh="handlePageRefresh"></Oper>
|
||||
</el-table>
|
||||
<div class="page t-c">
|
||||
<div class="page-wrap">
|
||||
@@ -36,6 +28,7 @@
|
||||
import { subWebsocketState } from '@/apis/request.js'
|
||||
import { injectGlobalData } from '@/provide.js'
|
||||
import { reactive, onMounted, onUnmounted, computed } from 'vue'
|
||||
import Oper from './Oper.vue'
|
||||
import Device from './Device.vue'
|
||||
import DeviceEdit from './DeviceEdit.vue'
|
||||
import Tuntap from './Tuntap.vue'
|
||||
@@ -57,7 +50,7 @@ import { provideSforward } from './sforward'
|
||||
import { provideDevices } from './devices'
|
||||
import { provideUpdater } from './updater'
|
||||
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) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
@@ -164,8 +157,6 @@ export default {
|
||||
.home-list-wrap{
|
||||
padding:1rem;
|
||||
|
||||
.green{color:green;}
|
||||
|
||||
.page{padding-top:1rem}
|
||||
.page-wrap{
|
||||
display:inline-block;
|
||||
|
86
linker.web/src/views/devices/Oper.vue
Normal file
86
linker.web/src/views/devices/Oper.vue
Normal 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>
|
@@ -89,13 +89,13 @@
|
||||
import { onMounted, onUnmounted, reactive, watch } from 'vue';
|
||||
import { getSForwardInfo, removeSForwardInfo, addSForwardInfo,testLocalSForwardInfo } from '@/apis/sforward'
|
||||
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 { useSforward } from './sforward';
|
||||
export default {
|
||||
props: ['data','modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
components:{WarnTriangleFilled},
|
||||
components:{WarnTriangleFilled,Delete},
|
||||
setup(props, { emit }) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
|
@@ -2,17 +2,18 @@
|
||||
<el-table-column prop="tunnel" label="隧道" width="90">
|
||||
<template #default="scope">
|
||||
<div v-if="tunnel.list[scope.row.MachineId]">
|
||||
<p>
|
||||
<a href="javascript:;" class="a-line" @click="handleTunnel(tunnel.list[scope.row.MachineId])">
|
||||
<a href="javascript:;" class="a-line"
|
||||
: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>
|
||||
</a>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
<p>
|
||||
<div>
|
||||
<a href="javascript:;" class="a-line" @click="handleConnections(scope.row.MachineId)">
|
||||
<span>连接数 : {{connectionCount(scope.row.MachineId)}}</span>
|
||||
</a>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
@@ -54,6 +55,6 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.green{color:green;}
|
||||
|
||||
.el-switch.is-disabled{opacity :1;}
|
||||
</style>
|
@@ -82,6 +82,5 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.green{color:green;}
|
||||
.el-switch.is-disabled{opacity :1;}
|
||||
</style>
|
@@ -9,7 +9,7 @@
|
||||
<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">
|
||||
<template #reference>
|
||||
<strong class="error">{{ tuntap.list[scope.row.MachineId].IP }}</strong>
|
||||
<strong class="red">{{ tuntap.list[scope.row.MachineId].IP }}</strong>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
@@ -67,8 +67,6 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.green{color:green;}
|
||||
.error{color:red;}
|
||||
.el-switch.is-disabled{opacity :1;}
|
||||
.el-input{
|
||||
width:8rem;
|
||||
|
@@ -39,10 +39,11 @@ import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { reactive, ref, watch } from 'vue';
|
||||
import { useTuntap } from './tuntap';
|
||||
|
||||
import { Delete, Plus } from '@element-plus/icons-vue'
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
emits: ['change','update:modelValue'],
|
||||
components: {Delete,Plus},
|
||||
setup(props, { emit }) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
@@ -117,6 +118,5 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.green{color:green;}
|
||||
.el-switch.is-disabled{opacity :1;}
|
||||
</style>
|
@@ -25,6 +25,7 @@ export const provideDevices = () => {
|
||||
devices.page.Count = res.Count;
|
||||
for (let j in res.List) {
|
||||
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;
|
||||
}
|
||||
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.Args = res.List[j].Args;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -8,18 +8,21 @@ export const provideUpdater = () => {
|
||||
const updater = ref({
|
||||
timer: 0,
|
||||
list: {},
|
||||
current: { Version: '', Status: 0, Length: 0, Current: 0 }
|
||||
current: { Version: '', Msg: [], DateTime: '', Status: 0, Length: 0, Current: 0 }
|
||||
});
|
||||
provide(updaterSymbol, updater);
|
||||
const _getUpdater = () => {
|
||||
if (globalData.value.api.connected) {
|
||||
getUpdater().then((res) => {
|
||||
console.log(res);
|
||||
const self = Object.values(res).filter(c => !!c.Version)[0];
|
||||
if (self) {
|
||||
updater.value.current.DateTime = self.DateTime;
|
||||
updater.value.current.Version = self.Version;
|
||||
updater.value.current.Status = self.Status;
|
||||
updater.value.current.Length = self.Length;
|
||||
updater.value.current.Current = self.Current;
|
||||
updater.value.current.Msg = self.Msg;
|
||||
}
|
||||
updater.value.list = res;
|
||||
updater.value.timer = setTimeout(_getUpdater, 800);
|
||||
|
@@ -45,11 +45,12 @@ import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { computed, inject, onMounted, reactive } from 'vue'
|
||||
import Version from './Version.vue';
|
||||
import { Delete,Plus } from '@element-plus/icons-vue';
|
||||
export default {
|
||||
label:'打洞排除IP',
|
||||
name:'excludeIP',
|
||||
order:3,
|
||||
components:{Version},
|
||||
components:{Version,Delete,Plus},
|
||||
setup(props) {
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
|
@@ -83,11 +83,12 @@ import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { computed, inject, onMounted, reactive } from 'vue'
|
||||
import Version from './Version.vue';
|
||||
import { Delete,Plus,Top,Bottom } from '@element-plus/icons-vue';
|
||||
export default {
|
||||
label:'中继服务器',
|
||||
name:'relayServers',
|
||||
order:4,
|
||||
components:{Version},
|
||||
components:{Version,Delete,Plus,Top,Bottom},
|
||||
setup(props) {
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
|
@@ -52,11 +52,12 @@ import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { computed, inject, reactive } from 'vue'
|
||||
import Version from './Version.vue';
|
||||
import { Delete,Plus,Select } from '@element-plus/icons-vue';
|
||||
export default {
|
||||
label:'信标服务器',
|
||||
name:'signInServers',
|
||||
order:0,
|
||||
components:{Version},
|
||||
components:{Version,Delete,Plus,Select },
|
||||
setup(props) {
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
|
@@ -46,11 +46,12 @@ import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { computed, inject, onMounted, reactive } from 'vue'
|
||||
import Version from './Version.vue';
|
||||
import { Delete,Plus,Top,Bottom } from '@element-plus/icons-vue';
|
||||
export default {
|
||||
label:'打洞协议',
|
||||
name:'transports',
|
||||
order:2,
|
||||
components:{Version},
|
||||
components:{Version, Delete,Plus,Top,Bottom},
|
||||
setup(props) {
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
|
@@ -78,13 +78,14 @@
|
||||
import { setTunnelServers,getTunnelTypes } from '@/apis/tunnel';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { computed, inject, onMounted, reactive } from 'vue'
|
||||
import { computed, onMounted, reactive } from 'vue'
|
||||
import Version from './Version.vue';
|
||||
import { Delete,Plus,Top,Bottom } from '@element-plus/icons-vue';
|
||||
export default {
|
||||
label:'端口服务器',
|
||||
name:'tunnelServers',
|
||||
order:1,
|
||||
components:{Version},
|
||||
components:{Version,Delete,Plus,Top,Bottom},
|
||||
setup(props) {
|
||||
const globalData = injectGlobalData();
|
||||
const list = ((globalData.value.config.Running.Tunnel || {Servers:[]}).Servers || []).sort((a,b)=>a.Disabled - b.Disabled);
|
||||
|
@@ -25,8 +25,8 @@
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
<PackageReleaseNotes>linker</PackageReleaseNotes>
|
||||
<AssemblyVersion>1.1.2.2</AssemblyVersion>
|
||||
<FileVersion>1.1.2.2</FileVersion>
|
||||
<AssemblyVersion>1.1.2.3</AssemblyVersion>
|
||||
<FileVersion>1.1.2.3</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using linker.client.capi;
|
||||
using linker.config;
|
||||
using linker.config;
|
||||
using linker.libs;
|
||||
using linker.libs.api;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using linker.client.capi;
|
||||
using linker.config;
|
||||
using linker.config;
|
||||
using linker.startup;
|
||||
using linker.libs;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using linker.libs.api;
|
||||
using System.Reflection;
|
||||
|
||||
namespace linker.client.capi
|
||||
namespace linker.plugins.capi
|
||||
{
|
||||
public interface IApiClientController : IApiController
|
||||
{
|
@@ -1,7 +1,7 @@
|
||||
using linker.server;
|
||||
using linker.plugins.messenger;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace linker.client
|
||||
namespace linker.plugins.client
|
||||
{
|
||||
/// <summary>
|
||||
/// 登入对象
|
@@ -1,15 +1,16 @@
|
||||
using linker.client.args;
|
||||
using linker.client.config;
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.server;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using MemoryPack;
|
||||
using System.Net;
|
||||
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>
|
||||
/// 登入
|
||||
@@ -19,20 +20,20 @@ namespace linker.client
|
||||
private readonly ClientSignInState clientSignInState;
|
||||
private readonly RunningConfig runningConfig;
|
||||
private readonly FileConfig config;
|
||||
private readonly TcpServer tcpServer;
|
||||
private readonly MessengerSender messengerSender;
|
||||
private readonly MessengerResolver messengerResolver;
|
||||
private readonly SignInArgsTransfer signInArgsTransfer;
|
||||
private readonly RunningConfigTransfer runningConfigTransfer;
|
||||
|
||||
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.runningConfig = runningConfig;
|
||||
this.config = config;
|
||||
this.tcpServer = tcpServer;
|
||||
this.messengerSender = messengerSender;
|
||||
this.messengerResolver = messengerResolver;
|
||||
this.signInArgsTransfer = signInArgsTransfer;
|
||||
this.runningConfigTransfer = runningConfigTransfer;
|
||||
|
||||
@@ -131,7 +132,7 @@ namespace linker.client
|
||||
Socket socket = new Socket(remote.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
socket.KeepAlive();
|
||||
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;
|
||||
}
|
||||
@@ -169,6 +170,16 @@ namespace linker.client
|
||||
clientSignInState.Connection?.Disponse(6);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登出
|
||||
/// </summary>
|
||||
public void SignOut()
|
||||
{
|
||||
if (clientSignInState.Connected)
|
||||
clientSignInState.Connection.Disponse(5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务器版本
|
||||
/// </summary>
|
||||
@@ -189,14 +200,7 @@ namespace linker.client
|
||||
clientSignInState.Version = "v1.0.0.0";
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 登出
|
||||
/// </summary>
|
||||
public void SignOut()
|
||||
{
|
||||
if (clientSignInState.Connected)
|
||||
clientSignInState.Connection.Disponse(5);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 修改客户端名称
|
@@ -2,12 +2,10 @@
|
||||
using linker.startup;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
using linker.client.args;
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.client.config.messenger;
|
||||
using linker.plugins.client.args;
|
||||
|
||||
namespace linker.client
|
||||
namespace linker.plugins.client
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户端插件
|
||||
@@ -17,16 +15,11 @@ namespace linker.client
|
||||
public StartupLevel Level => StartupLevel.Bottom;
|
||||
public string Name => "client";
|
||||
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 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<ClientSignInState>();
|
||||
@@ -46,7 +39,7 @@ namespace linker.client
|
||||
|
||||
public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<ConfigServerMessenger>();
|
||||
|
||||
}
|
||||
public void UseServer(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)
|
||||
{
|
@@ -1,4 +1,4 @@
|
||||
namespace linker.client.args
|
||||
namespace linker.plugins.client.args
|
||||
{
|
||||
public interface ISignInArgs
|
||||
{
|
@@ -3,7 +3,7 @@ using linker.libs;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
|
||||
namespace linker.client.args
|
||||
namespace linker.plugins.client.args
|
||||
{
|
||||
public sealed class SignInArgsTransfer
|
||||
{
|
||||
@@ -12,7 +12,7 @@ namespace linker.client.args
|
||||
public SignInArgsTransfer(ServiceProvider serviceProvider, FileConfig config)
|
||||
{
|
||||
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)
|
@@ -1,8 +1,8 @@
|
||||
using linker.config;
|
||||
using linker.libs.api;
|
||||
using linker.libs.extends;
|
||||
using linker.client.capi;
|
||||
using linker.client.config;
|
||||
using linker.plugins.capi;
|
||||
|
||||
namespace linker.plugins.config
|
||||
{
|
||||
|
@@ -1,4 +1,6 @@
|
||||
using linker.config;
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.plugins.config.messenger;
|
||||
using linker.startup;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
@@ -11,19 +13,26 @@ namespace linker.plugins.config
|
||||
|
||||
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)
|
||||
{
|
||||
serviceCollection.AddSingleton<ConfigClientApiController>();
|
||||
|
||||
serviceCollection.AddSingleton<ConfigClientMessenger>();
|
||||
serviceCollection.AddSingleton<RunningConfigApiController>();
|
||||
|
||||
serviceCollection.AddSingleton<RunningConfig>();
|
||||
serviceCollection.AddSingleton<RunningConfigTransfer>();
|
||||
}
|
||||
|
||||
public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<ConfigServerMessenger>();
|
||||
}
|
||||
|
||||
public void UseClient(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)
|
||||
|
@@ -1,12 +1,13 @@
|
||||
using linker.libs.api;
|
||||
using linker.client.capi;
|
||||
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
|
||||
{
|
||||
private readonly RunningConfigTransfer runningConfigTransfer;
|
||||
private readonly RunningConfigTransfer runningConfigTransfer;
|
||||
|
||||
public RunningConfigApiController(RunningConfigTransfer runningConfigTransfer)
|
||||
{
|
@@ -1,6 +1,7 @@
|
||||
using linker.client.config.messenger;
|
||||
using linker.libs;
|
||||
using linker.server;
|
||||
using linker.libs;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.config.messenger;
|
||||
using linker.plugins.messenger;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
@@ -30,6 +31,7 @@ namespace linker.client.config
|
||||
/// </summary>
|
||||
public Memory<byte> Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置同步
|
||||
/// </summary>
|
@@ -1,8 +1,9 @@
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.server;
|
||||
using linker.client.config;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.signin.messenger;
|
||||
using MemoryPack;
|
||||
|
||||
namespace linker.client.config.messenger
|
||||
namespace linker.plugins.config.messenger
|
||||
{
|
||||
public sealed class ConfigServerMessenger : IMessenger
|
||||
{
|
@@ -1,4 +1,4 @@
|
||||
namespace linker.client.config.messenger
|
||||
namespace linker.plugins.config.messenger
|
||||
{
|
||||
public enum ConfigMessengerIds : ushort
|
||||
{
|
@@ -1,6 +1,5 @@
|
||||
using linker.libs.api;
|
||||
using linker.libs.extends;
|
||||
using linker.client.capi;
|
||||
using linker.client.config;
|
||||
using System.Net;
|
||||
using linker.libs;
|
||||
@@ -8,9 +7,10 @@ using linker.plugins.forward.proxy;
|
||||
using linker.tunnel.connection;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.plugins.forward.messenger;
|
||||
using linker.server;
|
||||
using linker.client;
|
||||
using MemoryPack;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.capi;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.forward
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@ namespace linker.plugins.forward
|
||||
public StartupLevel Level => StartupLevel.Normal;
|
||||
public string Name => "forward";
|
||||
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;
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
using linker.client;
|
||||
using linker.client.config;
|
||||
using linker.client.config;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.forward.messenger;
|
||||
using linker.plugins.forward.proxy;
|
||||
using linker.server;
|
||||
using linker.plugins.messenger;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using linker.client.config;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.server;
|
||||
using LiteDB;
|
||||
using MemoryPack;
|
||||
using System.Net;
|
||||
|
@@ -2,7 +2,7 @@
|
||||
using linker.libs.api;
|
||||
using linker.libs;
|
||||
using linker.config;
|
||||
using linker.client.capi;
|
||||
using linker.plugins.capi;
|
||||
|
||||
namespace linker.plugins.logger
|
||||
{
|
||||
|
@@ -6,7 +6,7 @@ using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace linker.server
|
||||
namespace linker.plugins.messenger
|
||||
{
|
||||
public interface IConnectionReceiveCallback
|
||||
{
|
||||
@@ -405,7 +405,7 @@ namespace linker.server
|
||||
{
|
||||
try
|
||||
{
|
||||
await callback.Receive(this, packet, this.userToken).ConfigureAwait(false);
|
||||
await callback.Receive(this, packet, userToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
@@ -1,4 +1,4 @@
|
||||
namespace linker.server
|
||||
namespace linker.plugins.messenger
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息接口
|
@@ -1,8 +1,15 @@
|
||||
using linker.libs;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
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>
|
||||
/// 消息处理总线
|
||||
@@ -17,12 +24,135 @@ namespace linker.server
|
||||
private readonly MessengerSender messengerSender;
|
||||
private readonly ServiceProvider serviceProvider;
|
||||
|
||||
private X509Certificate serverCertificate;
|
||||
public MessengerResolver(MessengerSender messengerSender, ServiceProvider serviceProvider)
|
||||
{
|
||||
this.messengerSender = messengerSender;
|
||||
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>
|
@@ -1,7 +1,7 @@
|
||||
using linker.libs;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace linker.server
|
||||
namespace linker.plugins.messenger
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息发送器
|
@@ -1,34 +1,31 @@
|
||||
using linker.config;
|
||||
using linker.startup;
|
||||
using linker.libs;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
|
||||
namespace linker.server
|
||||
namespace linker.plugins.messenger
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务端插件
|
||||
/// </summary>
|
||||
public sealed class ServerStartup : IStartup
|
||||
public sealed class MessengerStartup : IStartup
|
||||
{
|
||||
public StartupLevel Level => StartupLevel.Normal;
|
||||
public string Name => "server";
|
||||
public string Name => "messenger";
|
||||
public bool Required => true;
|
||||
public string[] Dependent => new string[] { "serialize", "firewall", "signin" };
|
||||
public string[] Dependent => new string[] { };
|
||||
public StartupLoadType LoadType => StartupLoadType.Normal;
|
||||
|
||||
public void AddClient(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<MessengerSender>();
|
||||
serviceCollection.AddSingleton<MessengerResolver>();
|
||||
serviceCollection.AddSingleton<TcpServer>();
|
||||
}
|
||||
|
||||
public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<MessengerSender>();
|
||||
serviceCollection.AddSingleton<MessengerResolver>();
|
||||
serviceCollection.AddSingleton<TcpServer>();
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +37,7 @@ namespace linker.server
|
||||
{
|
||||
MessengerResolver messengerResolver = serviceProvider.GetService<MessengerResolver>();
|
||||
messengerResolver.LoadMessenger(assemblies);
|
||||
messengerResolver.Init(config.Data.Server.Certificate, config.Data.Server.Password);
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
@@ -50,26 +48,9 @@ namespace linker.server
|
||||
{
|
||||
MessengerResolver messengerResolver = serviceProvider.GetService<MessengerResolver>();
|
||||
messengerResolver.LoadMessenger(assemblies);
|
||||
messengerResolver.Init(config.Data.Server.Certificate, config.Data.Server.Password);
|
||||
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}");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
using System.Buffers;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace linker.server
|
||||
namespace linker.plugins.messenger
|
||||
{
|
||||
/// <summary>
|
||||
/// 请求数据包
|
@@ -1,11 +1,11 @@
|
||||
using linker.client;
|
||||
using linker.client.capi;
|
||||
using linker.config;
|
||||
using linker.config;
|
||||
using linker.plugins.relay.messenger;
|
||||
using linker.server;
|
||||
using linker.libs.api;
|
||||
using linker.libs.extends;
|
||||
using MemoryPack;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.capi;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.relay
|
||||
{
|
||||
|
@@ -17,7 +17,7 @@ namespace linker.plugins.relay
|
||||
|
||||
public bool Required => false;
|
||||
|
||||
public string[] Dependent => new string[] { };
|
||||
public string[] Dependent => new string[] { "messenger", "signin", "serialize", "config" };
|
||||
|
||||
public StartupLoadType LoadType => StartupLoadType.Normal;
|
||||
|
||||
|
@@ -9,7 +9,7 @@ using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using MemoryPack;
|
||||
using linker.client;
|
||||
using linker.plugins.client;
|
||||
|
||||
namespace linker.plugins.relay
|
||||
{
|
||||
|
@@ -1,10 +1,11 @@
|
||||
using linker.config;
|
||||
using linker.plugins.relay.transport;
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.server;
|
||||
using linker.libs;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.plugins.server;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.relay.messenger
|
||||
{
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using linker.config;
|
||||
using linker.plugins.relay.messenger;
|
||||
using linker.server;
|
||||
using linker.tunnel.connection;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
@@ -11,6 +10,8 @@ using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using linker.plugins.server;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.relay.transport
|
||||
{
|
||||
@@ -20,15 +21,15 @@ namespace linker.plugins.relay.transport
|
||||
public RelayType Type => RelayType.Linker;
|
||||
public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp;
|
||||
|
||||
private readonly TcpServer tcpServer;
|
||||
private readonly MessengerResolver messengerResolver;
|
||||
private readonly MessengerSender messengerSender;
|
||||
|
||||
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;
|
||||
|
||||
string path = Path.GetFullPath(config.Data.Client.Certificate);
|
||||
@@ -46,7 +47,7 @@ namespace linker.plugins.relay.transport
|
||||
socket.KeepAlive();
|
||||
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
|
||||
{
|
||||
Connection = connection,
|
||||
@@ -114,7 +115,7 @@ namespace linker.plugins.relay.transport
|
||||
socket.KeepAlive();
|
||||
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
|
||||
{
|
||||
Connection = connection,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using MemoryPack;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.serializes
|
||||
namespace linker.plugins.serializes
|
||||
{
|
||||
/// <summary>
|
||||
/// MemoryPack 的 IPAddress序列化扩展
|
||||
@@ -25,7 +25,7 @@ namespace linker.serializes
|
||||
span[0] = (byte)bytesWritten;
|
||||
|
||||
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)
|
@@ -2,7 +2,7 @@
|
||||
using MemoryPack;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.serializes
|
||||
namespace linker.plugins.serializes
|
||||
{
|
||||
/// <summary>
|
||||
/// MemoryPack 的 IPEndPoint序列化扩展
|
@@ -4,7 +4,7 @@ using MemoryPack;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
|
||||
namespace linker.serializes
|
||||
namespace linker.plugins.serializes
|
||||
{
|
||||
/// <summary>
|
||||
/// MemoryPack 序列化扩展加载插件
|
53
linker/plugins/server/ServerStartup.cs
Normal file
53
linker/plugins/server/ServerStartup.cs
Normal 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}");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
127
linker/plugins/server/TcpServer.cs
Normal file
127
linker/plugins/server/TcpServer.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +1,11 @@
|
||||
using linker.libs.api;
|
||||
using linker.libs.extends;
|
||||
using linker.client.capi;
|
||||
using linker.client.config;
|
||||
using linker.client;
|
||||
using linker.server;
|
||||
using MemoryPack;
|
||||
using linker.plugins.sforward.messenger;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.capi;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.sforward
|
||||
{
|
||||
|
@@ -18,7 +18,7 @@ namespace linker.plugins.sforward
|
||||
|
||||
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;
|
||||
|
||||
|
@@ -1,13 +1,13 @@
|
||||
using linker.client.config;
|
||||
using linker.client;
|
||||
using linker.libs;
|
||||
using linker.server;
|
||||
using linker.plugins.sforward.messenger;
|
||||
using MemoryPack;
|
||||
using linker.plugins.sforward.config;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using linker.libs.extends;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.sforward
|
||||
{
|
||||
|
@@ -2,13 +2,13 @@
|
||||
using linker.plugins.sforward.config;
|
||||
using linker.plugins.sforward.validator;
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.server;
|
||||
using MemoryPack;
|
||||
using linker.plugins.sforward.proxy;
|
||||
using linker.config;
|
||||
using LiteDB;
|
||||
using System.Net;
|
||||
using linker.plugins.forward.messenger;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.sforward.messenger
|
||||
{
|
||||
|
@@ -1,5 +1,5 @@
|
||||
using linker.plugins.sforward.config;
|
||||
using linker.server;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.sforward.config;
|
||||
|
||||
namespace linker.plugins.sforward.validator
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using linker.config;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.sforward.config;
|
||||
using linker.server;
|
||||
|
||||
namespace linker.plugins.sforward.validator
|
||||
{
|
||||
|
@@ -2,10 +2,10 @@
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.libs.api;
|
||||
using linker.libs.extends;
|
||||
using linker.client;
|
||||
using linker.server;
|
||||
using MemoryPack;
|
||||
using linker.client.capi;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.capi;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.signin
|
||||
{
|
||||
|
@@ -13,7 +13,7 @@ namespace linker.plugins.signin
|
||||
|
||||
public bool Required => false;
|
||||
|
||||
public string[] Dependent => new string[] { };
|
||||
public string[] Dependent => new string[] { "messenger", };
|
||||
|
||||
public StartupLoadType LoadType => StartupLoadType.Normal;
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
using linker.store;
|
||||
using linker.server;
|
||||
using linker.libs;
|
||||
using LiteDB;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using System.Text.Json.Serialization;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.signin.messenger
|
||||
{
|
||||
|
@@ -1,8 +1,8 @@
|
||||
using linker.client;
|
||||
using linker.config;
|
||||
using linker.server;
|
||||
using linker.libs;
|
||||
using linker.config;
|
||||
using MemoryPack;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.server;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.signin.messenger
|
||||
{
|
||||
|
@@ -1,8 +1,6 @@
|
||||
using linker.client;
|
||||
using linker.client.config;
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.plugins.tunnel.messenger;
|
||||
using linker.server;
|
||||
using linker.tunnel.adapter;
|
||||
using linker.tunnel.transport;
|
||||
using linker.libs;
|
||||
@@ -11,6 +9,8 @@ using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using linker.tunnel.wanport;
|
||||
using System.Buffers.Binary;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.tunnel
|
||||
{
|
||||
|
@@ -1,8 +1,5 @@
|
||||
using linker.client;
|
||||
using linker.client.capi;
|
||||
using linker.config;
|
||||
using linker.config;
|
||||
using linker.plugins.tunnel.messenger;
|
||||
using linker.server;
|
||||
using linker.tunnel.adapter;
|
||||
using linker.tunnel.transport;
|
||||
using linker.libs.api;
|
||||
@@ -11,6 +8,10 @@ using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.tunnel.wanport;
|
||||
using linker.client.config;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.server;
|
||||
using linker.plugins.capi;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.tunnel
|
||||
{
|
||||
|
@@ -1,12 +1,14 @@
|
||||
using linker.client;
|
||||
using linker.client.config;
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.libs;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.tunnel.messenger;
|
||||
using linker.server;
|
||||
using linker.tunnel.adapter;
|
||||
using linker.tunnel.wanport;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net.Quic;
|
||||
|
||||
namespace linker.plugins.tunnel
|
||||
{
|
||||
@@ -35,20 +37,14 @@ namespace linker.plugins.tunnel
|
||||
this.runningConfigTransfer = runningConfigTransfer;
|
||||
this.tunnelAdapter = tunnelAdapter;
|
||||
|
||||
clientSignInState.NetworkEnabledHandle += (times) =>
|
||||
{
|
||||
GetRemoveRouteLevel();
|
||||
};
|
||||
clientSignInState.NetworkFirstEnabledHandle += () =>
|
||||
{
|
||||
SyncExcludeIP();
|
||||
};
|
||||
|
||||
InitRouteLevel();
|
||||
InitExcludeIP();
|
||||
InitConfig();
|
||||
|
||||
runningConfigTransfer.Setter(exipConfigKey, SettExcludeIPs);
|
||||
runningConfigTransfer.Getter(exipConfigKey, () => MemoryPackSerializer.Serialize(GetExcludeIPs()));
|
||||
|
||||
TestQuic();
|
||||
}
|
||||
|
||||
private void InitConfig()
|
||||
{
|
||||
bool updateVersion = false;
|
||||
@@ -85,7 +81,7 @@ namespace linker.plugins.tunnel
|
||||
/// </summary>
|
||||
public void RefreshConfig()
|
||||
{
|
||||
GetRemoveRouteLevel();
|
||||
GetRemoteRouteLevel();
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改自己的网关层级信息
|
||||
@@ -95,7 +91,7 @@ namespace linker.plugins.tunnel
|
||||
{
|
||||
running.Data.Tunnel.RouteLevelPlus = tunnelTransportFileConfigInfo.RouteLevelPlus;
|
||||
running.Data.Update();
|
||||
GetRemoveRouteLevel();
|
||||
GetRemoteRouteLevel();
|
||||
}
|
||||
/// <summary>
|
||||
/// 收到别人发给我的修改我的信息
|
||||
@@ -108,7 +104,7 @@ namespace linker.plugins.tunnel
|
||||
Interlocked.Increment(ref version);
|
||||
return GetLocalRouteLevel();
|
||||
}
|
||||
private void GetRemoveRouteLevel()
|
||||
private void GetRemoteRouteLevel()
|
||||
{
|
||||
TunnelTransportRouteLevelInfo config = GetLocalRouteLevel();
|
||||
messengerSender.SendReply(new MessageRequestWrap
|
||||
@@ -138,11 +134,28 @@ namespace linker.plugins.tunnel
|
||||
{
|
||||
MachineId = config.Data.Client.Id,
|
||||
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()
|
||||
{
|
||||
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.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.dll,please 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ namespace linker.plugins.tunnel
|
||||
|
||||
public bool Required => false;
|
||||
|
||||
public string[] Dependent => new string[] { };
|
||||
public string[] Dependent => new string[] { "messenger", "signin", "serialize", "config" };
|
||||
|
||||
public StartupLoadType LoadType => StartupLoadType.Normal;
|
||||
|
||||
|
@@ -72,6 +72,8 @@ namespace linker.config
|
||||
public string MachineId { get; set; }
|
||||
public int RouteLevel { get; set; } = 0;
|
||||
public int RouteLevelPlus { get; set; } = 0;
|
||||
|
||||
public bool NeedReboot { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
using linker.config;
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.server;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.adapter;
|
||||
using linker.tunnel.transport;
|
||||
using linker.libs;
|
||||
using MemoryPack;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.tunnel.messenger
|
||||
{
|
||||
|
@@ -1,16 +1,16 @@
|
||||
using linker.server;
|
||||
using linker.libs.api;
|
||||
using linker.libs.api;
|
||||
using linker.plugins.tuntap.vea;
|
||||
using linker.client;
|
||||
using linker.plugins.tuntap.messenger;
|
||||
using MemoryPack;
|
||||
using linker.libs.extends;
|
||||
using linker.client.capi;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.config;
|
||||
using linker.plugins.forward.proxy;
|
||||
using linker.tunnel.connection;
|
||||
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
|
||||
{
|
||||
|
@@ -16,7 +16,7 @@ namespace linker.plugins.tuntap
|
||||
public StartupLevel Level => StartupLevel.Normal;
|
||||
public string Name => "tuntap";
|
||||
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;
|
||||
|
||||
|
@@ -1,10 +1,8 @@
|
||||
using linker.client;
|
||||
using linker.client.config;
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.plugins.tuntap.messenger;
|
||||
using linker.plugins.tuntap.proxy;
|
||||
using linker.plugins.tuntap.vea;
|
||||
using linker.server;
|
||||
using linker.libs;
|
||||
using MemoryPack;
|
||||
using System.Buffers.Binary;
|
||||
@@ -13,6 +11,8 @@ using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using linker.libs.extends;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.tuntap
|
||||
{
|
||||
|
@@ -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.server;
|
||||
using MemoryPack;
|
||||
|
||||
namespace linker.plugins.tuntap.messenger
|
||||
|
@@ -1,7 +1,4 @@
|
||||
using linker.server;
|
||||
using linker.libs.api;
|
||||
using linker.client;
|
||||
using linker.client.capi;
|
||||
using linker.libs.api;
|
||||
using linker.config;
|
||||
using linker.plugins.updater.messenger;
|
||||
using MemoryPack;
|
||||
@@ -9,6 +6,9 @@ using System.Collections.Concurrent;
|
||||
using linker.plugins.updater.config;
|
||||
using linker.libs.extends;
|
||||
using linker.client.config;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.capi;
|
||||
using linker.plugins.messenger;
|
||||
|
||||
namespace linker.plugins.updater
|
||||
{
|
||||
|
@@ -1,8 +1,9 @@
|
||||
using linker.client;
|
||||
using linker.client.config;
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.server;
|
||||
using linker.plugins.updater.messenger;
|
||||
using linker.server;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
@@ -78,7 +79,6 @@ namespace linker.plugins.updater
|
||||
{
|
||||
updaterHelper.Confirm(updateInfo, version);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 来自别的客户端的更新信息
|
||||
/// </summary>
|
||||
|
@@ -36,10 +36,11 @@ namespace linker.plugins.updater
|
||||
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));
|
||||
|
||||
Match match = new Regex(@"/snltty/linker/tree/(v[\d.]+)").Match(str);
|
||||
string tag = match.Groups[1].Value;
|
||||
string datetime = DateTime.Parse(new Regex("datetime=\"(.+)\"").Match(str).Groups[1].Value).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
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();
|
||||
|
||||
updateInfo.DateTime = datetime;
|
||||
updateInfo.Msg = msg;
|
||||
updateInfo.Version = tag;
|
||||
|
||||
@@ -243,6 +244,8 @@ namespace linker.plugins.updater
|
||||
public string Version { get; set; }
|
||||
[MemoryPackIgnore]
|
||||
public string[] Msg { get; set; }
|
||||
[MemoryPackIgnore]
|
||||
public string DateTime { get; set; }
|
||||
|
||||
public string MachineId { get; set; }
|
||||
public UpdateStatus Status { get; set; } = UpdateStatus.None;
|
||||
|
@@ -17,7 +17,7 @@ namespace linker.plugins.updater
|
||||
|
||||
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;
|
||||
|
||||
|
@@ -1,7 +1,8 @@
|
||||
using linker.config;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.server;
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.plugins.updater.config;
|
||||
using linker.server;
|
||||
using MemoryPack;
|
||||
|
||||
namespace linker.plugins.updater.messenger
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user