mirror of
https://github.com/snltty/linker.git
synced 2025-09-26 21:15:57 +08:00
191
This commit is contained in:
2
.github/workflows/dotnet.yml
vendored
2
.github/workflows/dotnet.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
release_name: v1.9.1.${{ steps.date.outputs.today }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
body: "1. 一些累计更新\r\n2. 服务器转发多节点\r\n3. 虚拟网卡下伪造ACK为TCP-in-TCP隧道提速\r\n4. 一些代码优化、修复一些错误\r\n5. 优化打洞\r\n6. 其它一些小改变"
|
||||
body: "1. 一些累计更新\r\n2. 服务器转发多节点\r\n3. 虚拟网卡下伪造ACK为TCP-in-TCP隧道提速\r\n4. 一些代码优化、修复一些错误\r\n5. 新增一个UDP同时打开的打洞协议,优化了一下TCP同时打开的打洞协议\r\n6. 其它一些小改变"
|
||||
- name: publish projects
|
||||
run: ./publish.bat "C:\\Android\\android-sdk"
|
||||
- name: upload-win-x86-oss
|
||||
|
1
src/linker.app/public/web/css/243.051707b5.css
Normal file
1
src/linker.app/public/web/css/243.051707b5.css
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/css/342.3b11288c.css
Normal file
1
src/linker.app/public/web/css/342.3b11288c.css
Normal file
@@ -0,0 +1 @@
|
||||
.el-radio-group[data-v-72593913]{margin-right:.6rem}.wrap[data-v-72593913]{padding-bottom:1rem}.el-form-item[data-v-4af2067e]{margin-bottom:1rem}.el-input-number--small[data-v-4af2067e]{width:10rem!important}.el-form-item[data-v-7ea96748]{margin-bottom:1rem}.el-input-number--small[data-v-7ea96748]{width:10rem!important}.head .search>div[data-v-1fe12153]{margin-right:1rem}.page[data-v-1fe12153]{padding:2rem 0;display:inline-block}.el-form-item[data-v-1fe12153]{margin-bottom:1rem}.el-input-number--small[data-v-1fe12153]{width:10rem!important}.head .search>div[data-v-6a696afb]{margin-right:1rem}.page[data-v-6a696afb]{padding:2rem 0;display:inline-block}.el-form-item[data-v-6a696afb]{margin-bottom:1rem}.el-input-number--small[data-v-6a696afb]{width:10rem!important}.el-transfer.src-tranfer .el-transfer__buttons .el-button{display:block}.el-transfer.src-tranfer .el-transfer__buttons .el-button:nth-child(2){margin:1rem 0 0 0}.el-form-item[data-v-26eb3ac8]{margin-bottom:1rem}.el-input-number--small[data-v-26eb3ac8]{width:10rem!important}.blue[data-v-92ae2ca2]{color:#409eff}.el-checkbox[data-v-92ae2ca2]{font-weight:100}a.a-edit .el-icon[data-v-92ae2ca2]{vertical-align:middle}.el-form-item[data-v-70160c48]{margin-bottom:1rem}.el-input-number--small[data-v-70160c48]{width:10rem!important}.head .search>div[data-v-7977ca92]{margin-right:1rem}.page[data-v-7977ca92]{padding:2rem 0;display:inline-block}.el-form-item[data-v-7977ca92]{margin-bottom:1rem}.el-input-number--small[data-v-7977ca92]{width:10rem!important}.blue[data-v-e76dff3a]{color:#409eff}a.a-edit[data-v-e76dff3a]{margin-left:1rem}a.a-edit .el-icon[data-v-e76dff3a]{vertical-align:middle}.el-form-item[data-v-06530694]{margin-bottom:1rem}.el-input-number--small[data-v-06530694]{width:10rem!important}.el-checkbox[data-v-09d3b4fe]{font-weight:100}a.a-edit .el-icon[data-v-09d3b4fe]{vertical-align:middle}.servers-wrap[data-v-3b21a224]{padding:1rem;font-size:1.3rem;color:#555}.servers-wrap a[data-v-3b21a224]{color:#333}
|
1
src/linker.app/public/web/css/54.ca171b7e.css
Normal file
1
src/linker.app/public/web/css/54.ca171b7e.css
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/css/708.e06d915f.css
Normal file
1
src/linker.app/public/web/css/708.e06d915f.css
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/css/app.e16885f2.css
Normal file
1
src/linker.app/public/web/css/app.e16885f2.css
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/><script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script><script defer="defer" src="js/chunk-vendors.3e624437.js"></script><script defer="defer" src="js/app.a82999c6.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.db9830c6.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/><script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script><script defer="defer" src="js/chunk-vendors.e9b4f2f4.js"></script><script defer="defer" src="js/app.d3e1d5d0.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.e16885f2.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
1
src/linker.app/public/web/js/243.6889156d.js
Normal file
1
src/linker.app/public/web/js/243.6889156d.js
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/js/276.3b6183fb.js
Normal file
1
src/linker.app/public/web/js/276.3b6183fb.js
Normal file
@@ -0,0 +1 @@
|
||||
"use strict";(self["webpackChunklinker_web"]=self["webpackChunklinker_web"]||[]).push([[276],{35377:function(e,s,t){t.d(s,{A:function(){return b}});var a=t(56768),n=t(24232);const l={class:"t-c"},c={class:"t-c w-100 mgt-1"};function o(e,s,t,o,r,d){const i=(0,a.g2)("Share"),u=(0,a.g2)("el-icon"),m=(0,a.g2)("el-button"),h=(0,a.g2)("el-transfer"),f=(0,a.g2)("el-dialog");return(0,a.uX)(),(0,a.CE)("div",null,[(0,a.RG)(e.$slots,"default",{},(()=>[(0,a.bF)(m,{class:"btn",size:"small",onClick:o.handleShowSync},{default:(0,a.k6)((()=>[(0,a.bF)(u,null,{default:(0,a.k6)((()=>[(0,a.bF)(i)])),_:1})])),_:1},8,["onClick"])])),(0,a.bF)(f,{class:"options-center",title:e.$t("server.sync"),"destroy-on-close":"",modelValue:o.state.showNames,"onUpdate:modelValue":s[2]||(s[2]=e=>o.state.showNames=e),width:"54rem",top:"2vh"},{default:(0,a.k6)((()=>[(0,a.Lk)("div",null,[(0,a.Lk)("div",l,(0,n.v_)(`${e.$t("server.sync")}【${e.$t(`server.async${o.state.name}`)}】${e.$t("server.asyncText")}`),1),(0,a.bF)(h,{class:"src-tranfer mgt-1",modelValue:o.state.srcIdValues,"onUpdate:modelValue":s[0]||(s[0]=e=>o.state.srcIdValues=e),filterable:"","filter-method":o.srcFilterMethod,data:o.state.srcIds,titles:[e.$t("firewall.unselect"),e.$t("firewall.selected")],props:{key:"MachineId",label:"MachineName"}},null,8,["modelValue","filter-method","data","titles"]),(0,a.Lk)("div",c,[(0,a.bF)(m,{onClick:s[1]||(s[1]=e=>o.state.showNames=!1)},{default:(0,a.k6)((()=>[(0,a.eW)((0,n.v_)(e.$t("common.cancel")),1)])),_:1}),(0,a.bF)(m,{type:"primary",onClick:o.handleConfirm},{default:(0,a.k6)((()=>[(0,a.eW)((0,n.v_)(e.$t("common.confirm")),1)])),_:1},8,["onClick"])])])])),_:1},8,["title","modelValue"])])}var r=t(69299),d=t(10004);const i=e=>(0,d.zG)("sync/Sync",e);var u=t(53830),m=t(57477),h=t(51219),f=t(90144),v=t(35931),k={props:["name"],components:{Share:m.SYj},setup(e){const{t:s}=(0,v.s9)(),t=(0,u.B)(),n=(0,a.EW)((()=>t.value.hasAccess("Sync"))),l=(0,f.Kh)({name:e.name,loading:!1,showNames:!1,srcIdValues:[],srcIds:[]}),c=()=>{i({names:[e.name],ids:l.srcIdValues}).then((e=>{h.nk.success(s("common.oper")),l.showNames=!1}))},o=()=>{n.value?(l.showNames=!0,d()):h.nk.success(s("common.access"))},d=()=>{l.loading=!0,(0,r.NT)().then((e=>{l.loading=!1,l.srcIds=e})).catch((e=>{l.loading=!1}))},m=(e,s)=>s.MachineName.toLowerCase().includes(e.toLowerCase());return{state:l,handleShowSync:o,srcFilterMethod:m,handleConfirm:c}}},w=t(71241);const p=(0,w.A)(k,[["render",o]]);var b=p},83384:function(e,s,t){t.r(s),t.d(s,{default:function(){return m}});var a=t(56768);const n={class:"firewall-setting-wrap flex flex-column h-100"},l={class:"inner"};function c(e,s,t,c,o,r){const d=(0,a.g2)("Firewall");return(0,a.uX)(),(0,a.CE)("div",n,[(0,a.Lk)("div",l,[(0,a.bF)(d)])])}var o=t(90144),r=t(63733),d={components:{Firewall:r.A},setup(e,{emit:s}){const t=(0,o.Kh)({});return{state:t}}},i=t(71241);const u=(0,i.A)(d,[["render",c],["__scopeId","data-v-101dd60e"]]);var m=u}}]);
|
1
src/linker.app/public/web/js/331.8ea253d9.js
Normal file
1
src/linker.app/public/web/js/331.8ea253d9.js
Normal file
File diff suppressed because one or more lines are too long
277
src/linker.app/public/web/js/342.a96755cf.js
Normal file
277
src/linker.app/public/web/js/342.a96755cf.js
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/js/52.e5d98938.js
Normal file
1
src/linker.app/public/web/js/52.e5d98938.js
Normal file
@@ -0,0 +1 @@
|
||||
"use strict";(self["webpackChunklinker_web"]=self["webpackChunklinker_web"]||[]).push([[52],{96271:function(e,t,n){n.d(t,{A:function(){return b}});var a=n(56768),s=n(24232);const o={class:"flex"},c={class:"flex-1"},r={class:"t-c"};function l(e,t,n,l,d,i){const u=(0,a.g2)("Sync"),m=(0,a.g2)("el-input"),h=(0,a.g2)("el-button"),v=(0,a.g2)("el-card"),f=(0,a.gN)("trim");return(0,a.uX)(),(0,a.Wv)(v,{shadow:"never"},{header:(0,a.k6)((()=>[(0,a.Lk)("div",o,[(0,a.Lk)("span",c,(0,s.v_)(e.$t("action.text")),1),l.state.isSelf?((0,a.uX)(),(0,a.Wv)(u,{key:0,name:"ActionStatic"})):(0,a.Q3)("",!0)])])),footer:(0,a.k6)((()=>[(0,a.Lk)("div",r,[(0,a.bF)(h,{type:"success",onClick:l.handleSave},{default:(0,a.k6)((()=>[(0,a.eW)((0,s.v_)(e.$t("common.confirm")),1)])),_:1},8,["onClick"])])])),default:(0,a.k6)((()=>[(0,a.Lk)("div",null,[(0,a.bo)((0,a.bF)(m,{modelValue:l.state.data,"onUpdate:modelValue":t[0]||(t[0]=e=>l.state.data=e),rows:10,type:"textarea",resize:"none",onChange:l.handleSave},null,8,["modelValue","onChange"]),[[f]])])])),_:1})}var d=n(10004);const i=e=>(0,d.zG)("action/GetServerArgs",e),u=e=>(0,d.zG)("action/SetServerArgs",e);var m=n(53830),h=n(51219),v=n(90144),f=n(35931),k=n(35377),p={props:["machineId"],components:{Sync:k.A},setup(e){const{t:t}=(0,f.s9)(),n=(0,m.B)(),s=(0,v.Kh)({data:"",machineId:e.machineId||n.value.config.Client.Id,isSelf:(0,a.EW)((()=>s.machineId==n.value.config.Client.Id))}),o=()=>{i(s.machineId).then((e=>{s.data=e}))},c=()=>{try{if(s.data&&"object"!=typeof JSON.parse(s.data))return void h.nk.error(t("action.jsonError"))}catch(e){return void h.nk.error(t("action.jsonError"))}u({Key:s.machineId,Value:s.data}).then((()=>{h.nk.success(t("common.oper"))})).catch((e=>{console.log(e),h.nk.error(t("common.operFail"))}))};return(0,a.sV)((()=>{o()})),{state:s,handleSave:c}}},g=n(71241);const I=(0,g.A)(p,[["render",l]]);var b=I},35377:function(e,t,n){n.d(t,{A:function(){return I}});var a=n(56768),s=n(24232);const o={class:"t-c"},c={class:"t-c w-100 mgt-1"};function r(e,t,n,r,l,d){const i=(0,a.g2)("Share"),u=(0,a.g2)("el-icon"),m=(0,a.g2)("el-button"),h=(0,a.g2)("el-transfer"),v=(0,a.g2)("el-dialog");return(0,a.uX)(),(0,a.CE)("div",null,[(0,a.RG)(e.$slots,"default",{},(()=>[(0,a.bF)(m,{class:"btn",size:"small",onClick:r.handleShowSync},{default:(0,a.k6)((()=>[(0,a.bF)(u,null,{default:(0,a.k6)((()=>[(0,a.bF)(i)])),_:1})])),_:1},8,["onClick"])])),(0,a.bF)(v,{class:"options-center",title:e.$t("server.sync"),"destroy-on-close":"",modelValue:r.state.showNames,"onUpdate:modelValue":t[2]||(t[2]=e=>r.state.showNames=e),width:"54rem",top:"2vh"},{default:(0,a.k6)((()=>[(0,a.Lk)("div",null,[(0,a.Lk)("div",o,(0,s.v_)(`${e.$t("server.sync")}【${e.$t(`server.async${r.state.name}`)}】${e.$t("server.asyncText")}`),1),(0,a.bF)(h,{class:"src-tranfer mgt-1",modelValue:r.state.srcIdValues,"onUpdate:modelValue":t[0]||(t[0]=e=>r.state.srcIdValues=e),filterable:"","filter-method":r.srcFilterMethod,data:r.state.srcIds,titles:[e.$t("firewall.unselect"),e.$t("firewall.selected")],props:{key:"MachineId",label:"MachineName"}},null,8,["modelValue","filter-method","data","titles"]),(0,a.Lk)("div",c,[(0,a.bF)(m,{onClick:t[1]||(t[1]=e=>r.state.showNames=!1)},{default:(0,a.k6)((()=>[(0,a.eW)((0,s.v_)(e.$t("common.cancel")),1)])),_:1}),(0,a.bF)(m,{type:"primary",onClick:r.handleConfirm},{default:(0,a.k6)((()=>[(0,a.eW)((0,s.v_)(e.$t("common.confirm")),1)])),_:1},8,["onClick"])])])])),_:1},8,["title","modelValue"])])}var l=n(69299),d=n(10004);const i=e=>(0,d.zG)("sync/Sync",e);var u=n(53830),m=n(57477),h=n(51219),v=n(90144),f=n(35931),k={props:["name"],components:{Share:m.SYj},setup(e){const{t:t}=(0,f.s9)(),n=(0,u.B)(),s=(0,a.EW)((()=>n.value.hasAccess("Sync"))),o=(0,v.Kh)({name:e.name,loading:!1,showNames:!1,srcIdValues:[],srcIds:[]}),c=()=>{i({names:[e.name],ids:o.srcIdValues}).then((e=>{h.nk.success(t("common.oper")),o.showNames=!1}))},r=()=>{s.value?(o.showNames=!0,d()):h.nk.success(t("common.access"))},d=()=>{o.loading=!0,(0,l.NT)().then((e=>{o.loading=!1,o.srcIds=e})).catch((e=>{o.loading=!1}))},m=(e,t)=>t.MachineName.toLowerCase().includes(e.toLowerCase());return{state:o,handleShowSync:r,srcFilterMethod:m,handleConfirm:c}}},p=n(71241);const g=(0,p.A)(k,[["render",r]]);var I=g},5052:function(e,t,n){n.r(t),n.d(t,{default:function(){return u}});var a=n(56768);const s={class:"action-wrap"};function o(e,t,n,o,c,r){const l=(0,a.g2)("Action");return(0,a.uX)(),(0,a.CE)("div",s,[(0,a.bF)(l,{machineId:o.state.machineId},null,8,["machineId"])])}var c=n(90144),r=n(96271),l={props:["machineId"],components:{Action:r.A},setup(e){const t=(0,c.Kh)({machineId:e.machineId});return{state:t}}},d=n(71241);const i=(0,d.A)(l,[["render",o],["__scopeId","data-v-08c763b2"]]);var u=i}}]);
|
1
src/linker.app/public/web/js/522.d9fe5cd7.js
Normal file
1
src/linker.app/public/web/js/522.d9fe5cd7.js
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/js/54.38d63fd7.js
Normal file
1
src/linker.app/public/web/js/54.38d63fd7.js
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/js/698.80cb6f77.js
Normal file
1
src/linker.app/public/web/js/698.80cb6f77.js
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/js/708.a4aca4ed.js
Normal file
1
src/linker.app/public/web/js/708.a4aca4ed.js
Normal file
@@ -0,0 +1 @@
|
||||
"use strict";(self["webpackChunklinker_web"]=self["webpackChunklinker_web"]||[]).push([[708],{87414:function(e,a,n){n.r(a),n.d(a,{default:function(){return J}});var t=n(56768);const s={class:"net-wrap app-wrap"},l={class:"inner absolute flex flex-column flex-nowrap"},i={class:"head"},u={class:"body flex-1 relative"},r={class:"status"};function c(e,a,n,c,d,o){const g=(0,t.g2)("Head"),p=(0,t.g2)("List"),v=(0,t.g2)("Status");return(0,t.uX)(),(0,t.CE)("div",s,[(0,t.Lk)("div",l,[(0,t.Lk)("div",i,[(0,t.bF)(g)]),(0,t.Lk)("div",u,[(0,t.bF)(p)]),(0,t.Lk)("div",r,[(0,t.bF)(v,{config:!1})])])])}n(44114);var d=n(24232);const o=e=>((0,t.Qi)("data-v-1cb47bd6"),e=e(),(0,t.jt)(),e),g={class:"head-wrap"},p={class:"tools flex"},v={class:"label"},h=o((()=>(0,t.Lk)("span",{class:"flex-1"},null,-1))),f={style:{"margin-left":"1rem"}};function k(e,a,n,s,l,i){const u=(0,t.g2)("Refresh"),r=(0,t.g2)("el-icon"),c=(0,t.g2)("el-button"),o=(0,t.g2)("Background");return(0,t.uX)(),(0,t.CE)("div",g,[(0,t.Lk)("div",p,[(0,t.Lk)("span",v,"分组 : "+(0,d.v_)(s.state.group),1),h,(0,t.bF)(c,{size:"small",onClick:s.handleRefresh},{default:(0,t.k6)((()=>[(0,t.eW)(" 刷新(F5)"),(0,t.bF)(r,null,{default:(0,t.k6)((()=>[(0,t.bF)(u)])),_:1})])),_:1},8,["onClick"]),(0,t.Lk)("div",f,[(0,t.bF)(o,{name:"net"})])])])}var b=n(53830),m=n(90144),C=n(57477),L=n(7199),_={components:{Edit:C.ffu,Refresh:C.C42,Background:L.A},setup(){const e=(0,b.B)(),a=(0,m.Kh)({server:(0,t.EW)((()=>e.value.config.Client.Server.Host)),group:(0,t.EW)((()=>e.value.config.Client.Group.Name))}),n=()=>{window.location.reload()};return{state:a,handleRefresh:n}}},w=n(71241);const S=(0,w.A)(_,[["render",k],["__scopeId","data-v-1cb47bd6"]]);var x=S;const F=e=>((0,t.Qi)("data-v-3c358101"),e=e(),(0,t.jt)(),e),z={class:"net-list-wrap flex flex-column absolute"},E={class:"flex-1 scrollbar"},T={class:"flex"},A=F((()=>(0,t.Lk)("div",{class:"flex-1"},null,-1))),I={class:"tuntap"},P={class:"page t-c"},B={class:"page-wrap t-c"};function R(e,a,n,s,l,i){const u=(0,t.g2)("DeviceName"),r=(0,t.g2)("UpdaterBtn"),c=(0,t.g2)("TuntapShow"),d=(0,t.g2)("el-pagination");return(0,t.uX)(),(0,t.CE)("div",z,[(0,t.Lk)("div",E,[(0,t.Lk)("ul",null,[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(s.devices.page.List,((e,a)=>((0,t.uX)(),(0,t.CE)("li",{key:a},[(0,t.Lk)("dl",null,[(0,t.Lk)("dt",T,[(0,t.Lk)("div",null,[(0,t.bF)(u,{item:e},null,8,["item"])]),A,(0,t.Lk)("div",null,[(0,t.bF)(r,{config:!1,item:e},null,8,["item"])])]),(0,t.Lk)("dd",I,[s.tuntap.list[e.MachineId]?((0,t.uX)(),(0,t.Wv)(c,{key:0,item:e},null,8,["item"])):(0,t.Q3)("",!0)])])])))),128))])]),(0,t.Lk)("div",P,[(0,t.Lk)("div",B,[(0,t.bF)(d,{size:"small",background:"",layout:"prev,pager, next","pager-count":5,total:s.devices.page.Count,"page-size":s.devices.page.Request.Size,"current-page":s.devices.page.Request.Page,onCurrentChange:s.handlePageChange,onSizeChange:s.handlePageSizeChange,"page-sizes":[10,20,50,100,255]},null,8,["total","page-size","current-page","onCurrentChange","onSizeChange"])])])])}var y=n(75234),X=n(54373),N=n(65304),U=n(31480),D=n(33200),Q=n(6564),W=n(73417),H=n(76978),K={components:{StarFilled:C.BQ2,UpdaterBtn:U.A,DeviceName:D.A,TuntapShow:Q.A},setup(e){(0,b.B)();const a=(0,m.Kh)({}),{devices:n,machineId:s,_getSignList:l,_getSignList1:i,handlePageChange:u,handlePageSizeChange:r,clearDevicesTimeout:c}=(0,X.r)(),{tuntap:d,_getTuntapInfo:o,handleTuntapRefresh:g,clearTuntapTimeout:p,handleTuntapEdit:v,sortTuntapIP:h}=(0,y.O)(),{_getUpdater:f,_subscribeUpdater:k,clearUpdaterTimeout:C}=(0,N.d)();(0,H.y)();(0,W.L2)();return(0,t.sV)((()=>{u(),g(),l(),i(),o(),f(),k()})),(0,t.hi)((()=>{c(),p(),C()})),{state:a,devices:n,machineId:s,handlePageChange:u,handlePageSizeChange:r,tuntap:d}}};const j=(0,w.A)(K,[["render",R],["__scopeId","data-v-3c358101"]]);var q=j,M=n(52417),V=n(81387),G={components:{Head:x,List:q,Status:M.A},setup(){document.addEventListener("contextmenu",(function(e){e.preventDefault()}));const e=(0,b.B)(),a=(0,V.rd)();return(0,t.sV)((()=>{0==e.value.hasAccess("NetManager")&&a.push({name:"NoPermission"})})),{}}};const O=(0,w.A)(G,[["render",c],["__scopeId","data-v-60d9820b"]]);var J=O}}]);
|
1
src/linker.app/public/web/js/733.6010de1f.js
Normal file
1
src/linker.app/public/web/js/733.6010de1f.js
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/js/847.dfeda1e8.js
Normal file
1
src/linker.app/public/web/js/847.dfeda1e8.js
Normal file
File diff suppressed because one or more lines are too long
1
src/linker.app/public/web/js/app.d3e1d5d0.js
Normal file
1
src/linker.app/public/web/js/app.d3e1d5d0.js
Normal file
File diff suppressed because one or more lines are too long
62
src/linker.app/public/web/js/chunk-vendors.e9b4f2f4.js
Normal file
62
src/linker.app/public/web/js/chunk-vendors.e9b4f2f4.js
Normal file
File diff suppressed because one or more lines are too long
@@ -1,11 +1,7 @@
|
||||
using linker.messenger.api;
|
||||
using linker.messenger.decenter;
|
||||
using linker.messenger.decenter;
|
||||
using linker.messenger.exroute;
|
||||
using linker.tunnel;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json;
|
||||
using linker.tunnel.connection;
|
||||
using linker.messenger.signin.args;
|
||||
using linker.messenger.sync;
|
||||
using linker.libs.web;
|
||||
@@ -15,9 +11,6 @@ namespace linker.messenger.tunnel
|
||||
{
|
||||
public static ServiceCollection AddTunnelClient(this ServiceCollection serviceCollection)
|
||||
{
|
||||
|
||||
//SerialzeExtends.AddJsonConverter(new ITunnelConnectionConverter());
|
||||
|
||||
serviceCollection.AddSingleton<TunnelTransfer>();
|
||||
serviceCollection.AddSingleton<TunnelClientExcludeIPTransfer>();
|
||||
serviceCollection.AddSingleton<ITunnelMessengerAdapter, TunnelMessengerAdapter>();
|
||||
@@ -75,8 +68,6 @@ namespace linker.messenger.tunnel
|
||||
|
||||
public static ServiceCollection AddTunnelServer(this ServiceCollection serviceCollection)
|
||||
{
|
||||
//SerialzeExtends.AddJsonConverter(new ITunnelConnectionConverter());
|
||||
|
||||
serviceCollection.AddSingleton<TunnelServerMessenger>();
|
||||
serviceCollection.AddSingleton<TunnelServerExternalResolver>();
|
||||
return serviceCollection;
|
||||
@@ -92,17 +83,4 @@ namespace linker.messenger.tunnel
|
||||
return serviceProvider;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ITunnelConnectionConverter : JsonConverter<ITunnelConnection>
|
||||
{
|
||||
public override ITunnelConnection Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, ITunnelConnection value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStringValue(string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -35,6 +35,7 @@ namespace linker.tunnel
|
||||
tunnelWanPortTransfer = new TunnelWanPortTransfer();
|
||||
transports = new List<ITunnelTransport> {
|
||||
new TransportUdp(tunnelMessengerAdapter),
|
||||
new TransportUdpP2PNAT(tunnelMessengerAdapter),
|
||||
new TransportTcpP2PNAT(tunnelMessengerAdapter),
|
||||
new TransportTcpNutssb(tunnelMessengerAdapter),
|
||||
transportUdpPortMap,
|
||||
@@ -327,7 +328,7 @@ namespace linker.tunnel
|
||||
/// <param name="tunnelTransportInfo"></param>
|
||||
public async Task OnBegin(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
|
||||
|
||||
if (operating.StartOperation(BuildKey(tunnelTransportInfo.Remote.MachineId, tunnelTransportInfo.TransactionId)) == false)
|
||||
{
|
||||
return;
|
||||
|
@@ -123,28 +123,31 @@ namespace linker.tunnel.transport
|
||||
&& tunnelTransportInfo.Local.LocalIps.Any(c => c.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
? new IPEndPoint(tunnelTransportInfo.Remote.LocalIps.FirstOrDefault(c => c.AddressFamily == AddressFamily.InterNetworkV6), tunnelTransportInfo.Remote.Remote.Port)
|
||||
: tunnelTransportInfo.Remote.Remote;
|
||||
Socket targetSocket = new(ep.AddressFamily, SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
|
||||
try
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
targetSocket.KeepAlive();
|
||||
targetSocket.IPv6Only(ep.AddressFamily, false);
|
||||
targetSocket.ReuseBind(new IPEndPoint(ep.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, tunnelTransportInfo.Local.Local.Port));
|
||||
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
Socket targetSocket = new(ep.AddressFamily, SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
|
||||
try
|
||||
{
|
||||
LoggerHelper.Instance.Warning($"{Name} connect to {tunnelTransportInfo.Remote.MachineId}->{tunnelTransportInfo.Remote.MachineName} {ep}");
|
||||
}
|
||||
await targetSocket.ConnectAsync(ep).WaitAsync(TimeSpan.FromMilliseconds(2000)).ConfigureAwait(false);
|
||||
targetSocket.KeepAlive();
|
||||
targetSocket.IPv6Only(ep.AddressFamily, false);
|
||||
targetSocket.ReuseBind(new IPEndPoint(ep.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, tunnelTransportInfo.Local.Local.Port));
|
||||
|
||||
if (mode == TunnelMode.Client)
|
||||
{
|
||||
return await TcpClient(tunnelTransportInfo, targetSocket).ConfigureAwait(false);
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Warning($"{Name} connect to {tunnelTransportInfo.Remote.MachineId}->{tunnelTransportInfo.Remote.MachineName} {ep}");
|
||||
}
|
||||
await targetSocket.ConnectAsync(ep).WaitAsync(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false);
|
||||
|
||||
if (mode == TunnelMode.Client)
|
||||
{
|
||||
return await TcpClient(tunnelTransportInfo, targetSocket).ConfigureAwait(false);
|
||||
}
|
||||
return await TcpServer(tunnelTransportInfo, targetSocket).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
targetSocket.SafeClose();
|
||||
}
|
||||
return await TcpServer(tunnelTransportInfo, targetSocket).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
targetSocket.SafeClose();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
168
src/linker.tunnel/transport/TransportUdpP2PNAT.cs
Normal file
168
src/linker.tunnel/transport/TransportUdpP2PNAT.cs
Normal file
@@ -0,0 +1,168 @@
|
||||
|
||||
using linker.tunnel.connection;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using linker.tunnel.wanport;
|
||||
|
||||
namespace linker.tunnel.transport
|
||||
{
|
||||
/// <summary>
|
||||
/// UDP同时连接打洞
|
||||
///
|
||||
/// 大致原理
|
||||
/// A 通知 B ,B立马连接A,A也同时去连接B
|
||||
/// </summary>
|
||||
public sealed class TransportUdpP2PNAT : ITunnelTransport
|
||||
{
|
||||
public string Name => "UdpP2PNAT";
|
||||
public string Label => "UDP、同时打开";
|
||||
public TunnelProtocolType ProtocolType => TunnelProtocolType.Udp;
|
||||
public TunnelWanPortProtocolType AllowWanPortProtocolType => TunnelWanPortProtocolType.Udp;
|
||||
public bool Reverse => true;
|
||||
|
||||
public bool DisableReverse => false;
|
||||
|
||||
public bool SSL => true;
|
||||
|
||||
public bool DisableSSL => false;
|
||||
|
||||
public byte Order => 3;
|
||||
|
||||
/// <summary>
|
||||
/// 连接成功
|
||||
/// </summary>
|
||||
public Action<ITunnelConnection> OnConnected { get; set; } = (state) => { };
|
||||
|
||||
|
||||
private readonly byte[] authBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.udp.ttl1");
|
||||
private readonly byte[] endBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.udp.end1");
|
||||
|
||||
private readonly ITunnelMessengerAdapter tunnelMessengerAdapter;
|
||||
public TransportUdpP2PNAT(ITunnelMessengerAdapter tunnelMessengerAdapter)
|
||||
{
|
||||
this.tunnelMessengerAdapter = tunnelMessengerAdapter;
|
||||
}
|
||||
public void SetSSL(X509Certificate certificate)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接对方
|
||||
/// </summary>
|
||||
/// <param name="tunnelTransportInfo"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ITunnelConnection> ConnectAsync(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
if (await tunnelMessengerAdapter.SendConnectBegin(tunnelTransportInfo).ConfigureAwait(false) == false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (tunnelTransportInfo.Direction == TunnelDirection.Reverse)
|
||||
{
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
}
|
||||
ITunnelConnection connection = await ConnectForward(tunnelTransportInfo, TunnelMode.Client).ConfigureAwait(false);
|
||||
if (connection != null)
|
||||
{
|
||||
await tunnelMessengerAdapter.SendConnectSuccess(tunnelTransportInfo).ConfigureAwait(false);
|
||||
return connection;
|
||||
}
|
||||
|
||||
await tunnelMessengerAdapter.SendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 收到对方开始连接的消息
|
||||
/// </summary>
|
||||
/// <param name="tunnelTransportInfo"></param>
|
||||
public async Task OnBegin(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
ITunnelConnection connection = await ConnectForward(tunnelTransportInfo, TunnelMode.Server).ConfigureAwait(false);
|
||||
if (connection != null)
|
||||
{
|
||||
OnConnected(connection);
|
||||
await tunnelMessengerAdapter.SendConnectSuccess(tunnelTransportInfo).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await tunnelMessengerAdapter.SendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnFail(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
}
|
||||
public void OnSuccess(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private async Task<ITunnelConnection> ConnectForward(TunnelTransportInfo tunnelTransportInfo, TunnelMode mode)
|
||||
{
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Warning($"{Name} connect to {tunnelTransportInfo.Remote.MachineId}->{tunnelTransportInfo.Remote.MachineName} {string.Join("\r\n", tunnelTransportInfo.RemoteEndPoints.Select(c => c.ToString()))}");
|
||||
}
|
||||
|
||||
IPEndPoint ep = tunnelTransportInfo.Remote.LocalIps.Any(c => c.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
&& tunnelTransportInfo.Local.LocalIps.Any(c => c.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
? new IPEndPoint(tunnelTransportInfo.Remote.LocalIps.FirstOrDefault(c => c.AddressFamily == AddressFamily.InterNetworkV6), tunnelTransportInfo.Remote.Remote.Port)
|
||||
: tunnelTransportInfo.Remote.Remote;
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
IPEndPoint tempEP = new IPEndPoint(ep.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, 0);
|
||||
Socket targetSocket = new(ep.AddressFamily, SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
|
||||
targetSocket.IPv6Only(ep.AddressFamily, false);
|
||||
targetSocket.WindowsUdpBug();
|
||||
targetSocket.ReuseBind(new IPEndPoint(ep.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, tunnelTransportInfo.Local.Local.Port));
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Warning($"{Name} connect to {tunnelTransportInfo.Remote.MachineId}->{tunnelTransportInfo.Remote.MachineName} {ep}");
|
||||
}
|
||||
|
||||
targetSocket.SendTo(authBytes, ep);
|
||||
recv:;
|
||||
var result = await targetSocket.ReceiveFromAsync(buffer, tempEP).WaitAsync(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false);
|
||||
if ((result.RemoteEndPoint as IPEndPoint).Equals(ep) == false)
|
||||
{
|
||||
goto recv;
|
||||
}
|
||||
|
||||
ISymmetricCrypto crypto = mode == TunnelMode.Client ? CryptoFactory.CreateSymmetric(tunnelTransportInfo.Remote.MachineId) : CryptoFactory.CreateSymmetric(tunnelTransportInfo.Local.MachineId);
|
||||
return new TunnelConnectionUdp
|
||||
{
|
||||
UdpClient = targetSocket,
|
||||
RemoteMachineId = tunnelTransportInfo.Remote.MachineId,
|
||||
RemoteMachineName = tunnelTransportInfo.Remote.MachineName,
|
||||
Direction = tunnelTransportInfo.Direction,
|
||||
ProtocolType = TunnelProtocolType.Udp,
|
||||
Type = TunnelType.P2P,
|
||||
Mode = mode,
|
||||
TransactionId = tunnelTransportInfo.TransactionId,
|
||||
TransactionTag = tunnelTransportInfo.TransactionTag,
|
||||
TransportName = tunnelTransportInfo.TransportName,
|
||||
IPEndPoint = NetworkHelper.TransEndpointFamily(ep),
|
||||
Label = string.Empty,
|
||||
Receive = true,
|
||||
SSL = tunnelTransportInfo.SSL,
|
||||
Crypto = crypto
|
||||
};
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
targetSocket.SafeClose();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -24,7 +24,7 @@
|
||||
2. 服务器转发多节点
|
||||
3. 虚拟网卡下伪造ACK为TCP-in-TCP隧道提速
|
||||
4. 一些代码优化、修复一些错误
|
||||
5. 优化打洞
|
||||
5. 新增一个UDP同时打开的打洞协议,优化了一下TCP同时打开的打洞协议
|
||||
6. 其它一些小改变</Description>
|
||||
<Copyright>snltty</Copyright>
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
|
@@ -1,8 +1,8 @@
|
||||
v1.9.1
|
||||
2025-08-30 21:22:23
|
||||
2025-08-31 01:38:15
|
||||
1. 一些累计更新
|
||||
2. 服务器转发多节点
|
||||
3. 虚拟网卡下伪造ACK为TCP-in-TCP隧道提速
|
||||
4. 一些代码优化、修复一些错误
|
||||
5. 优化打洞
|
||||
5. 新增一个UDP同时打开的打洞协议,优化了一下TCP同时打开的打洞协议
|
||||
6. 其它一些小改变
|
Reference in New Issue
Block a user