diff options
| -rw-r--r-- | web/assets/js/model/outbound.js | 37 | ||||
| -rw-r--r-- | web/html/xui/form/outbound.html | 26 |
2 files changed, 62 insertions, 1 deletions
diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js index af4e512c..f62b06b9 100644 --- a/web/assets/js/model/outbound.js +++ b/web/assets/js/model/outbound.js @@ -356,6 +356,34 @@ class RealityStreamSettings extends CommonClass { }; } }; +class SockoptStreamSettings extends CommonClass { + constructor(dialerProxy = "", tcpFastOpen = false, tcpKeepAliveInterval = 0, tcpNoDelay = false) { + super(); + this.dialerProxy = dialerProxy; + this.tcpFastOpen = tcpFastOpen; + this.tcpKeepAliveInterval = tcpKeepAliveInterval; + this.tcpNoDelay = tcpNoDelay; + } + + static fromJson(json = {}) { + if (Object.keys(json).length === 0) return undefined; + return new SockoptStreamSettings( + json.dialerProxy, + json.tcpFastOpen, + json.tcpKeepAliveInterval, + json.tcpNoDelay, + ); + } + + toJson() { + return { + dialerProxy: this.dialerProxy, + tcpFastOpen: this.tcpFastOpen, + tcpKeepAliveInterval: this.tcpKeepAliveInterval, + tcpNoDelay: this.tcpNoDelay, + }; + } +} class StreamSettings extends CommonClass { constructor(network='tcp', @@ -392,6 +420,14 @@ class StreamSettings extends CommonClass { return this.security === "reality"; } + get sockoptSwitch() { + return this.sockopt != undefined; + } + + set sockoptSwitch(value) { + this.sockopt = value ? new SockoptStreamSettings() : undefined; + } + static fromJson(json={}) { return new StreamSettings( json.network, @@ -422,6 +458,7 @@ class StreamSettings extends CommonClass { quicSettings: network === 'quic' ? this.quic.toJson() : undefined, grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined, httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined, + sockopt: this.sockopt != undefined ? this.sockopt.toJson() : undefined, }; } } diff --git a/web/html/xui/form/outbound.html b/web/html/xui/form/outbound.html index b6874240..2f2a5215 100644 --- a/web/html/xui/form/outbound.html +++ b/web/html/xui/form/outbound.html @@ -351,7 +351,7 @@ <a-radio-group v-model="outbound.stream.security" button-style="solid"> <a-radio-button value="none">{{ i18n "none" }}</a-radio-button> <a-radio-button value="tls">TLS</a-radio-button> - <a-radio-button v-if="outbound.canEnableReality()" value="reality">REALITY</a-radio-button> + <a-radio-button v-if="outbound.canEnableReality()" value="reality">Reality</a-radio-button> </a-radio-group> </a-form-item> <template v-if="outbound.stream.isTls"> @@ -399,6 +399,30 @@ </a-form-item> </template> </template> + +<!-- sockopt settings --> +<template v-if="outbound.canEnableStream()"> + <a-form-item label="Sockopts"> + <a-switch v-model="outbound.stream.sockoptSwitch"></a-switch> + </a-form-item> + <template v-if="outbound.stream.sockoptSwitch"> + <a-form-item label="Dialer Proxy"> + <a-select v-model="outbound.stream.sockopt.dialerProxy" :dropdown-class-name="themeSwitcher.currentTheme"> + <a-select-option v-for="tag in ['', ...outModal.tags]" :value="tag">[[ tag ]]</a-select-option> + </a-select> + </a-form-item> + <a-form-item label="TCP Fast Open"> + <a-switch v-model="outbound.stream.sockopt.tcpFastOpen"></a-switch> + </a-form-item> + <a-form-item label="Keep Alive Interval"> + <a-input-number v-model="outbound.stream.sockopt.tcpKeepAliveInterval" :min="0"></a-input-number> + </a-form-item> + <a-form-item label="TCP No-Delay"> + <a-switch v-model="outbound.stream.sockopt.tcpNoDelay"></a-switch> + </a-form-item> + </template> +</template> + </a-form> </a-tab-pane> <a-tab-pane key="2" tab="JSON" force-render="true"> |
