Format plural list options as arrays

This commit is contained in:
世界 2026-09-28 03:37:16 +08:00
parent d630fa94c5
commit a8bd33a8ad
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
12 changed files with 226 additions and 398 deletions

View file

@ -247,7 +247,7 @@ func TestNewAppleSessionConfig(t *testing.T) {
options: option.HTTPClientOptions{
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
CipherSuites: badoption.Listable[string]{"TLS_AES_128_GCM_SHA256"},
CipherSuites: option.LegacyListable[string]{"TLS_AES_128_GCM_SHA256"},
},
},
},
@ -258,7 +258,7 @@ func TestNewAppleSessionConfig(t *testing.T) {
options: option.HTTPClientOptions{
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
CurvePreferences: badoption.Listable[option.CurvePreference]{option.CurvePreference(option.X25519)},
CurvePreferences: option.LegacyListable[option.CurvePreference]{option.CurvePreference(option.X25519)},
},
},
},

View file

@ -153,17 +153,10 @@
"$ref": "#/$defs/Duration"
},
"resolvers": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"override_domain": {
"type": "string"
@ -202,17 +195,10 @@
"$ref": "#/$defs/Duration"
},
"resolvers": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"override_domain": {
"type": "string"
@ -245,17 +231,10 @@
"$ref": "#/$defs/Duration"
},
"resolvers": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"override_domain": {
"type": "string"
@ -3946,17 +3925,10 @@
"type": "string"
},
"data_ciphers": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"data_ciphers_fallback": {
"type": "string"
@ -4035,17 +4007,10 @@
}
},
"routes": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"route_gateway": {
"type": "string"
@ -4057,17 +4022,10 @@
"type": "boolean"
},
"redirect_gateway_flags": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"redirect_private": {
"type": "boolean"
@ -4307,17 +4265,10 @@
"type": "string"
},
"data_ciphers": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"data_ciphers_fallback": {
"type": "string"
@ -4522,17 +4473,10 @@
"type": "boolean"
},
"advertise_tags": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"listen_port": {
"type": "integer",
@ -5582,17 +5526,10 @@
"type": "string"
},
"stun_servers": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"ip_version": {
"type": "integer",
@ -5627,17 +5564,10 @@
"type": "string"
},
"stun_servers": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"ip_version": {
"type": "integer",
@ -8351,44 +8281,23 @@
]
},
"cipher_suites": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"curve_preferences": {
"anyOf": [
{
"type": "string",
"enum": [
"P256",
"P384",
"P521",
"X25519",
"X25519MLKEM768"
]
},
{
"type": "array",
"items": {
"type": "string",
"enum": [
"P256",
"P384",
"P521",
"X25519",
"X25519MLKEM768"
]
}
}
]
"type": "array",
"items": {
"type": "string",
"enum": [
"P256",
"P384",
"P521",
"X25519",
"X25519MLKEM768"
]
}
},
"certificate": {
"anyOf": [
@ -10558,30 +10467,16 @@
"type": "integer"
},
"addresses": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"resolve_domains": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"dnssec": {
"type": "string",
@ -10609,17 +10504,10 @@
"type": "object",
"properties": {
"routes": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"dns": {
"anyOf": [
@ -10641,46 +10529,25 @@
}
},
"search_domains": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"dhcp_options": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"redirect_gateway": {
"type": "boolean"
},
"redirect_gateway_flags": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"block_outside_dns": {
"type": "boolean"
@ -11271,17 +11138,10 @@
"maximum": 65535
},
"server_ports": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"hop_interval": {
"$ref": "#/$defs/Duration"
@ -11519,17 +11379,10 @@
"maximum": 65535
},
"server_ports": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"hop_interval": {
"$ref": "#/$defs/Duration"
@ -12906,17 +12759,10 @@
]
},
"host_key_algorithms": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"client_version": {
"type": "string"
@ -13990,44 +13836,23 @@
]
},
"cipher_suites": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"curve_preferences": {
"anyOf": [
{
"type": "string",
"enum": [
"P256",
"P384",
"P521",
"X25519",
"X25519MLKEM768"
]
},
{
"type": "array",
"items": {
"type": "string",
"enum": [
"P256",
"P384",
"P521",
"X25519",
"X25519MLKEM768"
]
}
}
]
"type": "array",
"items": {
"type": "string",
"enum": [
"P256",
"P384",
"P521",
"X25519",
"X25519MLKEM768"
]
}
},
"certificate": {
"anyOf": [
@ -14212,17 +14037,10 @@
"type": "boolean"
},
"dhcp_lease_files": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"auto_detect_interface": {
"type": "boolean"
@ -17333,17 +17151,10 @@
"type": "string"
},
"allowed_ips": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
"type": "array",
"items": {
"type": "string"
}
},
"persistent_keepalive_interval": {
"type": "integer",

View file

@ -39,11 +39,11 @@ type _ACMEProviderDNS01ChallengeOptions struct {
}
type AbstractACMEProviderDNS01ChallengeOptions struct {
TTL badoption.Duration `json:"ttl,omitempty"`
PropagationDelay badoption.Duration `json:"propagation_delay,omitempty"`
PropagationTimeout badoption.Duration `json:"propagation_timeout,omitempty"`
Resolvers badoption.Listable[string] `json:"resolvers,omitempty"`
OverrideDomain string `json:"override_domain,omitempty"`
TTL badoption.Duration `json:"ttl,omitempty"`
PropagationDelay badoption.Duration `json:"propagation_delay,omitempty"`
PropagationTimeout badoption.Duration `json:"propagation_timeout,omitempty"`
Resolvers LegacyListable[string] `json:"resolvers,omitempty"`
OverrideDomain string `json:"override_domain,omitempty"`
}
type ACMEProviderDNS01ChallengeOptions _ACMEProviderDNS01ChallengeOptions

View file

@ -34,7 +34,7 @@ type HysteriaUser struct {
type HysteriaOutboundOptions struct {
DialerOptions
ServerOptions
ServerPorts badoption.Listable[string] `json:"server_ports,omitempty"`
ServerPorts LegacyListable[string] `json:"server_ports,omitempty"`
HopInterval badoption.Duration `json:"hop_interval,omitempty"`
Up *byteformats.NetworkBytesCompat `json:"up,omitempty"`
UpMbps int `json:"up_mbps,omitempty"`

View file

@ -33,7 +33,7 @@ type Hysteria2Realm struct {
ServerURL string `json:"server_url"`
Token string `json:"token,omitempty"`
RealmID string `json:"realm_id"`
STUNServers badoption.Listable[string] `json:"stun_servers"`
STUNServers LegacyListable[string] `json:"stun_servers"`
IPVersion int `json:"ip_version,omitempty" enum:"0,4,6"`
PortMapping *Hysteria2RealmPortMapping `json:"port_mapping,omitempty"`
HTTPClient *HTTPClientOptions `json:"http_client,omitempty"`
@ -210,14 +210,14 @@ type Hysteria2MasqueradeString struct {
type Hysteria2OutboundOptions struct {
DialerOptions
ServerOptions
ServerPorts badoption.Listable[string] `json:"server_ports,omitempty"`
HopInterval badoption.Duration `json:"hop_interval,omitempty"`
HopIntervalMax badoption.Duration `json:"hop_interval_max,omitempty"`
UpMbps int `json:"up_mbps,omitempty"`
DownMbps int `json:"down_mbps,omitempty"`
Obfs *Hysteria2Obfs `json:"obfs,omitempty"`
Password string `json:"password,omitempty"`
Network NetworkList `json:"network,omitempty"`
ServerPorts LegacyListable[string] `json:"server_ports,omitempty"`
HopInterval badoption.Duration `json:"hop_interval,omitempty"`
HopIntervalMax badoption.Duration `json:"hop_interval_max,omitempty"`
UpMbps int `json:"up_mbps,omitempty"`
DownMbps int `json:"down_mbps,omitempty"`
Obfs *Hysteria2Obfs `json:"obfs,omitempty"`
Password string `json:"password,omitempty"`
Network NetworkList `json:"network,omitempty"`
OutboundTLSOptionsContainer
QUICOptions
BBRProfile string `json:"bbr_profile,omitempty" enum:"standard,conservative,aggressive"`

View file

@ -38,7 +38,7 @@ type OpenVPNClientEndpointOptions struct {
KeyDirection string `json:"key_direction,omitempty" enum:"server,client"`
TLS *OpenVPNOutboundTLSOptions `json:"tls,omitempty"`
Cipher string `json:"cipher,omitempty"`
DataCiphers badoption.Listable[string] `json:"data_ciphers,omitempty"`
DataCiphers LegacyListable[string] `json:"data_ciphers,omitempty"`
DataCiphersFallback string `json:"data_ciphers_fallback,omitempty"`
Auth string `json:"auth,omitempty"`
MSSFix uint32 `json:"mss_fix,omitempty"`
@ -52,11 +52,11 @@ type OpenVPNClientEndpointOptions struct {
AllowCompression string `json:"allow_compression,omitempty" enum:"no,asym,yes"`
RouteNoPull bool `json:"route_no_pull,omitempty"`
PullFilters []OpenVPNPullFilterOptions `json:"pull_filters,omitempty"`
Routes badoption.Listable[netip.Prefix] `json:"routes,omitempty"`
Routes LegacyListable[netip.Prefix] `json:"routes,omitempty"`
RouteGateway *badoption.Addr `json:"route_gateway,omitempty"`
RouteMetric int `json:"route_metric,omitempty"`
RedirectGateway bool `json:"redirect_gateway,omitempty"`
RedirectGatewayFlags badoption.Listable[string] `json:"redirect_gateway_flags,omitempty"`
RedirectGatewayFlags LegacyListable[string] `json:"redirect_gateway_flags,omitempty"`
RedirectPrivate bool `json:"redirect_private,omitempty"`
BlockIPv6 bool `json:"block_ipv6,omitempty"`
PingInterval badoption.Duration `json:"ping_interval,omitempty"`
@ -91,7 +91,7 @@ type OpenVPNServerEndpointOptions struct {
KeyDirection string `json:"key_direction,omitempty" enum:"server,client"`
TLS *OpenVPNInboundTLSOptions `json:"tls,omitempty"`
Cipher string `json:"cipher,omitempty"`
DataCiphers badoption.Listable[string] `json:"data_ciphers,omitempty"`
DataCiphers LegacyListable[string] `json:"data_ciphers,omitempty"`
DataCiphersFallback string `json:"data_ciphers_fallback,omitempty"`
Auth string `json:"auth,omitempty"`
MSSFix uint32 `json:"mss_fix,omitempty"`
@ -182,25 +182,25 @@ type OpenVPNInboundControlWrapOptions struct {
}
type OpenVPNPushOptions struct {
Routes badoption.Listable[netip.Prefix] `json:"routes,omitempty"`
DNS badoption.Listable[netip.Addr] `json:"dns,omitempty"`
DNSServers []OpenVPNPushDNSServerOptions `json:"dns_servers,omitempty"`
SearchDomains badoption.Listable[string] `json:"search_domains,omitempty"`
DHCPOptions badoption.Listable[string] `json:"dhcp_options,omitempty"`
RedirectGateway bool `json:"redirect_gateway,omitempty"`
RedirectGatewayFlags badoption.Listable[string] `json:"redirect_gateway_flags,omitempty"`
BlockOutsideDNS bool `json:"block_outside_dns,omitempty"`
PingInterval badoption.Duration `json:"ping_interval,omitempty"`
PingRestart badoption.Duration `json:"ping_restart,omitempty"`
Routes LegacyListable[netip.Prefix] `json:"routes,omitempty"`
DNS badoption.Listable[netip.Addr] `json:"dns,omitempty"`
DNSServers []OpenVPNPushDNSServerOptions `json:"dns_servers,omitempty"`
SearchDomains LegacyListable[string] `json:"search_domains,omitempty"`
DHCPOptions LegacyListable[string] `json:"dhcp_options,omitempty"`
RedirectGateway bool `json:"redirect_gateway,omitempty"`
RedirectGatewayFlags LegacyListable[string] `json:"redirect_gateway_flags,omitempty"`
BlockOutsideDNS bool `json:"block_outside_dns,omitempty"`
PingInterval badoption.Duration `json:"ping_interval,omitempty"`
PingRestart badoption.Duration `json:"ping_restart,omitempty"`
}
type OpenVPNPushDNSServerOptions struct {
Priority int `json:"priority"`
Addresses badoption.Listable[string] `json:"addresses"`
ResolveDomains badoption.Listable[string] `json:"resolve_domains,omitempty"`
DNSSEC string `json:"dnssec,omitempty" enum:"yes,optional,no"`
Transport string `json:"transport,omitempty" enum:"plain,dot,doh"`
SNI string `json:"sni,omitempty"`
Priority int `json:"priority"`
Addresses LegacyListable[string] `json:"addresses"`
ResolveDomains LegacyListable[string] `json:"resolve_domains,omitempty"`
DNSSEC string `json:"dnssec,omitempty" enum:"yes,optional,no"`
Transport string `json:"transport,omitempty" enum:"plain,dot,doh"`
SNI string `json:"sni,omitempty"`
}
type OpenVPNDNSServerOptions struct {

View file

@ -10,7 +10,7 @@ type RouteOptions struct {
Final string `json:"final,omitempty" reference:"outbound"`
FindProcess bool `json:"find_process,omitempty"`
FindNeighbor bool `json:"find_neighbor,omitempty"`
DHCPLeaseFiles badoption.Listable[string] `json:"dhcp_lease_files,omitempty"`
DHCPLeaseFiles LegacyListable[string] `json:"dhcp_lease_files,omitempty"`
AutoDetectInterface bool `json:"auto_detect_interface,omitempty"`
OverrideAndroidVPN bool `json:"override_android_vpn,omitempty"`
DefaultInterface string `json:"default_interface,omitempty"`

View file

@ -11,7 +11,7 @@ type SSHOutboundOptions struct {
PrivateKeyPath string `json:"private_key_path,omitempty"`
PrivateKeyPassphrase string `json:"private_key_passphrase,omitempty"`
HostKey badoption.Listable[string] `json:"host_key,omitempty"`
HostKeyAlgorithms badoption.Listable[string] `json:"host_key_algorithms,omitempty"`
HostKeyAlgorithms LegacyListable[string] `json:"host_key_algorithms,omitempty"`
ClientVersion string `json:"client_version,omitempty"`
Cipher badoption.Listable[string] `json:"cipher,omitempty"`
MAC badoption.Listable[string] `json:"mac,omitempty"`

View file

@ -24,7 +24,7 @@ type TailscaleEndpointOptions struct {
ExitNodeAllowLANAccess bool `json:"exit_node_allow_lan_access,omitempty"`
AdvertiseRoutes []netip.Prefix `json:"advertise_routes,omitempty"`
AdvertiseExitNode bool `json:"advertise_exit_node,omitempty"`
AdvertiseTags badoption.Listable[string] `json:"advertise_tags,omitempty"`
AdvertiseTags LegacyListable[string] `json:"advertise_tags,omitempty"`
ListenPort uint16 `json:"listen_port,omitempty"`
RelayServerPort *uint16 `json:"relay_server_port,omitempty"`
RelayServerStaticEndpoints []netip.AddrPort `json:"relay_server_static_endpoints,omitempty"`

View file

@ -11,26 +11,26 @@ import (
)
type InboundTLSOptions struct {
Enabled bool `json:"enabled,omitempty"`
ServerName string `json:"server_name,omitempty"`
Insecure bool `json:"insecure,omitempty"`
ALPN badoption.Listable[string] `json:"alpn,omitempty" examples:"http/1.1,h2,h3"`
MinVersion string `json:"min_version,omitempty" enum:"1.0,1.1,1.2,1.3"`
MaxVersion string `json:"max_version,omitempty" enum:"1.0,1.1,1.2,1.3"`
CipherSuites badoption.Listable[string] `json:"cipher_suites,omitempty"`
CurvePreferences badoption.Listable[CurvePreference] `json:"curve_preferences,omitempty"`
Certificate badoption.Listable[string] `json:"certificate,omitempty"`
CertificatePath string `json:"certificate_path,omitempty"`
ClientAuthentication ClientAuthType `json:"client_authentication,omitempty"`
ClientCertificate badoption.Listable[string] `json:"client_certificate,omitempty"`
ClientCertificatePath badoption.Listable[string] `json:"client_certificate_path,omitempty"`
ClientCertificatePublicKeySHA256 badoption.Listable[[]byte] `json:"client_certificate_public_key_sha256,omitempty"`
Key badoption.Listable[string] `json:"key,omitempty"`
KeyPath string `json:"key_path,omitempty"`
KernelTx bool `json:"kernel_tx,omitempty"`
KernelRx bool `json:"kernel_rx,omitempty"`
HandshakeTimeout badoption.Duration `json:"handshake_timeout,omitempty"`
CertificateProvider *CertificateProviderOptions `json:"certificate_provider,omitempty"`
Enabled bool `json:"enabled,omitempty"`
ServerName string `json:"server_name,omitempty"`
Insecure bool `json:"insecure,omitempty"`
ALPN badoption.Listable[string] `json:"alpn,omitempty" examples:"http/1.1,h2,h3"`
MinVersion string `json:"min_version,omitempty" enum:"1.0,1.1,1.2,1.3"`
MaxVersion string `json:"max_version,omitempty" enum:"1.0,1.1,1.2,1.3"`
CipherSuites LegacyListable[string] `json:"cipher_suites,omitempty"`
CurvePreferences LegacyListable[CurvePreference] `json:"curve_preferences,omitempty"`
Certificate badoption.Listable[string] `json:"certificate,omitempty"`
CertificatePath string `json:"certificate_path,omitempty"`
ClientAuthentication ClientAuthType `json:"client_authentication,omitempty"`
ClientCertificate badoption.Listable[string] `json:"client_certificate,omitempty"`
ClientCertificatePath badoption.Listable[string] `json:"client_certificate_path,omitempty"`
ClientCertificatePublicKeySHA256 badoption.Listable[[]byte] `json:"client_certificate_public_key_sha256,omitempty"`
Key badoption.Listable[string] `json:"key,omitempty"`
KeyPath string `json:"key_path,omitempty"`
KernelTx bool `json:"kernel_tx,omitempty"`
KernelRx bool `json:"kernel_rx,omitempty"`
HandshakeTimeout badoption.Duration `json:"handshake_timeout,omitempty"`
CertificateProvider *CertificateProviderOptions `json:"certificate_provider,omitempty"`
// Deprecated: use certificate_provider
ACME *InboundACMEOptions `json:"acme,omitempty" schema:"omit"`
@ -105,34 +105,34 @@ func (o *InboundTLSOptionsContainer) ReplaceInboundTLSOptions(options *InboundTL
}
type OutboundTLSOptions struct {
Enabled bool `json:"enabled,omitempty"`
Engine string `json:"engine,omitempty" enum:"go,apple,windows"`
DisableSNI bool `json:"disable_sni,omitempty"`
ServerName string `json:"server_name,omitempty"`
Insecure bool `json:"insecure,omitempty"`
ALPN badoption.Listable[string] `json:"alpn,omitempty" examples:"http/1.1,h2,h3"`
MinVersion string `json:"min_version,omitempty" enum:"1.0,1.1,1.2,1.3"`
MaxVersion string `json:"max_version,omitempty" enum:"1.0,1.1,1.2,1.3"`
CipherSuites badoption.Listable[string] `json:"cipher_suites,omitempty"`
CurvePreferences badoption.Listable[CurvePreference] `json:"curve_preferences,omitempty"`
Certificate badoption.Listable[string] `json:"certificate,omitempty"`
CertificatePath string `json:"certificate_path,omitempty"`
CertificatePublicKeySHA256 badoption.Listable[[]byte] `json:"certificate_public_key_sha256,omitempty"`
ClientCertificate badoption.Listable[string] `json:"client_certificate,omitempty"`
ClientCertificatePath string `json:"client_certificate_path,omitempty"`
ClientKey badoption.Listable[string] `json:"client_key,omitempty"`
ClientKeyPath string `json:"client_key_path,omitempty"`
Fragment bool `json:"fragment,omitempty"`
FragmentFallbackDelay badoption.Duration `json:"fragment_fallback_delay,omitempty"`
RecordFragment bool `json:"record_fragment,omitempty"`
Spoof string `json:"spoof,omitempty"`
SpoofMethod string `json:"spoof_method,omitempty" enum:"wrong-sequence,wrong-checksum,wrong-ack,wrong-md5,wrong-timestamp"`
KernelTx bool `json:"kernel_tx,omitempty"`
KernelRx bool `json:"kernel_rx,omitempty"`
HandshakeTimeout badoption.Duration `json:"handshake_timeout,omitempty"`
ECH *OutboundECHOptions `json:"ech,omitempty"`
UTLS *OutboundUTLSOptions `json:"utls,omitempty"`
Reality *OutboundRealityOptions `json:"reality,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Engine string `json:"engine,omitempty" enum:"go,apple,windows"`
DisableSNI bool `json:"disable_sni,omitempty"`
ServerName string `json:"server_name,omitempty"`
Insecure bool `json:"insecure,omitempty"`
ALPN badoption.Listable[string] `json:"alpn,omitempty" examples:"http/1.1,h2,h3"`
MinVersion string `json:"min_version,omitempty" enum:"1.0,1.1,1.2,1.3"`
MaxVersion string `json:"max_version,omitempty" enum:"1.0,1.1,1.2,1.3"`
CipherSuites LegacyListable[string] `json:"cipher_suites,omitempty"`
CurvePreferences LegacyListable[CurvePreference] `json:"curve_preferences,omitempty"`
Certificate badoption.Listable[string] `json:"certificate,omitempty"`
CertificatePath string `json:"certificate_path,omitempty"`
CertificatePublicKeySHA256 badoption.Listable[[]byte] `json:"certificate_public_key_sha256,omitempty"`
ClientCertificate badoption.Listable[string] `json:"client_certificate,omitempty"`
ClientCertificatePath string `json:"client_certificate_path,omitempty"`
ClientKey badoption.Listable[string] `json:"client_key,omitempty"`
ClientKeyPath string `json:"client_key_path,omitempty"`
Fragment bool `json:"fragment,omitempty"`
FragmentFallbackDelay badoption.Duration `json:"fragment_fallback_delay,omitempty"`
RecordFragment bool `json:"record_fragment,omitempty"`
Spoof string `json:"spoof,omitempty"`
SpoofMethod string `json:"spoof_method,omitempty" enum:"wrong-sequence,wrong-checksum,wrong-ack,wrong-md5,wrong-timestamp"`
KernelTx bool `json:"kernel_tx,omitempty"`
KernelRx bool `json:"kernel_rx,omitempty"`
HandshakeTimeout badoption.Duration `json:"handshake_timeout,omitempty"`
ECH *OutboundECHOptions `json:"ech,omitempty"`
UTLS *OutboundUTLSOptions `json:"utls,omitempty"`
Reality *OutboundRealityOptions `json:"reality,omitempty"`
}
type OutboundTLSOptionsContainer struct {

View file

@ -1,7 +1,9 @@
package option
import (
"context"
"maps"
"reflect"
"slices"
"strings"
@ -10,11 +12,26 @@ import (
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/json"
"github.com/sagernet/sing/common/json/badoption"
N "github.com/sagernet/sing/common/network"
mDNS "github.com/miekg/dns"
)
type LegacyListable[T any] []T
func (l *LegacyListable[T]) UnmarshalJSONContext(ctx context.Context, content []byte) error {
return (*badoption.Listable[T])(l).UnmarshalJSONContext(ctx, content)
}
func (l LegacyListable[T]) DescribeSchema(builder schema.Builder) (*schema.Node, error) {
elementNode, err := builder.Describe(reflect.TypeFor[T]())
if err != nil {
return nil, err
}
return &schema.Node{Type: "array", Items: elementNode}, nil
}
type NetworkList string
func (v *NetworkList) UnmarshalJSON(content []byte) error {

View file

@ -23,11 +23,11 @@ type WireGuardEndpointOptions struct {
}
type WireGuardPeer struct {
Address string `json:"address,omitempty"`
Port uint16 `json:"port,omitempty"`
PublicKey string `json:"public_key,omitempty"`
PreSharedKey string `json:"pre_shared_key,omitempty"`
AllowedIPs badoption.Listable[netip.Prefix] `json:"allowed_ips,omitempty"`
PersistentKeepaliveInterval uint16 `json:"persistent_keepalive_interval,omitempty"`
Reserved []uint8 `json:"reserved,omitempty"`
Address string `json:"address,omitempty"`
Port uint16 `json:"port,omitempty"`
PublicKey string `json:"public_key,omitempty"`
PreSharedKey string `json:"pre_shared_key,omitempty"`
AllowedIPs LegacyListable[netip.Prefix] `json:"allowed_ips,omitempty"`
PersistentKeepaliveInterval uint16 `json:"persistent_keepalive_interval,omitempty"`
Reserved []uint8 `json:"reserved,omitempty"`
}