feat(simnet): add SimNet protocol to admin server form

- form-schema: constants/defaults/schemas/types + full ~48 simnet field set
- server-form: SimNet field group rendering
- node-form: allow simnet protocol type
- i18n: en-US / zh-CN simnet labels
This commit is contained in:
2026-07-27 00:18:47 -07:00
parent e64f808633
commit 6b9ae70491
9 changed files with 738 additions and 4 deletions
@@ -49,8 +49,8 @@
"encryption_rtt": "RTT", "encryption_rtt": "RTT",
"encryption_server_padding": "Server Padding", "encryption_server_padding": "Server Padding",
"encryption_ticket": "Ticket Time", "encryption_ticket": "Ticket Time",
"expired": "Expired",
"expireTime": "Expire Time", "expireTime": "Expire Time",
"expired": "Expired",
"extra": "Extra", "extra": "Extra",
"flow": "Flow", "flow": "Flow",
"generate_quantum_resistant_key": "Generate Quantum-Resistant Key", "generate_quantum_resistant_key": "Generate Quantum-Resistant Key",
@@ -141,6 +141,52 @@
}, },
"server_key": "Server Key", "server_key": "Server Key",
"service_name": "Service Name", "service_name": "Service Name",
"simnet": "SimNet",
"simnet_af_enabled": "Enable Anti-Fingerprint",
"simnet_af_fake_header_injection": "Fake Header Injection",
"simnet_af_handshake_polymorphism": "Handshake Polymorphism",
"simnet_af_magic_mode": "Anti-Fingerprint Magic Mode",
"simnet_af_path_mode": "Anti-Fingerprint Path Mode",
"simnet_af_path_prefix": "Anti-Fingerprint Path Prefix",
"simnet_af_path_prefix_placeholder": "Optional path prefix",
"simnet_af_path_suffix": "Anti-Fingerprint Path Suffix",
"simnet_af_path_suffix_placeholder": "Optional path suffix",
"simnet_af_response_jitter_ms": "Anti-Fingerprint Response Jitter",
"simnet_af_settings_jitter": "Settings Frame Jitter",
"simnet_client_max_concurrent_streams": "Client Concurrent Streams",
"simnet_client_max_streams_per_session": "Client Streams / Session",
"simnet_client_max_udp_sessions": "Client UDP Sessions",
"simnet_client_session_idle_timeout_secs": "Client Session Idle Timeout",
"simnet_egress_block_link_local": "Block Link-Local Egress",
"simnet_egress_block_loopback": "Block Loopback Egress",
"simnet_egress_block_metadata": "Block Metadata Egress",
"simnet_egress_block_private": "Block Private Egress",
"simnet_fallback_enabled": "Enable HTTPS Fallback Reverse Proxy",
"simnet_fallback_host_header": "Fallback Host Header",
"simnet_fallback_host_header_placeholder": "Optional, defaults to target host",
"simnet_fallback_target_host": "Fallback Target Host",
"simnet_fallback_target_host_placeholder": "e.g. www.example.com",
"simnet_fallback_target_port": "Fallback Target Port",
"simnet_fallback_target_scheme": "Fallback Target Scheme",
"simnet_fallback_tls_sni": "Fallback TLS SNI",
"simnet_fallback_tls_sni_placeholder": "Optional, defaults to target host",
"simnet_inbound_max_handler_tasks_per_session": "Handler Tasks / Session",
"simnet_inbound_max_streams_per_session": "Inbound Streams / Session",
"simnet_inbound_max_udp_streams_per_session": "Inbound UDP Streams / Session",
"simnet_initial_window_size": "H2 Initial Window",
"simnet_max_concurrent_streams": "H2 Concurrent Streams",
"simnet_max_frame_size": "H2 Max Frame Size",
"simnet_recv_window": "Receive Window",
"simnet_reverse_enabled": "Enable Local Reverse Proxy",
"simnet_reverse_listen_addr": "Reverse Listen Address",
"simnet_reverse_listen_port": "Reverse Listen Port",
"simnet_reverse_target_host": "Reverse Target Host",
"simnet_reverse_target_port": "Reverse Target Port",
"simnet_send_window": "Send Window",
"simnet_stream_data_channel_capacity": "Stream Data Channel",
"simnet_stream_event_channel_capacity": "Stream Event Channel",
"simnet_target_dial_timeout_ms": "Target Dial Timeout",
"simnet_target_max_concurrent_dials": "Concurrent Target Dials",
"sorted_success": "Sorted successfully", "sorted_success": "Sorted successfully",
"status": "Status", "status": "Status",
"subscribeId": "Subscribe ID", "subscribeId": "Subscribe ID",
@@ -49,8 +49,8 @@
"encryption_rtt": "RTT", "encryption_rtt": "RTT",
"encryption_server_padding": "服务器填充", "encryption_server_padding": "服务器填充",
"encryption_ticket": "票据时间", "encryption_ticket": "票据时间",
"expired": "已过期",
"expireTime": "过期时间", "expireTime": "过期时间",
"expired": "已过期",
"extra": "额外", "extra": "额外",
"flow": "流控", "flow": "流控",
"generate_quantum_resistant_key": "生成量子抗性密钥", "generate_quantum_resistant_key": "生成量子抗性密钥",
@@ -141,6 +141,52 @@
}, },
"server_key": "服务器密钥", "server_key": "服务器密钥",
"service_name": "服务名称", "service_name": "服务名称",
"simnet": "SimNet",
"simnet_af_enabled": "启用反指纹",
"simnet_af_fake_header_injection": "注入伪装 Header",
"simnet_af_handshake_polymorphism": "握手多态",
"simnet_af_magic_mode": "反指纹 Magic 模式",
"simnet_af_path_mode": "反指纹路径模式",
"simnet_af_path_prefix": "反指纹路径前缀",
"simnet_af_path_prefix_placeholder": "可选路径前缀",
"simnet_af_path_suffix": "反指纹路径后缀",
"simnet_af_path_suffix_placeholder": "可选路径后缀",
"simnet_af_response_jitter_ms": "反指纹响应抖动",
"simnet_af_settings_jitter": "Settings 帧抖动",
"simnet_client_max_concurrent_streams": "客户端并发流上限",
"simnet_client_max_streams_per_session": "客户端每会话流上限",
"simnet_client_max_udp_sessions": "客户端 UDP 会话上限",
"simnet_client_session_idle_timeout_secs": "客户端会话空闲超时",
"simnet_egress_block_link_local": "阻止出口访问链路本地地址",
"simnet_egress_block_loopback": "阻止出口访问 Loopback",
"simnet_egress_block_metadata": "阻止出口访问元数据地址",
"simnet_egress_block_private": "阻止出口访问私网",
"simnet_fallback_enabled": "启用 HTTPS Fallback 反向代理",
"simnet_fallback_host_header": "Fallback Host Header",
"simnet_fallback_host_header_placeholder": "可选,默认使用目标主机",
"simnet_fallback_target_host": "Fallback 目标主机",
"simnet_fallback_target_host_placeholder": "例如 www.example.com",
"simnet_fallback_target_port": "Fallback 目标端口",
"simnet_fallback_target_scheme": "Fallback 目标协议",
"simnet_fallback_tls_sni": "Fallback TLS SNI",
"simnet_fallback_tls_sni_placeholder": "可选,默认使用目标主机",
"simnet_inbound_max_handler_tasks_per_session": "每会话处理任务上限",
"simnet_inbound_max_streams_per_session": "每会话入站流上限",
"simnet_inbound_max_udp_streams_per_session": "每会话入站 UDP 流上限",
"simnet_initial_window_size": "H2 初始窗口",
"simnet_max_concurrent_streams": "H2 并发流上限",
"simnet_max_frame_size": "H2 最大帧大小",
"simnet_recv_window": "接收窗口",
"simnet_reverse_enabled": "启用本地反向代理",
"simnet_reverse_listen_addr": "反代监听地址",
"simnet_reverse_listen_port": "反代监听端口",
"simnet_reverse_target_host": "反代目标主机",
"simnet_reverse_target_port": "反代目标端口",
"simnet_send_window": "发送窗口",
"simnet_stream_data_channel_capacity": "流数据队列容量",
"simnet_stream_event_channel_capacity": "流事件队列容量",
"simnet_target_dial_timeout_ms": "目标拨号超时",
"simnet_target_max_concurrent_dials": "并发目标拨号上限",
"sorted_success": "排序成功", "sorted_success": "排序成功",
"status": "状态", "status": "状态",
"subscribeId": "订阅 ID", "subscribeId": "订阅 ID",
+2 -1
View File
@@ -50,7 +50,8 @@ export type ProtocolName =
| "naive" | "naive"
| "http" | "http"
| "socks" | "socks"
| "mieru"; | "mieru"
| "simnet";
const buildSchema = (t: TFunction) => const buildSchema = (t: TFunction) =>
z.object({ z.object({
@@ -10,6 +10,7 @@ export const protocols = [
"naive", "naive",
"http", "http",
"mieru", "mieru",
"simnet",
] as const; ] as const;
// Global label map for display; fallback to raw value if missing // Global label map for display; fallback to raw value if missing
@@ -69,6 +70,7 @@ export const SECURITY = {
anytls: ["none", "tls", "reality"] as const, anytls: ["none", "tls", "reality"] as const,
naive: ["none", "tls"] as const, naive: ["none", "tls"] as const,
http: ["none", "tls"] as const, http: ["none", "tls"] as const,
simnet: ["none", "tls"] as const,
} as const; } as const;
export const FLOWS = { export const FLOWS = {
@@ -99,6 +101,12 @@ export const FINGERPRINTS = [
export const CERT_MODES = ["none", "http", "dns", "self"] as const; export const CERT_MODES = ["none", "http", "dns", "self"] as const;
// Simnet enums (first version keeps carrier/af modes locked to supported values).
export const SIMNET_CARRIERS = ["h2", "ws", "raw"] as const;
export const SIMNET_AF_PATH_MODES = ["api", "random"] as const;
export const SIMNET_AF_MAGIC_MODES = ["derived", "random"] as const;
export const SIMNET_FALLBACK_SCHEMES = ["https", "http"] as const;
export const multiplexLevels = ["none", "low", "middle", "high"] as const; export const multiplexLevels = ["none", "low", "middle", "high"] as const;
export function getLabel(value: string): string { export function getLabel(value: string): string {
@@ -171,6 +171,66 @@ export function getProtocolDefaultConfig(proto: ProtocolType) {
multiplex: "none", multiplex: "none",
transport: "tcp", transport: "tcp",
} as any; } as any;
case "simnet":
return {
type: "simnet",
enable: false,
port: 443,
simnet_psk: null,
simnet_key_id: null,
simnet_ticket_id: null,
simnet_path: null,
simnet_carrier: "h2",
security: "tls",
sni: null,
allow_insecure: false,
cert_mode: "none",
cert_dns_provider: null,
cert_dns_env: null,
simnet_af_enabled: false,
simnet_af_path_mode: "api",
simnet_af_path_prefix: null,
simnet_af_path_suffix: null,
simnet_af_magic_mode: "derived",
simnet_af_response_jitter_ms: 50,
simnet_af_handshake_polymorphism: false,
simnet_af_settings_jitter: false,
simnet_af_fake_header_injection: false,
simnet_reverse_enabled: false,
simnet_reverse_listen_addr: "127.0.0.1",
simnet_reverse_listen_port: null,
simnet_reverse_target_host: "127.0.0.1",
simnet_reverse_target_port: null,
simnet_fallback_enabled: false,
simnet_fallback_target_scheme: "https",
simnet_fallback_target_host: null,
simnet_fallback_target_port: null,
simnet_fallback_host_header: null,
simnet_fallback_tls_sni: null,
simnet_inbound_max_streams_per_session: 128,
simnet_inbound_max_udp_streams_per_session: 64,
simnet_inbound_max_handler_tasks_per_session: 128,
simnet_stream_event_channel_capacity: 256,
simnet_stream_data_channel_capacity: 128,
simnet_target_dial_timeout_ms: 12_000,
simnet_target_max_concurrent_dials: 256,
simnet_egress_block_loopback: false,
simnet_egress_block_private: false,
simnet_egress_block_link_local: false,
simnet_egress_block_metadata: false,
simnet_send_window: 4_194_304,
simnet_recv_window: 4_194_304,
simnet_max_concurrent_streams: 100,
simnet_initial_window_size: 65_535,
simnet_max_frame_size: 16_384,
simnet_client_max_concurrent_streams: 32,
simnet_client_max_streams_per_session: 512,
simnet_client_session_idle_timeout_secs: 90,
simnet_client_max_udp_sessions: 64,
up_mbps: null,
down_mbps: null,
ratio: 1,
} as any;
case "anytls": case "anytls":
return { return {
type: "anytls", type: "anytls",
@@ -7,6 +7,10 @@ import {
FLOWS, FLOWS,
multiplexLevels, multiplexLevels,
SECURITY, SECURITY,
SIMNET_AF_MAGIC_MODES,
SIMNET_AF_PATH_MODES,
SIMNET_CARRIERS,
SIMNET_FALLBACK_SCHEMES,
SS_CIPHERS, SS_CIPHERS,
TRANSPORTS, TRANSPORTS,
TUIC_CONGESTION, TUIC_CONGESTION,
@@ -18,6 +22,7 @@ const nullableString = z.string().nullish();
const nullableBool = z.boolean().nullish(); const nullableBool = z.boolean().nullish();
const nullablePort = z.number().int().min(0).max(65_535).nullish(); const nullablePort = z.number().int().min(0).max(65_535).nullish();
const nullableRatio = z.number().min(0).nullish(); const nullableRatio = z.number().min(0).nullish();
const nullableNonNegativeInt = z.number().int().min(0).nullish();
const ss = z.object({ const ss = z.object({
ratio: nullableRatio, ratio: nullableRatio,
@@ -207,6 +212,66 @@ const mieru = z.object({
transport: z.enum(TRANSPORTS.mieru).nullish(), transport: z.enum(TRANSPORTS.mieru).nullish(),
}); });
const simnet = z.object({
ratio: nullableRatio,
type: z.literal("simnet"),
enable: nullableBool,
port: nullablePort,
simnet_psk: nullableString,
simnet_key_id: z.number().int().nullish(),
simnet_ticket_id: nullableString,
simnet_path: nullableString,
simnet_carrier: z.enum(SIMNET_CARRIERS).nullish(),
security: z.enum(["none", "tls"] as const).nullish(),
sni: nullableString,
allow_insecure: nullableBool,
cert_mode: z.enum(CERT_MODES).nullish(),
cert_dns_provider: nullableString,
cert_dns_env: nullableString,
simnet_af_enabled: nullableBool,
simnet_af_path_mode: z.enum(SIMNET_AF_PATH_MODES).nullish(),
simnet_af_path_prefix: nullableString,
simnet_af_path_suffix: nullableString,
simnet_af_magic_mode: z.enum(SIMNET_AF_MAGIC_MODES).nullish(),
simnet_af_response_jitter_ms: z.number().int().min(0).nullish(),
simnet_af_handshake_polymorphism: nullableBool,
simnet_af_settings_jitter: nullableBool,
simnet_af_fake_header_injection: nullableBool,
simnet_reverse_enabled: nullableBool,
simnet_reverse_listen_addr: nullableString,
simnet_reverse_listen_port: nullablePort,
simnet_reverse_target_host: nullableString,
simnet_reverse_target_port: nullablePort,
simnet_fallback_enabled: nullableBool,
simnet_fallback_target_scheme: z.enum(SIMNET_FALLBACK_SCHEMES).nullish(),
simnet_fallback_target_host: nullableString,
simnet_fallback_target_port: nullablePort,
simnet_fallback_host_header: nullableString,
simnet_fallback_tls_sni: nullableString,
simnet_inbound_max_streams_per_session: nullableNonNegativeInt,
simnet_inbound_max_udp_streams_per_session: nullableNonNegativeInt,
simnet_inbound_max_handler_tasks_per_session: nullableNonNegativeInt,
simnet_stream_event_channel_capacity: nullableNonNegativeInt,
simnet_stream_data_channel_capacity: nullableNonNegativeInt,
simnet_target_dial_timeout_ms: nullableNonNegativeInt,
simnet_target_max_concurrent_dials: nullableNonNegativeInt,
simnet_egress_block_loopback: nullableBool,
simnet_egress_block_private: nullableBool,
simnet_egress_block_link_local: nullableBool,
simnet_egress_block_metadata: nullableBool,
simnet_send_window: nullableNonNegativeInt,
simnet_recv_window: nullableNonNegativeInt,
simnet_max_concurrent_streams: nullableNonNegativeInt,
simnet_initial_window_size: nullableNonNegativeInt,
simnet_max_frame_size: nullableNonNegativeInt,
simnet_client_max_concurrent_streams: nullableNonNegativeInt,
simnet_client_max_streams_per_session: nullableNonNegativeInt,
simnet_client_session_idle_timeout_secs: nullableNonNegativeInt,
simnet_client_max_udp_sessions: nullableNonNegativeInt,
up_mbps: z.number().nullish(),
down_mbps: z.number().nullish(),
});
export const protocolApiScheme = z.discriminatedUnion("type", [ export const protocolApiScheme = z.discriminatedUnion("type", [
ss, ss,
vmess, vmess,
@@ -219,6 +284,7 @@ export const protocolApiScheme = z.discriminatedUnion("type", [
naive, naive,
http, http,
mieru, mieru,
simnet,
]); ]);
export const formSchema = z.object({ export const formSchema = z.object({
@@ -32,7 +32,8 @@ export type FieldConfig = {
| "security" | "security"
| "reality" | "reality"
| "obfs" | "obfs"
| "encryption"; | "encryption"
| "simnet";
gridSpan?: 1 | 2; gridSpan?: 1 | 2;
}; };
@@ -15,6 +15,10 @@ import {
FLOWS, FLOWS,
multiplexLevels, multiplexLevels,
SECURITY, SECURITY,
SIMNET_AF_MAGIC_MODES,
SIMNET_AF_PATH_MODES,
SIMNET_CARRIERS,
SIMNET_FALLBACK_SCHEMES,
SS_CIPHERS, SS_CIPHERS,
TRANSPORTS, TRANSPORTS,
TUIC_CONGESTION, TUIC_CONGESTION,
@@ -1221,6 +1225,499 @@ export function useProtocolFields() {
condition: (p) => p.security === "reality", condition: (p) => p.security === "reality",
}, },
], ],
simnet: [
{
name: "ratio",
type: "number",
label: t("traffic_ratio", "Ratio"),
min: 0,
step: 0.01,
defaultValue: 1,
group: "basic",
},
{
name: "port",
type: "number",
label: t("port", "Port"),
min: 1,
max: 65_535,
placeholder: "443",
group: "basic",
},
{
name: "simnet_psk",
type: "input",
label: t("simnet_psk", "SimNet PSK"),
placeholder: t(
"simnet_psk_placeholder",
"Server pre-shared key (shared across all users)"
),
generate: {
function: () => generatePassword(32),
},
group: "basic",
},
{
name: "simnet_ticket_id",
type: "input",
label: t("simnet_ticket_id", "SimNet Ticket ID"),
placeholder: t("simnet_ticket_id_placeholder", "Optional ticket id"),
group: "basic",
},
{
name: "simnet_path",
type: "input",
label: t("simnet_path", "SimNet Path"),
placeholder: t("simnet_path_placeholder", "e.g. /simnet"),
group: "basic",
},
{
name: "simnet_carrier",
type: "select",
label: t("simnet_carrier", "Carrier"),
options: SIMNET_CARRIERS,
defaultValue: "h2",
group: "basic",
},
{
name: "up_mbps",
type: "number",
label: t("up_mbps", "Upload Bandwidth"),
min: 1,
placeholder: t(
"bandwidth_placeholder",
"Enter bandwidth, leave empty for BBR"
),
suffix: "Mbps",
group: "basic",
},
{
name: "down_mbps",
type: "number",
label: t("down_mbps", "Download Bandwidth"),
min: 1,
placeholder: t(
"bandwidth_placeholder",
"Enter bandwidth, leave empty for BBR"
),
suffix: "Mbps",
group: "basic",
},
{
name: "security",
type: "select",
label: t("security", "Security"),
options: ["none", "tls"],
defaultValue: "tls",
group: "security",
},
{
name: "sni",
type: "input",
label: t("security_sni", "SNI"),
placeholder: t("sni_placeholder", "e.g. edge.example.com"),
group: "security",
},
{
name: "allow_insecure",
type: "switch",
label: t("security_allow_insecure", "Allow Insecure"),
group: "security",
},
{
name: "cert_mode",
type: "select",
label: t("cert_mode", "Certificate Mode"),
options: CERT_MODES,
defaultValue: "none",
group: "security",
},
{
name: "cert_dns_provider",
type: "input",
label: t("cert_dns_provider", "DNS Provider"),
placeholder: "e.g. cloudflare, aliyun",
group: "security",
condition: (p) => p.cert_mode === "dns",
},
{
name: "cert_dns_env",
type: "textarea",
label: t("cert_dns_env", "DNS Environment Variables"),
placeholder:
"CF_DNS_API_TOKEN=1234567890abcdefghijklmnopqrstuvwxyz\nALI_ACCESS_KEY_ID=your_access_key_id\nALI_ACCESS_KEY_SECRET=your_access_key_secret",
group: "security",
condition: (p) => p.cert_mode === "dns",
},
{
name: "simnet_af_enabled",
type: "switch",
label: t("simnet_af_enabled", "Enable Anti-Fingerprint"),
group: "simnet",
},
{
name: "simnet_af_path_mode",
type: "select",
label: t("simnet_af_path_mode", "AF Path Mode"),
options: SIMNET_AF_PATH_MODES,
defaultValue: "api",
group: "simnet",
condition: (p) => !!p.simnet_af_enabled,
},
{
name: "simnet_af_path_prefix",
type: "input",
label: t("simnet_af_path_prefix", "AF Path Prefix"),
placeholder: t(
"simnet_af_path_prefix_placeholder",
"Optional path prefix"
),
group: "simnet",
condition: (p) => !!p.simnet_af_enabled,
},
{
name: "simnet_af_path_suffix",
type: "input",
label: t("simnet_af_path_suffix", "AF Path Suffix"),
placeholder: t(
"simnet_af_path_suffix_placeholder",
"Optional path suffix"
),
group: "simnet",
condition: (p) => !!p.simnet_af_enabled,
},
{
name: "simnet_af_magic_mode",
type: "select",
label: t("simnet_af_magic_mode", "AF Magic Mode"),
options: SIMNET_AF_MAGIC_MODES,
defaultValue: "derived",
group: "simnet",
condition: (p) => !!p.simnet_af_enabled,
},
{
name: "simnet_af_response_jitter_ms",
type: "number",
label: t("simnet_af_response_jitter_ms", "AF Response Jitter"),
min: 0,
suffix: "ms",
defaultValue: 50,
group: "simnet",
condition: (p) => !!p.simnet_af_enabled,
},
{
name: "simnet_af_handshake_polymorphism",
type: "switch",
label: t(
"simnet_af_handshake_polymorphism",
"Handshake Polymorphism"
),
group: "simnet",
condition: (p) => !!p.simnet_af_enabled,
},
{
name: "simnet_af_settings_jitter",
type: "switch",
label: t("simnet_af_settings_jitter", "Settings Jitter"),
group: "simnet",
condition: (p) => !!p.simnet_af_enabled,
},
{
name: "simnet_af_fake_header_injection",
type: "switch",
label: t("simnet_af_fake_header_injection", "Fake Header Injection"),
group: "simnet",
condition: (p) => !!p.simnet_af_enabled,
},
{
name: "simnet_reverse_enabled",
type: "switch",
label: t("simnet_reverse_enabled", "Enable Local Reverse Proxy"),
group: "simnet",
},
{
name: "simnet_reverse_listen_addr",
type: "input",
label: t("simnet_reverse_listen_addr", "Reverse Listen Address"),
placeholder: "127.0.0.1",
group: "simnet",
condition: (p) => !!p.simnet_reverse_enabled,
},
{
name: "simnet_reverse_listen_port",
type: "number",
label: t("simnet_reverse_listen_port", "Reverse Listen Port"),
min: 1,
max: 65_535,
placeholder: "18080",
group: "simnet",
condition: (p) => !!p.simnet_reverse_enabled,
},
{
name: "simnet_reverse_target_host",
type: "input",
label: t("simnet_reverse_target_host", "Reverse Target Host"),
placeholder: "127.0.0.1",
group: "simnet",
condition: (p) => !!p.simnet_reverse_enabled,
},
{
name: "simnet_reverse_target_port",
type: "number",
label: t("simnet_reverse_target_port", "Reverse Target Port"),
min: 1,
max: 65_535,
placeholder: "8080",
group: "simnet",
condition: (p) => !!p.simnet_reverse_enabled,
},
{
name: "simnet_fallback_enabled",
type: "switch",
label: t(
"simnet_fallback_enabled",
"Enable HTTPS Fallback Reverse Proxy"
),
group: "simnet",
},
{
name: "simnet_fallback_target_scheme",
type: "select",
label: t("simnet_fallback_target_scheme", "Fallback Target Scheme"),
options: SIMNET_FALLBACK_SCHEMES,
defaultValue: "https",
group: "simnet",
condition: (p) => !!p.simnet_fallback_enabled,
},
{
name: "simnet_fallback_target_host",
type: "input",
label: t("simnet_fallback_target_host", "Fallback Target Host"),
placeholder: t(
"simnet_fallback_target_host_placeholder",
"e.g. www.example.com"
),
group: "simnet",
condition: (p) => !!p.simnet_fallback_enabled,
},
{
name: "simnet_fallback_target_port",
type: "number",
label: t("simnet_fallback_target_port", "Fallback Target Port"),
min: 1,
max: 65_535,
placeholder: "443 / 80",
group: "simnet",
condition: (p) => !!p.simnet_fallback_enabled,
},
{
name: "simnet_fallback_host_header",
type: "input",
label: t("simnet_fallback_host_header", "Fallback Host Header"),
placeholder: t(
"simnet_fallback_host_header_placeholder",
"Optional, defaults to target host"
),
group: "simnet",
condition: (p) => !!p.simnet_fallback_enabled,
},
{
name: "simnet_fallback_tls_sni",
type: "input",
label: t("simnet_fallback_tls_sni", "Fallback TLS SNI"),
placeholder: t(
"simnet_fallback_tls_sni_placeholder",
"Optional, defaults to target host"
),
group: "simnet",
condition: (p) => !!p.simnet_fallback_enabled,
},
{
name: "simnet_inbound_max_streams_per_session",
type: "number",
label: t(
"simnet_inbound_max_streams_per_session",
"Inbound Streams / Session"
),
min: 1,
defaultValue: 128,
group: "simnet",
},
{
name: "simnet_inbound_max_udp_streams_per_session",
type: "number",
label: t(
"simnet_inbound_max_udp_streams_per_session",
"Inbound UDP Streams / Session"
),
min: 1,
defaultValue: 64,
group: "simnet",
},
{
name: "simnet_inbound_max_handler_tasks_per_session",
type: "number",
label: t(
"simnet_inbound_max_handler_tasks_per_session",
"Handler Tasks / Session"
),
min: 1,
defaultValue: 128,
group: "simnet",
},
{
name: "simnet_stream_event_channel_capacity",
type: "number",
label: t(
"simnet_stream_event_channel_capacity",
"Stream Event Channel"
),
min: 1,
defaultValue: 256,
group: "simnet",
},
{
name: "simnet_stream_data_channel_capacity",
type: "number",
label: t(
"simnet_stream_data_channel_capacity",
"Stream Data Channel"
),
min: 1,
defaultValue: 128,
group: "simnet",
},
{
name: "simnet_target_dial_timeout_ms",
type: "number",
label: t("simnet_target_dial_timeout_ms", "Target Dial Timeout"),
min: 1,
suffix: "ms",
defaultValue: 12_000,
group: "simnet",
},
{
name: "simnet_target_max_concurrent_dials",
type: "number",
label: t(
"simnet_target_max_concurrent_dials",
"Concurrent Target Dials"
),
min: 1,
defaultValue: 256,
group: "simnet",
},
{
name: "simnet_send_window",
type: "number",
label: t("simnet_send_window", "Send Window"),
min: 1,
suffix: "bytes",
defaultValue: 4_194_304,
group: "simnet",
},
{
name: "simnet_recv_window",
type: "number",
label: t("simnet_recv_window", "Receive Window"),
min: 1,
suffix: "bytes",
defaultValue: 4_194_304,
group: "simnet",
},
{
name: "simnet_max_concurrent_streams",
type: "number",
label: t("simnet_max_concurrent_streams", "H2 Concurrent Streams"),
min: 1,
defaultValue: 100,
group: "simnet",
},
{
name: "simnet_initial_window_size",
type: "number",
label: t("simnet_initial_window_size", "H2 Initial Window"),
min: 1,
suffix: "bytes",
defaultValue: 65_535,
group: "simnet",
},
{
name: "simnet_max_frame_size",
type: "number",
label: t("simnet_max_frame_size", "H2 Max Frame Size"),
min: 1,
suffix: "bytes",
defaultValue: 16_384,
group: "simnet",
},
{
name: "simnet_client_max_concurrent_streams",
type: "number",
label: t(
"simnet_client_max_concurrent_streams",
"Client Concurrent Streams"
),
min: 1,
defaultValue: 32,
group: "simnet",
},
{
name: "simnet_client_max_streams_per_session",
type: "number",
label: t(
"simnet_client_max_streams_per_session",
"Client Streams / Session"
),
min: 1,
defaultValue: 512,
group: "simnet",
},
{
name: "simnet_client_session_idle_timeout_secs",
type: "number",
label: t(
"simnet_client_session_idle_timeout_secs",
"Client Session Idle Timeout"
),
min: 1,
suffix: "s",
defaultValue: 90,
group: "simnet",
},
{
name: "simnet_client_max_udp_sessions",
type: "number",
label: t("simnet_client_max_udp_sessions", "Client UDP Sessions"),
min: 1,
defaultValue: 64,
group: "simnet",
},
{
name: "simnet_egress_block_loopback",
type: "switch",
label: t("simnet_egress_block_loopback", "Block Loopback Egress"),
group: "simnet",
},
{
name: "simnet_egress_block_private",
type: "switch",
label: t("simnet_egress_block_private", "Block Private Egress"),
group: "simnet",
},
{
name: "simnet_egress_block_link_local",
type: "switch",
label: t("simnet_egress_block_link_local", "Block Link-Local Egress"),
group: "simnet",
},
{
name: "simnet_egress_block_metadata",
type: "switch",
label: t("simnet_egress_block_metadata", "Block Metadata Egress"),
group: "simnet",
},
],
}), }),
[t] [t]
); );
@@ -696,6 +696,15 @@ export default function ServerForm(props: {
i, i,
current current
)} )}
{renderGroupCard(
t("simnet", "SimNet"),
fields,
"simnet",
control,
form,
i,
current
)}
</div> </div>
</AccordionContent> </AccordionContent>
</AccordionItem> </AccordionItem>