1- import { Card , SectionLabel , Select } from "../../../components" ;
2- import type { CoreEngine , TunEngine } from "../../../generated/bindings" ;
1+ import { Card , Field , SectionLabel , Select } from "../../../components" ;
2+ import type { CoreEngine , TunEngine , TunUdpMode } from "../../../generated/bindings" ;
33import { useT } from "../../../i18n" ;
44import type { AdvancedSettings } from "../../../lib/bridge" ;
55
66// Cores the user can pick a TUN engine for, and the engines each may use.
77// `singbox-tun` (sing-box's own native TUN) is sing-box-only; xray has no native
8- // tun, so it uses an external engine. Further engines plug in here later .
8+ // tun, so it uses an external engine (tun2socks/hev) . Further engines plug in here.
99const CORES : CoreEngine [ ] = [ "sing-box" , "xray" ] ;
1010const ENGINE_LABEL : Record < TunEngine , string > = {
1111 "singbox-tun" : "sing-box TUN" ,
1212 tun2socks : "tun2socks" ,
13+ hev : "hev" ,
1314} ;
1415const ENGINES_FOR : Record < CoreEngine , TunEngine [ ] > = {
15- "sing-box" : [ "singbox-tun" , "tun2socks" ] ,
16- xray : [ "tun2socks" ] ,
16+ "sing-box" : [ "singbox-tun" , "tun2socks" , "hev" ] ,
17+ xray : [ "tun2socks" , "hev" ] ,
1718} ;
1819
1920function defaultTunFor ( core : CoreEngine ) : TunEngine {
@@ -35,6 +36,10 @@ export function TunEngineSection({
3536 const setTunFor = ( core : CoreEngine , value : TunEngine ) =>
3637 set ( "tunByCore" , { ...( settings . tunByCore ?? { } ) , [ core ] : value } ) ;
3738
39+ // hev is the only engine that reads the tuning knobs below, so only surface them
40+ // when at least one core uses it.
41+ const usesHev = CORES . some ( ( core ) => tunFor ( core ) === "hev" ) ;
42+
3843 return (
3944 < >
4045 < SectionLabel > { t ( "settings.tunEngine" ) } </ SectionLabel >
@@ -63,6 +68,70 @@ export function TunEngineSection({
6368 />
6469 </ div >
6570 ) ) }
71+
72+ { usesHev && (
73+ < div
74+ style = { { marginTop : 12 , borderTop : "1px solid var(--outline-faint)" , paddingTop : 12 } }
75+ >
76+ < div style = { { fontSize : 11.5 , color : "var(--on-surface-faint)" , marginBottom : 10 } } >
77+ { t ( "settings.tunHevTuning" ) }
78+ </ div >
79+ < div
80+ style = { {
81+ display : "flex" ,
82+ alignItems : "center" ,
83+ justifyContent : "space-between" ,
84+ gap : 12 ,
85+ padding : "5px 0" ,
86+ } }
87+ >
88+ < span style = { { fontSize : 13.5 , color : "var(--on-surface)" } } >
89+ { t ( "settings.tunUdpMode" ) }
90+ </ span >
91+ < Select
92+ style = { { width : 150 , flex : "0 0 auto" } }
93+ value = { settings . tunUdpMode }
94+ onChange = { ( v ) => set ( "tunUdpMode" , v as TunUdpMode ) }
95+ options = { [
96+ { value : "udp" , label : "UDP" } ,
97+ { value : "tcp" , label : "TCP" } ,
98+ ] }
99+ />
100+ </ div >
101+ < div style = { { padding : "8px 4px 0" } } >
102+ < Field
103+ label = { t ( "settings.tunConnectTimeout" ) }
104+ value = { settings . tunConnectTimeoutMs }
105+ type = "number"
106+ onChange = { ( value ) => set ( "tunConnectTimeoutMs" , Number ( value ) ) }
107+ />
108+ < Field
109+ label = { t ( "settings.tunTcpRwTimeout" ) }
110+ value = { settings . tunTcpRwTimeoutMs }
111+ type = "number"
112+ onChange = { ( value ) => set ( "tunTcpRwTimeoutMs" , Number ( value ) ) }
113+ />
114+ < Field
115+ label = { t ( "settings.tunUdpRwTimeout" ) }
116+ value = { settings . tunUdpRwTimeoutMs }
117+ type = "number"
118+ onChange = { ( value ) => set ( "tunUdpRwTimeoutMs" , Number ( value ) ) }
119+ />
120+ < Field
121+ label = { t ( "settings.tunTcpBuffer" ) }
122+ value = { settings . tunTcpBufferSize }
123+ type = "number"
124+ onChange = { ( value ) => set ( "tunTcpBufferSize" , Number ( value ) ) }
125+ />
126+ < Field
127+ label = { t ( "settings.tunUdpRecvBuffer" ) }
128+ value = { settings . tunUdpRecvBufferSize }
129+ type = "number"
130+ onChange = { ( value ) => set ( "tunUdpRecvBufferSize" , Number ( value ) ) }
131+ />
132+ </ div >
133+ </ div >
134+ ) }
66135 </ Card >
67136 </ >
68137 ) ;
0 commit comments