Browse Source

Update QUIC params defaults and UI validations

#4142
Adjust QUIC parameter defaults and tighten form validation across inbound/outbound components.

- Set default brutalUp/brutalDown to 65537 and only include them in JSON when congestion is 'brutal' or 'force-brutal'.
- Change keepAlivePeriod defaults (inbound QUIC -> 5s, Hysteria stream -> 2s) and enforce minimums in the UI.
- Expose and serialize additional QUIC fields in outbound QuicParams: init/max stream windows, init/max connection windows, maxIdleTimeout, disablePathMTUDiscovery, maxIncomingStreams.
- Add UI min/placeholder constraints: stream/connection receive windows min=16384 and updated placeholders to show defaults, brutal fields min=65537, maxIncomingStreams min=8 (placeholders updated), keepAlive min adjusted.
- Add Wireguard and Hysteria entries to Protocols.

Touched files: web/assets/js/model/inbound.js, web/assets/js/model/outbound.js, web/html/form/outbound.html, web/html/form/stream/stream_finalmask.html.
MHSanaei 1 day ago
parent
commit
d44b70682c

+ 7 - 5
web/assets/js/model/inbound.js

@@ -1207,15 +1207,15 @@ class QuicParams extends XrayCommonClass {
     constructor(
         congestion = 'bbr',
         debug = false,
-        brutalUp = '',
-        brutalDown = '',
+        brutalUp = 65537,
+        brutalDown = 65537,
         udpHop = undefined,
         initStreamReceiveWindow = 8388608,
         maxStreamReceiveWindow = 8388608,
         initConnectionReceiveWindow = 20971520,
         maxConnectionReceiveWindow = 20971520,
         maxIdleTimeout = 30,
-        keepAlivePeriod = 0,
+        keepAlivePeriod = 5,
         disablePathMTUDiscovery = false,
         maxIncomingStreams = 1024,
     ) {
@@ -1265,8 +1265,10 @@ class QuicParams extends XrayCommonClass {
     toJson() {
         const result = { congestion: this.congestion };
         if (this.debug) result.debug = this.debug;
-        if (this.brutalUp) result.brutalUp = this.brutalUp;
-        if (this.brutalDown) result.brutalDown = this.brutalDown;
+        if (['brutal', 'force-brutal'].includes(this.congestion)) {
+            if (this.brutalUp) result.brutalUp = this.brutalUp;
+            if (this.brutalDown) result.brutalDown = this.brutalDown;
+        }
         if (this.udpHop) result.udpHop = { ports: this.udpHop.ports, interval: this.udpHop.interval };
         if (this.initStreamReceiveWindow > 0) result.initStreamReceiveWindow = this.initStreamReceiveWindow;
         if (this.maxStreamReceiveWindow > 0) result.maxStreamReceiveWindow = this.maxStreamReceiveWindow;

+ 41 - 7
web/assets/js/model/outbound.js

@@ -6,10 +6,10 @@ const Protocols = {
     VLESS: "vless",
     Trojan: "trojan",
     Shadowsocks: "shadowsocks",
+    Wireguard: "wireguard",
+    Hysteria: "hysteria",
     Socks: "socks",
     HTTP: "http",
-    Wireguard: "wireguard",
-    Hysteria: "hysteria"
 };
 
 const SSMethods = {
@@ -500,7 +500,7 @@ class HysteriaStreamSettings extends CommonClass {
         initConnectionReceiveWindow = 20971520,
         maxConnectionReceiveWindow = 20971520,
         maxIdleTimeout = 30,
-        keepAlivePeriod = 0,
+        keepAlivePeriod = 2,
         disablePathMTUDiscovery = false
     ) {
         super();
@@ -789,9 +789,17 @@ class QuicParams extends CommonClass {
     constructor(
         congestion = 'bbr',
         debug = false,
-        brutalUp = '',
-        brutalDown = '',
+        brutalUp = 65537,
+        brutalDown = 65537,
         udpHop = undefined,
+        initStreamReceiveWindow = 8388608,
+        maxStreamReceiveWindow = 8388608,
+        initConnectionReceiveWindow = 20971520,
+        maxConnectionReceiveWindow = 20971520,
+        maxIdleTimeout = 30,
+        keepAlivePeriod = 5,
+        disablePathMTUDiscovery = false,
+        maxIncomingStreams = 1024,
     ) {
         super();
         this.congestion = congestion;
@@ -799,6 +807,14 @@ class QuicParams extends CommonClass {
         this.brutalUp = brutalUp;
         this.brutalDown = brutalDown;
         this.udpHop = udpHop;
+        this.initStreamReceiveWindow = initStreamReceiveWindow;
+        this.maxStreamReceiveWindow = maxStreamReceiveWindow;
+        this.initConnectionReceiveWindow = initConnectionReceiveWindow;
+        this.maxConnectionReceiveWindow = maxConnectionReceiveWindow;
+        this.maxIdleTimeout = maxIdleTimeout;
+        this.keepAlivePeriod = keepAlivePeriod;
+        this.disablePathMTUDiscovery = disablePathMTUDiscovery;
+        this.maxIncomingStreams = maxIncomingStreams;
     }
 
     get hasUdpHop() {
@@ -817,15 +833,33 @@ class QuicParams extends CommonClass {
             json.brutalUp,
             json.brutalDown,
             json.udpHop ? { ports: json.udpHop.ports, interval: json.udpHop.interval } : undefined,
+            json.initStreamReceiveWindow,
+            json.maxStreamReceiveWindow,
+            json.initConnectionReceiveWindow,
+            json.maxConnectionReceiveWindow,
+            json.maxIdleTimeout,
+            json.keepAlivePeriod,
+            json.disablePathMTUDiscovery,
+            json.maxIncomingStreams,
         );
     }
 
     toJson() {
         const result = { congestion: this.congestion };
         if (this.debug) result.debug = this.debug;
-        if (this.brutalUp) result.brutalUp = this.brutalUp;
-        if (this.brutalDown) result.brutalDown = this.brutalDown;
+        if (['brutal', 'force-brutal'].includes(this.congestion)) {
+            if (this.brutalUp) result.brutalUp = this.brutalUp;
+            if (this.brutalDown) result.brutalDown = this.brutalDown;
+        }
         if (this.udpHop) result.udpHop = { ports: this.udpHop.ports, interval: this.udpHop.interval };
+        if (this.initStreamReceiveWindow > 0) result.initStreamReceiveWindow = this.initStreamReceiveWindow;
+        if (this.maxStreamReceiveWindow > 0) result.maxStreamReceiveWindow = this.maxStreamReceiveWindow;
+        if (this.initConnectionReceiveWindow > 0) result.initConnectionReceiveWindow = this.initConnectionReceiveWindow;
+        if (this.maxConnectionReceiveWindow > 0) result.maxConnectionReceiveWindow = this.maxConnectionReceiveWindow;
+        if (this.maxIdleTimeout !== 30 && this.maxIdleTimeout > 0) result.maxIdleTimeout = this.maxIdleTimeout;
+        if (this.keepAlivePeriod > 0) result.keepAlivePeriod = this.keepAlivePeriod;
+        if (this.disablePathMTUDiscovery) result.disablePathMTUDiscovery = this.disablePathMTUDiscovery;
+        if (this.maxIncomingStreams > 0) result.maxIncomingStreams = this.maxIncomingStreams;
         return result;
     }
 }

+ 17 - 17
web/html/form/outbound.html

@@ -579,23 +579,23 @@
             <a-input-number v-model.number="outbound.stream.hysteria.udphopIntervalMax" :min="5"></a-input-number>
           </a-form-item>
           <a-form-item label="Init Stream Receive">
-            <a-input-number v-model.number="outbound.stream.hysteria.initStreamReceiveWindow"></a-input-number>
+            <a-input-number v-model.number="outbound.stream.hysteria.initStreamReceiveWindow" :min="16384"></a-input-number>
           </a-form-item>
           <a-form-item label="Max Stream Receive">
-            <a-input-number v-model.number="outbound.stream.hysteria.maxStreamReceiveWindow"></a-input-number>
+            <a-input-number v-model.number="outbound.stream.hysteria.maxStreamReceiveWindow" :min="16384"></a-input-number>
           </a-form-item>
           <a-form-item label="Init Connection Receive">
-            <a-input-number v-model.number="outbound.stream.hysteria.initConnectionReceiveWindow"></a-input-number>
+            <a-input-number v-model.number="outbound.stream.hysteria.initConnectionReceiveWindow" :min="16384"></a-input-number>
           </a-form-item>
           <a-form-item label="Max Connection Receive">
-            <a-input-number v-model.number="outbound.stream.hysteria.maxConnectionReceiveWindow"></a-input-number>
+            <a-input-number v-model.number="outbound.stream.hysteria.maxConnectionReceiveWindow" :min="16384"></a-input-number>
           </a-form-item>
           <a-form-item label="Max Idle Timeout (s)">
             <a-input-number v-model.number="outbound.stream.hysteria.maxIdleTimeout" :min="4"
               :max="120"></a-input-number>
           </a-form-item>
           <a-form-item label="Keep Alive Period (s)">
-            <a-input-number v-model.number="outbound.stream.hysteria.keepAlivePeriod" :min="0"
+            <a-input-number v-model.number="outbound.stream.hysteria.keepAlivePeriod" :min="2"
               :max="60"></a-input-number>
           </a-form-item>
           <a-form-item label="Disable Path MTU Dis">
@@ -934,10 +934,10 @@
             </a-form-item>
             <template v-if="['brutal','force-brutal'].includes(outbound.stream.finalmask.quicParams.congestion)">
               <a-form-item label="Brutal Up">
-                <a-input v-model.trim="outbound.stream.finalmask.quicParams.brutalUp" placeholder="e.g. 60 mbps" />
+                <a-input v-model.trim="outbound.stream.finalmask.quicParams.brutalUp" :min="65537"placeholder="65537" />
               </a-form-item>
               <a-form-item label="Brutal Down">
-                <a-input v-model.trim="outbound.stream.finalmask.quicParams.brutalDown" placeholder="e.g. 60 mbps" />
+                <a-input v-model.trim="outbound.stream.finalmask.quicParams.brutalDown" :min="65537" placeholder="65537" />
               </a-form-item>
             </template>
             <a-form-item label="UDP Hop">
@@ -964,24 +964,24 @@
               <a-switch v-model="outbound.stream.finalmask.quicParams.disablePathMTUDiscovery"></a-switch>
             </a-form-item>
             <a-form-item label="Max Incoming Streams">
-              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxIncomingStreams" :min="0"
-                placeholder="0 = default" />
+              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxIncomingStreams" :min="8"
+                placeholder="8 = default" />
             </a-form-item>
             <a-form-item label="Init Stream Window">
-              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.initStreamReceiveWindow" :min="0"
-                placeholder="0 = default" />
+              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.initStreamReceiveWindow" :min="16384"
+                placeholder="8388608 = default" />
             </a-form-item>
             <a-form-item label="Max Stream Window">
-              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxStreamReceiveWindow" :min="0"
-                placeholder="0 = default" />
+              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxStreamReceiveWindow" :min="16384"
+                placeholder="8388608 = default" />
             </a-form-item>
             <a-form-item label="Init Conn Window">
-              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.initConnectionReceiveWindow" :min="0"
-                placeholder="0 = default" />
+              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.initConnectionReceiveWindow" :min="16384"
+                placeholder="20971520 = default" />
             </a-form-item>
             <a-form-item label="Max Conn Window">
-              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxConnectionReceiveWindow" :min="0"
-                placeholder="0 = default" />
+              <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxConnectionReceiveWindow" :min="16384"
+                placeholder="20971520 = default" />
             </a-form-item>
           </template>
         </template>

+ 13 - 13
web/html/form/stream/stream_finalmask.html

@@ -356,10 +356,10 @@
       </a-form-item>
       <template v-if="['brutal','force-brutal'].includes(inbound.stream.finalmask.quicParams.congestion)">
         <a-form-item label="Brutal Up">
-          <a-input v-model.trim="inbound.stream.finalmask.quicParams.brutalUp" placeholder="e.g. 60 mbps" />
+          <a-input v-model.trim="inbound.stream.finalmask.quicParams.brutalUp" :min="65537" placeholder="65537" />
         </a-form-item>
         <a-form-item label="Brutal Down">
-          <a-input v-model.trim="inbound.stream.finalmask.quicParams.brutalDown" placeholder="e.g. 60 mbps" />
+          <a-input v-model.trim="inbound.stream.finalmask.quicParams.brutalDown" :min="65537" placeholder="65537" />
         </a-form-item>
       </template>
       <a-form-item label="UDP Hop">
@@ -377,30 +377,30 @@
         <a-input-number v-model.number="inbound.stream.finalmask.quicParams.maxIdleTimeout" :min="4" :max="120" />
       </a-form-item>
       <a-form-item label="Keep Alive Period (s)">
-        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.keepAlivePeriod" :min="0" :max="60" />
+        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.keepAlivePeriod" :min="2" :max="60" />
       </a-form-item>
       <a-form-item label="Disable Path MTU Dis">
         <a-switch v-model="inbound.stream.finalmask.quicParams.disablePathMTUDiscovery"></a-switch>
       </a-form-item>
       <a-form-item label="Max Incoming Streams">
-        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.maxIncomingStreams" :min="0"
-          placeholder="0 = default" />
+        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.maxIncomingStreams" :min="8"
+          placeholder="1024 = default" />
       </a-form-item>
       <a-form-item label="Init Stream Window">
-        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.initStreamReceiveWindow" :min="0"
-          placeholder="0 = default" />
+        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.initStreamReceiveWindow" :min="16384"
+          placeholder="8388608 = default" />
       </a-form-item>
       <a-form-item label="Max Stream Window">
-        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.maxStreamReceiveWindow" :min="0"
-          placeholder="0 = default" />
+        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.maxStreamReceiveWindow" :min="16384"
+          placeholder="8388608 = default" />
       </a-form-item>
       <a-form-item label="Init Conn Window">
-        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.initConnectionReceiveWindow" :min="0"
-          placeholder="0 = default" />
+        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.initConnectionReceiveWindow" :min="16384"
+          placeholder="20971520 = default" />
       </a-form-item>
       <a-form-item label="Max Conn Window">
-        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.maxConnectionReceiveWindow" :min="0"
-          placeholder="0 = default" />
+        <a-input-number v-model.number="inbound.stream.finalmask.quicParams.maxConnectionReceiveWindow" :min="16384"
+          placeholder="20971520 = default" />
       </a-form-item>
     </template>
   </template>