diff --git a/common/dialer/default.go b/common/dialer/default.go index b8a0d5f4..fcc5e60e 100644 --- a/common/dialer/default.go +++ b/common/dialer/default.go @@ -3,6 +3,7 @@ package dialer import ( "context" "net" + "net/netip" "time" "github.com/sagernet/sing-box/adapter" @@ -102,7 +103,7 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi udpAddr4 string ) if options.Inet4BindAddress != nil { - bindAddr := options.Inet4BindAddress.Build() + bindAddr := options.Inet4BindAddress.Build(netip.IPv4Unspecified()) dialer4.LocalAddr = &net.TCPAddr{IP: bindAddr.AsSlice()} udpDialer4.LocalAddr = &net.UDPAddr{IP: bindAddr.AsSlice()} udpAddr4 = M.SocksaddrFrom(bindAddr, 0).String() @@ -113,7 +114,7 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi udpAddr6 string ) if options.Inet6BindAddress != nil { - bindAddr := options.Inet6BindAddress.Build() + bindAddr := options.Inet6BindAddress.Build(netip.IPv6Unspecified()) dialer6.LocalAddr = &net.TCPAddr{IP: bindAddr.AsSlice()} udpDialer6.LocalAddr = &net.UDPAddr{IP: bindAddr.AsSlice()} udpAddr6 = M.SocksaddrFrom(bindAddr, 0).String() diff --git a/common/listener/listener.go b/common/listener/listener.go index b42b0434..289f15c5 100644 --- a/common/listener/listener.go +++ b/common/listener/listener.go @@ -3,6 +3,7 @@ package listener import ( "context" "net" + "net/netip" "sync/atomic" "github.com/sagernet/sing-box/adapter" @@ -92,7 +93,7 @@ func (l *Listener) Start() error { if l.setSystemProxy { listenPort := M.SocksaddrFromNet(l.tcpListener.Addr()).Port var listenAddrString string - listenAddr := l.listenOptions.Listen.Build() + listenAddr := l.listenOptions.Listen.Build(netip.IPv4Unspecified()) if listenAddr.IsUnspecified() { listenAddrString = "127.0.0.1" } else { diff --git a/common/listener/listener_tcp.go b/common/listener/listener_tcp.go index 02cef3f0..646d4017 100644 --- a/common/listener/listener_tcp.go +++ b/common/listener/listener_tcp.go @@ -2,6 +2,7 @@ package listener import ( "net" + "net/netip" "time" "github.com/sagernet/sing-box/adapter" @@ -16,7 +17,7 @@ import ( func (l *Listener) ListenTCP() (net.Listener, error) { var err error - bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(), l.listenOptions.ListenPort) + bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(netip.AddrFrom4([4]byte{127, 0, 0, 1})), l.listenOptions.ListenPort) var tcpListener net.Listener var listenConfig net.ListenConfig if l.listenOptions.TCPKeepAlive >= 0 { diff --git a/common/listener/listener_udp.go b/common/listener/listener_udp.go index d871c672..9be23213 100644 --- a/common/listener/listener_udp.go +++ b/common/listener/listener_udp.go @@ -2,6 +2,7 @@ package listener import ( "net" + "net/netip" "os" "time" @@ -13,7 +14,7 @@ import ( ) func (l *Listener) ListenUDP() (net.PacketConn, error) { - bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(), l.listenOptions.ListenPort) + bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(netip.AddrFrom4([4]byte{127, 0, 0, 1})), l.listenOptions.ListenPort) var lc net.ListenConfig var udpFragment bool if l.listenOptions.UDPFragment != nil { diff --git a/experimental/deprecated/manager.go b/experimental/deprecated/manager.go index d7cae179..d12acf48 100644 --- a/experimental/deprecated/manager.go +++ b/experimental/deprecated/manager.go @@ -2,6 +2,7 @@ package deprecated import ( "context" + "github.com/sagernet/sing/service" ) diff --git a/option/dns.go b/option/dns.go index be947583..32c1ac2e 100644 --- a/option/dns.go +++ b/option/dns.go @@ -1,6 +1,10 @@ package option -import "net/netip" +import ( + "net/netip" + + "github.com/sagernet/sing/common/json/badoption" +) type DNSOptions struct { Servers []DNSServerOptions `json:"servers,omitempty"` @@ -12,22 +16,22 @@ type DNSOptions struct { } type DNSServerOptions struct { - Tag string `json:"tag,omitempty"` - Address string `json:"address"` - AddressResolver string `json:"address_resolver,omitempty"` - AddressStrategy DomainStrategy `json:"address_strategy,omitempty"` - AddressFallbackDelay Duration `json:"address_fallback_delay,omitempty"` - Strategy DomainStrategy `json:"strategy,omitempty"` - Detour string `json:"detour,omitempty"` - ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"` + Tag string `json:"tag,omitempty"` + Address string `json:"address"` + AddressResolver string `json:"address_resolver,omitempty"` + AddressStrategy DomainStrategy `json:"address_strategy,omitempty"` + AddressFallbackDelay badoption.Duration `json:"address_fallback_delay,omitempty"` + Strategy DomainStrategy `json:"strategy,omitempty"` + Detour string `json:"detour,omitempty"` + ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"` } type DNSClientOptions struct { - Strategy DomainStrategy `json:"strategy,omitempty"` - DisableCache bool `json:"disable_cache,omitempty"` - DisableExpire bool `json:"disable_expire,omitempty"` - IndependentCache bool `json:"independent_cache,omitempty"` - ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"` + Strategy DomainStrategy `json:"strategy,omitempty"` + DisableCache bool `json:"disable_cache,omitempty"` + DisableExpire bool `json:"disable_expire,omitempty"` + IndependentCache bool `json:"independent_cache,omitempty"` + ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"` } type DNSFakeIPOptions struct { diff --git a/option/experimental.go b/option/experimental.go index 6ab66385..bf0df9e7 100644 --- a/option/experimental.go +++ b/option/experimental.go @@ -1,5 +1,7 @@ package option +import "github.com/sagernet/sing/common/json/badoption" + type ExperimentalOptions struct { CacheFile *CacheFileOptions `json:"cache_file,omitempty"` ClashAPI *ClashAPIOptions `json:"clash_api,omitempty"` @@ -8,24 +10,24 @@ type ExperimentalOptions struct { } type CacheFileOptions struct { - Enabled bool `json:"enabled,omitempty"` - Path string `json:"path,omitempty"` - CacheID string `json:"cache_id,omitempty"` - StoreFakeIP bool `json:"store_fakeip,omitempty"` - StoreRDRC bool `json:"store_rdrc,omitempty"` - RDRCTimeout Duration `json:"rdrc_timeout,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Path string `json:"path,omitempty"` + CacheID string `json:"cache_id,omitempty"` + StoreFakeIP bool `json:"store_fakeip,omitempty"` + StoreRDRC bool `json:"store_rdrc,omitempty"` + RDRCTimeout badoption.Duration `json:"rdrc_timeout,omitempty"` } type ClashAPIOptions struct { - ExternalController string `json:"external_controller,omitempty"` - ExternalUI string `json:"external_ui,omitempty"` - ExternalUIDownloadURL string `json:"external_ui_download_url,omitempty"` - ExternalUIDownloadDetour string `json:"external_ui_download_detour,omitempty"` - Secret string `json:"secret,omitempty"` - DefaultMode string `json:"default_mode,omitempty"` - ModeList []string `json:"-"` - AccessControlAllowOrigin Listable[string] `json:"access_control_allow_origin,omitempty"` - AccessControlAllowPrivateNetwork bool `json:"access_control_allow_private_network,omitempty"` + ExternalController string `json:"external_controller,omitempty"` + ExternalUI string `json:"external_ui,omitempty"` + ExternalUIDownloadURL string `json:"external_ui_download_url,omitempty"` + ExternalUIDownloadDetour string `json:"external_ui_download_detour,omitempty"` + Secret string `json:"secret,omitempty"` + DefaultMode string `json:"default_mode,omitempty"` + ModeList []string `json:"-"` + AccessControlAllowOrigin badoption.Listable[string] `json:"access_control_allow_origin,omitempty"` + AccessControlAllowPrivateNetwork bool `json:"access_control_allow_private_network,omitempty"` // Deprecated: migrated to global cache file CacheFile string `json:"cache_file,omitempty"` diff --git a/option/group.go b/option/group.go index 72a0f637..02b3a5ec 100644 --- a/option/group.go +++ b/option/group.go @@ -1,5 +1,7 @@ package option +import "github.com/sagernet/sing/common/json/badoption" + type SelectorOutboundOptions struct { Outbounds []string `json:"outbounds"` Default string `json:"default,omitempty"` @@ -7,10 +9,10 @@ type SelectorOutboundOptions struct { } type URLTestOutboundOptions struct { - Outbounds []string `json:"outbounds"` - URL string `json:"url,omitempty"` - Interval Duration `json:"interval,omitempty"` - Tolerance uint16 `json:"tolerance,omitempty"` - IdleTimeout Duration `json:"idle_timeout,omitempty"` - InterruptExistConnections bool `json:"interrupt_exist_connections,omitempty"` + Outbounds []string `json:"outbounds"` + URL string `json:"url,omitempty"` + Interval badoption.Duration `json:"interval,omitempty"` + Tolerance uint16 `json:"tolerance,omitempty"` + IdleTimeout badoption.Duration `json:"idle_timeout,omitempty"` + InterruptExistConnections bool `json:"interrupt_exist_connections,omitempty"` } diff --git a/option/inbound.go b/option/inbound.go index 651d0284..a67719fa 100644 --- a/option/inbound.go +++ b/option/inbound.go @@ -7,6 +7,7 @@ import ( E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badjson" + "github.com/sagernet/sing/common/json/badoption" "github.com/sagernet/sing/service" ) @@ -49,24 +50,24 @@ func (h *Inbound) UnmarshalJSONContext(ctx context.Context, content []byte) erro // Deprecated: Use rule action instead type InboundOptions struct { - SniffEnabled bool `json:"sniff,omitempty"` - SniffOverrideDestination bool `json:"sniff_override_destination,omitempty"` - SniffTimeout Duration `json:"sniff_timeout,omitempty"` - DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"` - UDPDisableDomainUnmapping bool `json:"udp_disable_domain_unmapping,omitempty"` - Detour string `json:"detour,omitempty"` + SniffEnabled bool `json:"sniff,omitempty"` + SniffOverrideDestination bool `json:"sniff_override_destination,omitempty"` + SniffTimeout badoption.Duration `json:"sniff_timeout,omitempty"` + DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"` + UDPDisableDomainUnmapping bool `json:"udp_disable_domain_unmapping,omitempty"` + Detour string `json:"detour,omitempty"` } type ListenOptions struct { - Listen *ListenAddress `json:"listen,omitempty"` - ListenPort uint16 `json:"listen_port,omitempty"` - TCPKeepAlive Duration `json:"tcp_keep_alive,omitempty"` - TCPKeepAliveInterval Duration `json:"tcp_keep_alive_interval,omitempty"` - TCPFastOpen bool `json:"tcp_fast_open,omitempty"` - TCPMultiPath bool `json:"tcp_multi_path,omitempty"` - UDPFragment *bool `json:"udp_fragment,omitempty"` - UDPFragmentDefault bool `json:"-"` - UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"` + Listen *badoption.Addr `json:"listen,omitempty"` + ListenPort uint16 `json:"listen_port,omitempty"` + TCPKeepAlive badoption.Duration `json:"tcp_keep_alive,omitempty"` + TCPKeepAliveInterval badoption.Duration `json:"tcp_keep_alive_interval,omitempty"` + TCPFastOpen bool `json:"tcp_fast_open,omitempty"` + TCPMultiPath bool `json:"tcp_multi_path,omitempty"` + UDPFragment *bool `json:"udp_fragment,omitempty"` + UDPFragmentDefault bool `json:"-"` + UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"` // Deprecated: removed ProxyProtocol bool `json:"proxy_protocol,omitempty"` @@ -75,7 +76,7 @@ type ListenOptions struct { InboundOptions } -type UDPTimeoutCompat Duration +type UDPTimeoutCompat badoption.Duration func (c UDPTimeoutCompat) MarshalJSON() ([]byte, error) { return json.Marshal((time.Duration)(c).String()) @@ -88,7 +89,7 @@ func (c *UDPTimeoutCompat) UnmarshalJSON(data []byte) error { *c = UDPTimeoutCompat(time.Second * time.Duration(valueNumber)) return nil } - return json.Unmarshal(data, (*Duration)(c)) + return json.Unmarshal(data, (*badoption.Duration)(c)) } type ListenOptionsWrapper interface { diff --git a/option/ntp.go b/option/ntp.go index 0bd2489a..d441d95e 100644 --- a/option/ntp.go +++ b/option/ntp.go @@ -1,9 +1,11 @@ package option +import "github.com/sagernet/sing/common/json/badoption" + type NTPOptions struct { - Enabled bool `json:"enabled,omitempty"` - Interval Duration `json:"interval,omitempty"` - WriteToSystem bool `json:"write_to_system,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Interval badoption.Duration `json:"interval,omitempty"` + WriteToSystem bool `json:"write_to_system,omitempty"` ServerOptions DialerOptions } diff --git a/option/outbound.go b/option/outbound.go index 1dddb354..0e2d5874 100644 --- a/option/outbound.go +++ b/option/outbound.go @@ -8,6 +8,7 @@ import ( E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badjson" + "github.com/sagernet/sing/common/json/badoption" M "github.com/sagernet/sing/common/metadata" "github.com/sagernet/sing/service" ) @@ -64,21 +65,21 @@ type DialerOptionsWrapper interface { } type DialerOptions struct { - Detour string `json:"detour,omitempty"` - BindInterface string `json:"bind_interface,omitempty"` - Inet4BindAddress *ListenAddress `json:"inet4_bind_address,omitempty"` - Inet6BindAddress *ListenAddress `json:"inet6_bind_address,omitempty"` - ProtectPath string `json:"protect_path,omitempty"` - RoutingMark uint32 `json:"routing_mark,omitempty"` - ReuseAddr bool `json:"reuse_addr,omitempty"` - ConnectTimeout Duration `json:"connect_timeout,omitempty"` - TCPFastOpen bool `json:"tcp_fast_open,omitempty"` - TCPMultiPath bool `json:"tcp_multi_path,omitempty"` - UDPFragment *bool `json:"udp_fragment,omitempty"` - UDPFragmentDefault bool `json:"-"` - DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"` - FallbackDelay Duration `json:"fallback_delay,omitempty"` - IsWireGuardListener bool `json:"-"` + Detour string `json:"detour,omitempty"` + BindInterface string `json:"bind_interface,omitempty"` + Inet4BindAddress *badoption.Addr `json:"inet4_bind_address,omitempty"` + Inet6BindAddress *badoption.Addr `json:"inet6_bind_address,omitempty"` + ProtectPath string `json:"protect_path,omitempty"` + RoutingMark uint32 `json:"routing_mark,omitempty"` + ReuseAddr bool `json:"reuse_addr,omitempty"` + ConnectTimeout badoption.Duration `json:"connect_timeout,omitempty"` + TCPFastOpen bool `json:"tcp_fast_open,omitempty"` + TCPMultiPath bool `json:"tcp_multi_path,omitempty"` + UDPFragment *bool `json:"udp_fragment,omitempty"` + UDPFragmentDefault bool `json:"-"` + DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"` + FallbackDelay badoption.Duration `json:"fallback_delay,omitempty"` + IsWireGuardListener bool `json:"-"` } func (o *DialerOptions) TakeDialerOptions() DialerOptions { diff --git a/option/platform.go b/option/platform.go index a43cbf23..e4ecd6fa 100644 --- a/option/platform.go +++ b/option/platform.go @@ -3,6 +3,7 @@ package option import ( E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" + "github.com/sagernet/sing/common/json/badoption" ) type OnDemandOptions struct { @@ -12,10 +13,10 @@ type OnDemandOptions struct { type OnDemandRule struct { Action *OnDemandRuleAction `json:"action,omitempty"` - DNSSearchDomainMatch Listable[string] `json:"dns_search_domain_match,omitempty"` - DNSServerAddressMatch Listable[string] `json:"dns_server_address_match,omitempty"` + DNSSearchDomainMatch badoption.Listable[string] `json:"dns_search_domain_match,omitempty"` + DNSServerAddressMatch badoption.Listable[string] `json:"dns_server_address_match,omitempty"` InterfaceTypeMatch *OnDemandRuleInterfaceType `json:"interface_type_match,omitempty"` - SSIDMatch Listable[string] `json:"ssid_match,omitempty"` + SSIDMatch badoption.Listable[string] `json:"ssid_match,omitempty"` ProbeURL string `json:"probe_url,omitempty"` } diff --git a/option/rule.go b/option/rule.go index 952afa61..d5ff9925 100644 --- a/option/rule.go +++ b/option/rule.go @@ -8,6 +8,7 @@ import ( E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badjson" + "github.com/sagernet/sing/common/json/badoption" ) type _Rule struct { @@ -66,39 +67,39 @@ func (r Rule) IsValid() bool { } type RawDefaultRule struct { - Inbound Listable[string] `json:"inbound,omitempty"` - IPVersion int `json:"ip_version,omitempty"` - Network Listable[string] `json:"network,omitempty"` - AuthUser Listable[string] `json:"auth_user,omitempty"` - Protocol Listable[string] `json:"protocol,omitempty"` - Client Listable[string] `json:"client,omitempty"` - Domain Listable[string] `json:"domain,omitempty"` - DomainSuffix Listable[string] `json:"domain_suffix,omitempty"` - DomainKeyword Listable[string] `json:"domain_keyword,omitempty"` - DomainRegex Listable[string] `json:"domain_regex,omitempty"` - Geosite Listable[string] `json:"geosite,omitempty"` - SourceGeoIP Listable[string] `json:"source_geoip,omitempty"` - GeoIP Listable[string] `json:"geoip,omitempty"` - SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"` - SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"` - IPCIDR Listable[string] `json:"ip_cidr,omitempty"` - IPIsPrivate bool `json:"ip_is_private,omitempty"` - SourcePort Listable[uint16] `json:"source_port,omitempty"` - SourcePortRange Listable[string] `json:"source_port_range,omitempty"` - Port Listable[uint16] `json:"port,omitempty"` - PortRange Listable[string] `json:"port_range,omitempty"` - ProcessName Listable[string] `json:"process_name,omitempty"` - ProcessPath Listable[string] `json:"process_path,omitempty"` - ProcessPathRegex Listable[string] `json:"process_path_regex,omitempty"` - PackageName Listable[string] `json:"package_name,omitempty"` - User Listable[string] `json:"user,omitempty"` - UserID Listable[int32] `json:"user_id,omitempty"` - ClashMode string `json:"clash_mode,omitempty"` - WIFISSID Listable[string] `json:"wifi_ssid,omitempty"` - WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"` - RuleSet Listable[string] `json:"rule_set,omitempty"` - RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"` - Invert bool `json:"invert,omitempty"` + Inbound badoption.Listable[string] `json:"inbound,omitempty"` + IPVersion int `json:"ip_version,omitempty"` + Network badoption.Listable[string] `json:"network,omitempty"` + AuthUser badoption.Listable[string] `json:"auth_user,omitempty"` + Protocol badoption.Listable[string] `json:"protocol,omitempty"` + Client badoption.Listable[string] `json:"client,omitempty"` + Domain badoption.Listable[string] `json:"domain,omitempty"` + DomainSuffix badoption.Listable[string] `json:"domain_suffix,omitempty"` + DomainKeyword badoption.Listable[string] `json:"domain_keyword,omitempty"` + DomainRegex badoption.Listable[string] `json:"domain_regex,omitempty"` + Geosite badoption.Listable[string] `json:"geosite,omitempty"` + SourceGeoIP badoption.Listable[string] `json:"source_geoip,omitempty"` + GeoIP badoption.Listable[string] `json:"geoip,omitempty"` + SourceIPCIDR badoption.Listable[string] `json:"source_ip_cidr,omitempty"` + SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"` + IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"` + IPIsPrivate bool `json:"ip_is_private,omitempty"` + SourcePort badoption.Listable[uint16] `json:"source_port,omitempty"` + SourcePortRange badoption.Listable[string] `json:"source_port_range,omitempty"` + Port badoption.Listable[uint16] `json:"port,omitempty"` + PortRange badoption.Listable[string] `json:"port_range,omitempty"` + ProcessName badoption.Listable[string] `json:"process_name,omitempty"` + ProcessPath badoption.Listable[string] `json:"process_path,omitempty"` + ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"` + PackageName badoption.Listable[string] `json:"package_name,omitempty"` + User badoption.Listable[string] `json:"user,omitempty"` + UserID badoption.Listable[int32] `json:"user_id,omitempty"` + ClashMode string `json:"clash_mode,omitempty"` + WIFISSID badoption.Listable[string] `json:"wifi_ssid,omitempty"` + WIFIBSSID badoption.Listable[string] `json:"wifi_bssid,omitempty"` + RuleSet badoption.Listable[string] `json:"rule_set,omitempty"` + RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"` + Invert bool `json:"invert,omitempty"` // Deprecated: renamed to rule_set_ip_cidr_match_source Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"` diff --git a/option/rule_action.go b/option/rule_action.go index a7244e17..7a76391c 100644 --- a/option/rule_action.go +++ b/option/rule_action.go @@ -3,6 +3,7 @@ package option import ( "context" "fmt" + "net/netip" "time" C "github.com/sagernet/sing-box/constant" @@ -11,6 +12,7 @@ import ( E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badjson" + "github.com/sagernet/sing/common/json/badoption" ) type _RuleAction struct { @@ -177,7 +179,7 @@ type _DNSRouteActionOptions struct { // Deprecated: Use DNSRouteOptionsActionOptions instead. RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"` // Deprecated: Use DNSRouteOptionsActionOptions instead. - ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"` + ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"` } type DNSRouteActionOptions _DNSRouteActionOptions @@ -197,9 +199,9 @@ func (r *DNSRouteActionOptions) UnmarshalJSONContext(ctx context.Context, data [ } type _DNSRouteOptionsActionOptions struct { - DisableCache bool `json:"disable_cache,omitempty"` - RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"` - ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"` + DisableCache bool `json:"disable_cache,omitempty"` + RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"` + ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"` } type DNSRouteOptionsActionOptions _DNSRouteOptionsActionOptions @@ -225,10 +227,10 @@ func (d DirectActionOptions) Descriptions() []string { descriptions = append(descriptions, "bind_interface="+d.BindInterface) } if d.Inet4BindAddress != nil { - descriptions = append(descriptions, "inet4_bind_address="+d.Inet4BindAddress.Build().String()) + descriptions = append(descriptions, "inet4_bind_address="+d.Inet4BindAddress.Build(netip.IPv4Unspecified()).String()) } if d.Inet6BindAddress != nil { - descriptions = append(descriptions, "inet6_bind_address="+d.Inet6BindAddress.Build().String()) + descriptions = append(descriptions, "inet6_bind_address="+d.Inet6BindAddress.Build(netip.IPv6Unspecified()).String()) } if d.RoutingMark != 0 { descriptions = append(descriptions, "routing_mark="+fmt.Sprintf("0x%x", d.RoutingMark)) @@ -294,8 +296,8 @@ func (r *RejectActionOptions) UnmarshalJSON(bytes []byte) error { } type RouteActionSniff struct { - Sniffer Listable[string] `json:"sniffer,omitempty"` - Timeout Duration `json:"timeout,omitempty"` + Sniffer badoption.Listable[string] `json:"sniffer,omitempty"` + Timeout badoption.Duration `json:"timeout,omitempty"` } type RouteActionResolve struct { diff --git a/option/rule_dns.go b/option/rule_dns.go index 894e95d3..e758488b 100644 --- a/option/rule_dns.go +++ b/option/rule_dns.go @@ -9,6 +9,7 @@ import ( E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badjson" + "github.com/sagernet/sing/common/json/badoption" ) type _DNSRule struct { @@ -67,41 +68,41 @@ func (r DNSRule) IsValid() bool { } type RawDefaultDNSRule struct { - Inbound Listable[string] `json:"inbound,omitempty"` - IPVersion int `json:"ip_version,omitempty"` - QueryType Listable[DNSQueryType] `json:"query_type,omitempty"` - Network Listable[string] `json:"network,omitempty"` - AuthUser Listable[string] `json:"auth_user,omitempty"` - Protocol Listable[string] `json:"protocol,omitempty"` - Domain Listable[string] `json:"domain,omitempty"` - DomainSuffix Listable[string] `json:"domain_suffix,omitempty"` - DomainKeyword Listable[string] `json:"domain_keyword,omitempty"` - DomainRegex Listable[string] `json:"domain_regex,omitempty"` - Geosite Listable[string] `json:"geosite,omitempty"` - SourceGeoIP Listable[string] `json:"source_geoip,omitempty"` - GeoIP Listable[string] `json:"geoip,omitempty"` - IPCIDR Listable[string] `json:"ip_cidr,omitempty"` - IPIsPrivate bool `json:"ip_is_private,omitempty"` - SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"` - SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"` - SourcePort Listable[uint16] `json:"source_port,omitempty"` - SourcePortRange Listable[string] `json:"source_port_range,omitempty"` - Port Listable[uint16] `json:"port,omitempty"` - PortRange Listable[string] `json:"port_range,omitempty"` - ProcessName Listable[string] `json:"process_name,omitempty"` - ProcessPath Listable[string] `json:"process_path,omitempty"` - ProcessPathRegex Listable[string] `json:"process_path_regex,omitempty"` - PackageName Listable[string] `json:"package_name,omitempty"` - User Listable[string] `json:"user,omitempty"` - UserID Listable[int32] `json:"user_id,omitempty"` - Outbound Listable[string] `json:"outbound,omitempty"` - ClashMode string `json:"clash_mode,omitempty"` - WIFISSID Listable[string] `json:"wifi_ssid,omitempty"` - WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"` - RuleSet Listable[string] `json:"rule_set,omitempty"` - RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"` - RuleSetIPCIDRAcceptEmpty bool `json:"rule_set_ip_cidr_accept_empty,omitempty"` - Invert bool `json:"invert,omitempty"` + Inbound badoption.Listable[string] `json:"inbound,omitempty"` + IPVersion int `json:"ip_version,omitempty"` + QueryType badoption.Listable[DNSQueryType] `json:"query_type,omitempty"` + Network badoption.Listable[string] `json:"network,omitempty"` + AuthUser badoption.Listable[string] `json:"auth_user,omitempty"` + Protocol badoption.Listable[string] `json:"protocol,omitempty"` + Domain badoption.Listable[string] `json:"domain,omitempty"` + DomainSuffix badoption.Listable[string] `json:"domain_suffix,omitempty"` + DomainKeyword badoption.Listable[string] `json:"domain_keyword,omitempty"` + DomainRegex badoption.Listable[string] `json:"domain_regex,omitempty"` + Geosite badoption.Listable[string] `json:"geosite,omitempty"` + SourceGeoIP badoption.Listable[string] `json:"source_geoip,omitempty"` + GeoIP badoption.Listable[string] `json:"geoip,omitempty"` + IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"` + IPIsPrivate bool `json:"ip_is_private,omitempty"` + SourceIPCIDR badoption.Listable[string] `json:"source_ip_cidr,omitempty"` + SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"` + SourcePort badoption.Listable[uint16] `json:"source_port,omitempty"` + SourcePortRange badoption.Listable[string] `json:"source_port_range,omitempty"` + Port badoption.Listable[uint16] `json:"port,omitempty"` + PortRange badoption.Listable[string] `json:"port_range,omitempty"` + ProcessName badoption.Listable[string] `json:"process_name,omitempty"` + ProcessPath badoption.Listable[string] `json:"process_path,omitempty"` + ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"` + PackageName badoption.Listable[string] `json:"package_name,omitempty"` + User badoption.Listable[string] `json:"user,omitempty"` + UserID badoption.Listable[int32] `json:"user_id,omitempty"` + Outbound badoption.Listable[string] `json:"outbound,omitempty"` + ClashMode string `json:"clash_mode,omitempty"` + WIFISSID badoption.Listable[string] `json:"wifi_ssid,omitempty"` + WIFIBSSID badoption.Listable[string] `json:"wifi_bssid,omitempty"` + RuleSet badoption.Listable[string] `json:"rule_set,omitempty"` + RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"` + RuleSetIPCIDRAcceptEmpty bool `json:"rule_set_ip_cidr_accept_empty,omitempty"` + Invert bool `json:"invert,omitempty"` // Deprecated: renamed to rule_set_ip_cidr_match_source Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"` diff --git a/option/rule_set.go b/option/rule_set.go index 358821de..f0d96bb6 100644 --- a/option/rule_set.go +++ b/option/rule_set.go @@ -10,6 +10,7 @@ import ( F "github.com/sagernet/sing/common/format" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badjson" + "github.com/sagernet/sing/common/json/badoption" "go4.org/netipx" ) @@ -84,9 +85,9 @@ type LocalRuleSet struct { } type RemoteRuleSet struct { - URL string `json:"url"` - DownloadDetour string `json:"download_detour,omitempty"` - UpdateInterval Duration `json:"update_interval,omitempty"` + URL string `json:"url"` + DownloadDetour string `json:"download_detour,omitempty"` + UpdateInterval badoption.Duration `json:"update_interval,omitempty"` } type _HeadlessRule struct { @@ -145,32 +146,32 @@ func (r HeadlessRule) IsValid() bool { } type DefaultHeadlessRule struct { - QueryType Listable[DNSQueryType] `json:"query_type,omitempty"` - Network Listable[string] `json:"network,omitempty"` - Domain Listable[string] `json:"domain,omitempty"` - DomainSuffix Listable[string] `json:"domain_suffix,omitempty"` - DomainKeyword Listable[string] `json:"domain_keyword,omitempty"` - DomainRegex Listable[string] `json:"domain_regex,omitempty"` - SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"` - IPCIDR Listable[string] `json:"ip_cidr,omitempty"` - SourcePort Listable[uint16] `json:"source_port,omitempty"` - SourcePortRange Listable[string] `json:"source_port_range,omitempty"` - Port Listable[uint16] `json:"port,omitempty"` - PortRange Listable[string] `json:"port_range,omitempty"` - ProcessName Listable[string] `json:"process_name,omitempty"` - ProcessPath Listable[string] `json:"process_path,omitempty"` - ProcessPathRegex Listable[string] `json:"process_path_regex,omitempty"` - PackageName Listable[string] `json:"package_name,omitempty"` - WIFISSID Listable[string] `json:"wifi_ssid,omitempty"` - WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"` - Invert bool `json:"invert,omitempty"` + QueryType badoption.Listable[DNSQueryType] `json:"query_type,omitempty"` + Network badoption.Listable[string] `json:"network,omitempty"` + Domain badoption.Listable[string] `json:"domain,omitempty"` + DomainSuffix badoption.Listable[string] `json:"domain_suffix,omitempty"` + DomainKeyword badoption.Listable[string] `json:"domain_keyword,omitempty"` + DomainRegex badoption.Listable[string] `json:"domain_regex,omitempty"` + SourceIPCIDR badoption.Listable[string] `json:"source_ip_cidr,omitempty"` + IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"` + SourcePort badoption.Listable[uint16] `json:"source_port,omitempty"` + SourcePortRange badoption.Listable[string] `json:"source_port_range,omitempty"` + Port badoption.Listable[uint16] `json:"port,omitempty"` + PortRange badoption.Listable[string] `json:"port_range,omitempty"` + ProcessName badoption.Listable[string] `json:"process_name,omitempty"` + ProcessPath badoption.Listable[string] `json:"process_path,omitempty"` + ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"` + PackageName badoption.Listable[string] `json:"package_name,omitempty"` + WIFISSID badoption.Listable[string] `json:"wifi_ssid,omitempty"` + WIFIBSSID badoption.Listable[string] `json:"wifi_bssid,omitempty"` + Invert bool `json:"invert,omitempty"` DomainMatcher *domain.Matcher `json:"-"` SourceIPSet *netipx.IPSet `json:"-"` IPSet *netipx.IPSet `json:"-"` - AdGuardDomain Listable[string] `json:"-"` - AdGuardDomainMatcher *domain.AdGuardMatcher `json:"-"` + AdGuardDomain badoption.Listable[string] `json:"-"` + AdGuardDomainMatcher *domain.AdGuardMatcher `json:"-"` } func (r DefaultHeadlessRule) IsValid() bool { diff --git a/option/simple.go b/option/simple.go index 78171ce4..5fda30ef 100644 --- a/option/simple.go +++ b/option/simple.go @@ -1,6 +1,9 @@ package option -import "github.com/sagernet/sing/common/auth" +import ( + "github.com/sagernet/sing/common/auth" + "github.com/sagernet/sing/common/json/badoption" +) type SocksInboundOptions struct { ListenOptions @@ -30,6 +33,6 @@ type HTTPOutboundOptions struct { Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` OutboundTLSOptionsContainer - Path string `json:"path,omitempty"` - Headers HTTPHeader `json:"headers,omitempty"` + Path string `json:"path,omitempty"` + Headers badoption.HTTPHeader `json:"headers,omitempty"` } diff --git a/option/ssh.go b/option/ssh.go index d0bfbf74..1c6ca6bb 100644 --- a/option/ssh.go +++ b/option/ssh.go @@ -1,14 +1,16 @@ package option +import "github.com/sagernet/sing/common/json/badoption" + type SSHOutboundOptions struct { DialerOptions ServerOptions - User string `json:"user,omitempty"` - Password string `json:"password,omitempty"` - PrivateKey Listable[string] `json:"private_key,omitempty"` - PrivateKeyPath string `json:"private_key_path,omitempty"` - PrivateKeyPassphrase string `json:"private_key_passphrase,omitempty"` - HostKey Listable[string] `json:"host_key,omitempty"` - HostKeyAlgorithms Listable[string] `json:"host_key_algorithms,omitempty"` - ClientVersion string `json:"client_version,omitempty"` + User string `json:"user,omitempty"` + Password string `json:"password,omitempty"` + PrivateKey badoption.Listable[string] `json:"private_key,omitempty"` + 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"` + ClientVersion string `json:"client_version,omitempty"` } diff --git a/option/time_unit.go b/option/time_unit.go deleted file mode 100644 index 5e531dad..00000000 --- a/option/time_unit.go +++ /dev/null @@ -1,226 +0,0 @@ -package option - -import ( - "errors" - "time" -) - -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -const durationDay = 24 * time.Hour - -var unitMap = map[string]uint64{ - "ns": uint64(time.Nanosecond), - "us": uint64(time.Microsecond), - "µs": uint64(time.Microsecond), // U+00B5 = micro symbol - "μs": uint64(time.Microsecond), // U+03BC = Greek letter mu - "ms": uint64(time.Millisecond), - "s": uint64(time.Second), - "m": uint64(time.Minute), - "h": uint64(time.Hour), - "d": uint64(durationDay), -} - -// ParseDuration parses a duration string. -// A duration string is a possibly signed sequence of -// decimal numbers, each with optional fraction and a unit suffix, -// such as "300ms", "-1.5h" or "2h45m". -// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". -func ParseDuration(s string) (Duration, error) { - // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+ - orig := s - var d uint64 - neg := false - - // Consume [-+]? - if s != "" { - c := s[0] - if c == '-' || c == '+' { - neg = c == '-' - s = s[1:] - } - } - // Special case: if all that is left is "0", this is zero. - if s == "0" { - return 0, nil - } - if s == "" { - return 0, errors.New("time: invalid duration " + quote(orig)) - } - for s != "" { - var ( - v, f uint64 // integers before, after decimal point - scale float64 = 1 // value = v + f/scale - ) - - var err error - - // The next character must be [0-9.] - if !(s[0] == '.' || '0' <= s[0] && s[0] <= '9') { - return 0, errors.New("time: invalid duration " + quote(orig)) - } - // Consume [0-9]* - pl := len(s) - v, s, err = leadingInt(s) - if err != nil { - return 0, errors.New("time: invalid duration " + quote(orig)) - } - pre := pl != len(s) // whether we consumed anything before a period - - // Consume (\.[0-9]*)? - post := false - if s != "" && s[0] == '.' { - s = s[1:] - pl := len(s) - f, scale, s = leadingFraction(s) - post = pl != len(s) - } - if !pre && !post { - // no digits (e.g. ".s" or "-.s") - return 0, errors.New("time: invalid duration " + quote(orig)) - } - - // Consume unit. - i := 0 - for ; i < len(s); i++ { - c := s[i] - if c == '.' || '0' <= c && c <= '9' { - break - } - } - if i == 0 { - return 0, errors.New("time: missing unit in duration " + quote(orig)) - } - u := s[:i] - s = s[i:] - unit, ok := unitMap[u] - if !ok { - return 0, errors.New("time: unknown unit " + quote(u) + " in duration " + quote(orig)) - } - if v > 1<<63/unit { - // overflow - return 0, errors.New("time: invalid duration " + quote(orig)) - } - v *= unit - if f > 0 { - // float64 is needed to be nanosecond accurate for fractions of hours. - // v >= 0 && (f*unit/scale) <= 3.6e+12 (ns/h, h is the largest unit) - v += uint64(float64(f) * (float64(unit) / scale)) - if v > 1<<63 { - // overflow - return 0, errors.New("time: invalid duration " + quote(orig)) - } - } - d += v - if d > 1<<63 { - return 0, errors.New("time: invalid duration " + quote(orig)) - } - } - if neg { - return -Duration(d), nil - } - if d > 1<<63-1 { - return 0, errors.New("time: invalid duration " + quote(orig)) - } - return Duration(d), nil -} - -var errLeadingInt = errors.New("time: bad [0-9]*") // never printed - -// leadingInt consumes the leading [0-9]* from s. -func leadingInt[bytes []byte | string](s bytes) (x uint64, rem bytes, err error) { - i := 0 - for ; i < len(s); i++ { - c := s[i] - if c < '0' || c > '9' { - break - } - if x > 1<<63/10 { - // overflow - return 0, rem, errLeadingInt - } - x = x*10 + uint64(c) - '0' - if x > 1<<63 { - // overflow - return 0, rem, errLeadingInt - } - } - return x, s[i:], nil -} - -// leadingFraction consumes the leading [0-9]* from s. -// It is used only for fractions, so does not return an error on overflow, -// it just stops accumulating precision. -func leadingFraction(s string) (x uint64, scale float64, rem string) { - i := 0 - scale = 1 - overflow := false - for ; i < len(s); i++ { - c := s[i] - if c < '0' || c > '9' { - break - } - if overflow { - continue - } - if x > (1<<63-1)/10 { - // It's possible for overflow to give a positive number, so take care. - overflow = true - continue - } - y := x*10 + uint64(c) - '0' - if y > 1<<63 { - overflow = true - continue - } - x = y - scale *= 10 - } - return x, scale, s[i:] -} - -// These are borrowed from unicode/utf8 and strconv and replicate behavior in -// that package, since we can't take a dependency on either. -const ( - lowerhex = "0123456789abcdef" - runeSelf = 0x80 - runeError = '\uFFFD' -) - -func quote(s string) string { - buf := make([]byte, 1, len(s)+2) // slice will be at least len(s) + quotes - buf[0] = '"' - for i, c := range s { - if c >= runeSelf || c < ' ' { - // This means you are asking us to parse a time.Duration or - // time.Location with unprintable or non-ASCII characters in it. - // We don't expect to hit this case very often. We could try to - // reproduce strconv.Quote's behavior with full fidelity but - // given how rarely we expect to hit these edge cases, speed and - // conciseness are better. - var width int - if c == runeError { - width = 1 - if i+2 < len(s) && s[i:i+3] == string(runeError) { - width = 3 - } - } else { - width = len(string(c)) - } - for j := 0; j < width; j++ { - buf = append(buf, `\x`...) - buf = append(buf, lowerhex[s[i+j]>>4]) - buf = append(buf, lowerhex[s[i+j]&0xF]) - } - } else { - if c == '"' || c == '\\' { - buf = append(buf, '\\') - } - buf = append(buf, string(c)...) - } - } - buf = append(buf, '"') - return string(buf) -} diff --git a/option/tls.go b/option/tls.go index 3680afe0..72aaaef1 100644 --- a/option/tls.go +++ b/option/tls.go @@ -1,20 +1,22 @@ package option +import "github.com/sagernet/sing/common/json/badoption" + type InboundTLSOptions struct { - Enabled bool `json:"enabled,omitempty"` - ServerName string `json:"server_name,omitempty"` - Insecure bool `json:"insecure,omitempty"` - ALPN Listable[string] `json:"alpn,omitempty"` - MinVersion string `json:"min_version,omitempty"` - MaxVersion string `json:"max_version,omitempty"` - CipherSuites Listable[string] `json:"cipher_suites,omitempty"` - Certificate Listable[string] `json:"certificate,omitempty"` - CertificatePath string `json:"certificate_path,omitempty"` - Key Listable[string] `json:"key,omitempty"` - KeyPath string `json:"key_path,omitempty"` - ACME *InboundACMEOptions `json:"acme,omitempty"` - ECH *InboundECHOptions `json:"ech,omitempty"` - Reality *InboundRealityOptions `json:"reality,omitempty"` + Enabled bool `json:"enabled,omitempty"` + ServerName string `json:"server_name,omitempty"` + Insecure bool `json:"insecure,omitempty"` + ALPN badoption.Listable[string] `json:"alpn,omitempty"` + MinVersion string `json:"min_version,omitempty"` + MaxVersion string `json:"max_version,omitempty"` + CipherSuites badoption.Listable[string] `json:"cipher_suites,omitempty"` + Certificate badoption.Listable[string] `json:"certificate,omitempty"` + CertificatePath string `json:"certificate_path,omitempty"` + Key badoption.Listable[string] `json:"key,omitempty"` + KeyPath string `json:"key_path,omitempty"` + ACME *InboundACMEOptions `json:"acme,omitempty"` + ECH *InboundECHOptions `json:"ech,omitempty"` + Reality *InboundRealityOptions `json:"reality,omitempty"` } type InboundTLSOptionsContainer struct { @@ -35,19 +37,19 @@ func (o *InboundTLSOptionsContainer) ReplaceInboundTLSOptions(options *InboundTL } type OutboundTLSOptions struct { - Enabled bool `json:"enabled,omitempty"` - DisableSNI bool `json:"disable_sni,omitempty"` - ServerName string `json:"server_name,omitempty"` - Insecure bool `json:"insecure,omitempty"` - ALPN Listable[string] `json:"alpn,omitempty"` - MinVersion string `json:"min_version,omitempty"` - MaxVersion string `json:"max_version,omitempty"` - CipherSuites Listable[string] `json:"cipher_suites,omitempty"` - Certificate Listable[string] `json:"certificate,omitempty"` - CertificatePath string `json:"certificate_path,omitempty"` - ECH *OutboundECHOptions `json:"ech,omitempty"` - UTLS *OutboundUTLSOptions `json:"utls,omitempty"` - Reality *OutboundRealityOptions `json:"reality,omitempty"` + Enabled bool `json:"enabled,omitempty"` + DisableSNI bool `json:"disable_sni,omitempty"` + ServerName string `json:"server_name,omitempty"` + Insecure bool `json:"insecure,omitempty"` + ALPN badoption.Listable[string] `json:"alpn,omitempty"` + MinVersion string `json:"min_version,omitempty"` + MaxVersion string `json:"max_version,omitempty"` + CipherSuites badoption.Listable[string] `json:"cipher_suites,omitempty"` + Certificate badoption.Listable[string] `json:"certificate,omitempty"` + CertificatePath string `json:"certificate_path,omitempty"` + ECH *OutboundECHOptions `json:"ech,omitempty"` + UTLS *OutboundUTLSOptions `json:"utls,omitempty"` + Reality *OutboundRealityOptions `json:"reality,omitempty"` } type OutboundTLSOptionsContainer struct { @@ -71,8 +73,8 @@ type InboundRealityOptions struct { Enabled bool `json:"enabled,omitempty"` Handshake InboundRealityHandshakeOptions `json:"handshake,omitempty"` PrivateKey string `json:"private_key,omitempty"` - ShortID Listable[string] `json:"short_id,omitempty"` - MaxTimeDifference Duration `json:"max_time_difference,omitempty"` + ShortID badoption.Listable[string] `json:"short_id,omitempty"` + MaxTimeDifference badoption.Duration `json:"max_time_difference,omitempty"` } type InboundRealityHandshakeOptions struct { @@ -81,19 +83,19 @@ type InboundRealityHandshakeOptions struct { } type InboundECHOptions struct { - Enabled bool `json:"enabled,omitempty"` - PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"` - DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"` - Key Listable[string] `json:"key,omitempty"` - KeyPath string `json:"key_path,omitempty"` + Enabled bool `json:"enabled,omitempty"` + PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"` + DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"` + Key badoption.Listable[string] `json:"key,omitempty"` + KeyPath string `json:"key_path,omitempty"` } type OutboundECHOptions struct { - Enabled bool `json:"enabled,omitempty"` - PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"` - DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"` - Config Listable[string] `json:"config,omitempty"` - ConfigPath string `json:"config_path,omitempty"` + Enabled bool `json:"enabled,omitempty"` + PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"` + DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"` + Config badoption.Listable[string] `json:"config,omitempty"` + ConfigPath string `json:"config_path,omitempty"` } type OutboundUTLSOptions struct { diff --git a/option/tls_acme.go b/option/tls_acme.go index 9c2e081f..50270607 100644 --- a/option/tls_acme.go +++ b/option/tls_acme.go @@ -5,10 +5,11 @@ import ( E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badjson" + "github.com/sagernet/sing/common/json/badoption" ) type InboundACMEOptions struct { - Domain Listable[string] `json:"domain,omitempty"` + Domain badoption.Listable[string] `json:"domain,omitempty"` DataDirectory string `json:"data_directory,omitempty"` DefaultServerName string `json:"default_server_name,omitempty"` Email string `json:"email,omitempty"` diff --git a/option/tuic.go b/option/tuic.go index 736d5a66..a9b739ec 100644 --- a/option/tuic.go +++ b/option/tuic.go @@ -1,12 +1,14 @@ package option +import "github.com/sagernet/sing/common/json/badoption" + type TUICInboundOptions struct { ListenOptions - Users []TUICUser `json:"users,omitempty"` - CongestionControl string `json:"congestion_control,omitempty"` - AuthTimeout Duration `json:"auth_timeout,omitempty"` - ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"` - Heartbeat Duration `json:"heartbeat,omitempty"` + Users []TUICUser `json:"users,omitempty"` + CongestionControl string `json:"congestion_control,omitempty"` + AuthTimeout badoption.Duration `json:"auth_timeout,omitempty"` + ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"` + Heartbeat badoption.Duration `json:"heartbeat,omitempty"` InboundTLSOptionsContainer } @@ -19,13 +21,13 @@ type TUICUser struct { type TUICOutboundOptions struct { DialerOptions ServerOptions - UUID string `json:"uuid,omitempty"` - Password string `json:"password,omitempty"` - CongestionControl string `json:"congestion_control,omitempty"` - UDPRelayMode string `json:"udp_relay_mode,omitempty"` - UDPOverStream bool `json:"udp_over_stream,omitempty"` - ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"` - Heartbeat Duration `json:"heartbeat,omitempty"` - Network NetworkList `json:"network,omitempty"` + UUID string `json:"uuid,omitempty"` + Password string `json:"password,omitempty"` + CongestionControl string `json:"congestion_control,omitempty"` + UDPRelayMode string `json:"udp_relay_mode,omitempty"` + UDPOverStream bool `json:"udp_over_stream,omitempty"` + ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"` + Heartbeat badoption.Duration `json:"heartbeat,omitempty"` + Network NetworkList `json:"network,omitempty"` OutboundTLSOptionsContainer } diff --git a/option/tun.go b/option/tun.go index dbb1bfea..a7a0f6bc 100644 --- a/option/tun.go +++ b/option/tun.go @@ -7,51 +7,52 @@ 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" ) type TunInboundOptions struct { - InterfaceName string `json:"interface_name,omitempty"` - MTU uint32 `json:"mtu,omitempty"` - GSO bool `json:"gso,omitempty"` - Address Listable[netip.Prefix] `json:"address,omitempty"` - AutoRoute bool `json:"auto_route,omitempty"` - IPRoute2TableIndex int `json:"iproute2_table_index,omitempty"` - IPRoute2RuleIndex int `json:"iproute2_rule_index,omitempty"` - AutoRedirect bool `json:"auto_redirect,omitempty"` - AutoRedirectInputMark FwMark `json:"auto_redirect_input_mark,omitempty"` - AutoRedirectOutputMark FwMark `json:"auto_redirect_output_mark,omitempty"` - StrictRoute bool `json:"strict_route,omitempty"` - RouteAddress Listable[netip.Prefix] `json:"route_address,omitempty"` - RouteAddressSet Listable[string] `json:"route_address_set,omitempty"` - RouteExcludeAddress Listable[netip.Prefix] `json:"route_exclude_address,omitempty"` - RouteExcludeAddressSet Listable[string] `json:"route_exclude_address_set,omitempty"` - IncludeInterface Listable[string] `json:"include_interface,omitempty"` - ExcludeInterface Listable[string] `json:"exclude_interface,omitempty"` - IncludeUID Listable[uint32] `json:"include_uid,omitempty"` - IncludeUIDRange Listable[string] `json:"include_uid_range,omitempty"` - ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"` - ExcludeUIDRange Listable[string] `json:"exclude_uid_range,omitempty"` - IncludeAndroidUser Listable[int] `json:"include_android_user,omitempty"` - IncludePackage Listable[string] `json:"include_package,omitempty"` - ExcludePackage Listable[string] `json:"exclude_package,omitempty"` - EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"` - UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"` - Stack string `json:"stack,omitempty"` - Platform *TunPlatformOptions `json:"platform,omitempty"` + InterfaceName string `json:"interface_name,omitempty"` + MTU uint32 `json:"mtu,omitempty"` + GSO bool `json:"gso,omitempty"` + Address badoption.Listable[netip.Prefix] `json:"address,omitempty"` + AutoRoute bool `json:"auto_route,omitempty"` + IPRoute2TableIndex int `json:"iproute2_table_index,omitempty"` + IPRoute2RuleIndex int `json:"iproute2_rule_index,omitempty"` + AutoRedirect bool `json:"auto_redirect,omitempty"` + AutoRedirectInputMark FwMark `json:"auto_redirect_input_mark,omitempty"` + AutoRedirectOutputMark FwMark `json:"auto_redirect_output_mark,omitempty"` + StrictRoute bool `json:"strict_route,omitempty"` + RouteAddress badoption.Listable[netip.Prefix] `json:"route_address,omitempty"` + RouteAddressSet badoption.Listable[string] `json:"route_address_set,omitempty"` + RouteExcludeAddress badoption.Listable[netip.Prefix] `json:"route_exclude_address,omitempty"` + RouteExcludeAddressSet badoption.Listable[string] `json:"route_exclude_address_set,omitempty"` + IncludeInterface badoption.Listable[string] `json:"include_interface,omitempty"` + ExcludeInterface badoption.Listable[string] `json:"exclude_interface,omitempty"` + IncludeUID badoption.Listable[uint32] `json:"include_uid,omitempty"` + IncludeUIDRange badoption.Listable[string] `json:"include_uid_range,omitempty"` + ExcludeUID badoption.Listable[uint32] `json:"exclude_uid,omitempty"` + ExcludeUIDRange badoption.Listable[string] `json:"exclude_uid_range,omitempty"` + IncludeAndroidUser badoption.Listable[int] `json:"include_android_user,omitempty"` + IncludePackage badoption.Listable[string] `json:"include_package,omitempty"` + ExcludePackage badoption.Listable[string] `json:"exclude_package,omitempty"` + EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"` + UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"` + Stack string `json:"stack,omitempty"` + Platform *TunPlatformOptions `json:"platform,omitempty"` InboundOptions // Deprecated: merged to Address - Inet4Address Listable[netip.Prefix] `json:"inet4_address,omitempty"` + Inet4Address badoption.Listable[netip.Prefix] `json:"inet4_address,omitempty"` // Deprecated: merged to Address - Inet6Address Listable[netip.Prefix] `json:"inet6_address,omitempty"` + Inet6Address badoption.Listable[netip.Prefix] `json:"inet6_address,omitempty"` // Deprecated: merged to RouteAddress - Inet4RouteAddress Listable[netip.Prefix] `json:"inet4_route_address,omitempty"` + Inet4RouteAddress badoption.Listable[netip.Prefix] `json:"inet4_route_address,omitempty"` // Deprecated: merged to RouteAddress - Inet6RouteAddress Listable[netip.Prefix] `json:"inet6_route_address,omitempty"` + Inet6RouteAddress badoption.Listable[netip.Prefix] `json:"inet6_route_address,omitempty"` // Deprecated: merged to RouteExcludeAddress - Inet4RouteExcludeAddress Listable[netip.Prefix] `json:"inet4_route_exclude_address,omitempty"` + Inet4RouteExcludeAddress badoption.Listable[netip.Prefix] `json:"inet4_route_exclude_address,omitempty"` // Deprecated: merged to RouteExcludeAddress - Inet6RouteExcludeAddress Listable[netip.Prefix] `json:"inet6_route_exclude_address,omitempty"` + Inet6RouteExcludeAddress badoption.Listable[netip.Prefix] `json:"inet6_route_exclude_address,omitempty"` } type FwMark uint32 diff --git a/option/tun_platform.go b/option/tun_platform.go index a0a54eed..b42f6894 100644 --- a/option/tun_platform.go +++ b/option/tun_platform.go @@ -1,5 +1,7 @@ package option +import "github.com/sagernet/sing/common/json/badoption" + type TunPlatformOptions struct { HTTPProxy *HTTPProxyOptions `json:"http_proxy,omitempty"` } @@ -7,6 +9,6 @@ type TunPlatformOptions struct { type HTTPProxyOptions struct { Enabled bool `json:"enabled,omitempty"` ServerOptions - BypassDomain Listable[string] `json:"bypass_domain,omitempty"` - MatchDomain Listable[string] `json:"match_domain,omitempty"` + BypassDomain badoption.Listable[string] `json:"bypass_domain,omitempty"` + MatchDomain badoption.Listable[string] `json:"match_domain,omitempty"` } diff --git a/option/types.go b/option/types.go index bb648549..04e3f10e 100644 --- a/option/types.go +++ b/option/types.go @@ -1,10 +1,7 @@ package option import ( - "net/http" - "net/netip" "strings" - "time" "github.com/sagernet/sing-dns" E "github.com/sagernet/sing/common/exceptions" @@ -15,79 +12,6 @@ import ( mDNS "github.com/miekg/dns" ) -type ListenAddress netip.Addr - -func NewListenAddress(addr netip.Addr) *ListenAddress { - address := ListenAddress(addr) - return &address -} - -func (a ListenAddress) MarshalJSON() ([]byte, error) { - addr := netip.Addr(a) - if !addr.IsValid() { - return nil, nil - } - return json.Marshal(addr.String()) -} - -func (a *ListenAddress) UnmarshalJSON(content []byte) error { - var value string - err := json.Unmarshal(content, &value) - if err != nil { - return err - } - addr, err := netip.ParseAddr(value) - if err != nil { - return err - } - *a = ListenAddress(addr) - return nil -} - -func (a *ListenAddress) Build() netip.Addr { - if a == nil { - return netip.AddrFrom4([4]byte{127, 0, 0, 1}) - } - return (netip.Addr)(*a) -} - -type AddrPrefix netip.Prefix - -func (a AddrPrefix) MarshalJSON() ([]byte, error) { - prefix := netip.Prefix(a) - if prefix.Bits() == prefix.Addr().BitLen() { - return json.Marshal(prefix.Addr().String()) - } else { - return json.Marshal(prefix.String()) - } -} - -func (a *AddrPrefix) UnmarshalJSON(content []byte) error { - var value string - err := json.Unmarshal(content, &value) - if err != nil { - return err - } - prefix, prefixErr := netip.ParsePrefix(value) - if prefixErr == nil { - *a = AddrPrefix(prefix) - return nil - } - addr, addrErr := netip.ParseAddr(value) - if addrErr == nil { - *a = AddrPrefix(netip.PrefixFrom(addr, addr.BitLen())) - return nil - } - return prefixErr -} - -func (a *AddrPrefix) Build() netip.Prefix { - if a == nil { - return netip.Prefix{} - } - return netip.Prefix(*a) -} - type NetworkList string func (v *NetworkList) UnmarshalJSON(content []byte) error { @@ -120,30 +44,6 @@ func (v NetworkList) Build() []string { return strings.Split(string(v), "\n") } -type Listable[T any] []T - -func (l Listable[T]) MarshalJSON() ([]byte, error) { - arrayList := []T(l) - if len(arrayList) == 1 { - return json.Marshal(arrayList[0]) - } - return json.Marshal(arrayList) -} - -func (l *Listable[T]) UnmarshalJSON(content []byte) error { - err := json.UnmarshalDisallowUnknownFields(content, (*[]T)(l)) - if err == nil { - return nil - } - var singleItem T - newError := json.UnmarshalDisallowUnknownFields(content, &singleItem) - if newError != nil { - return E.Errors(err, newError) - } - *l = []T{singleItem} - return nil -} - type DomainStrategy dns.DomainStrategy func (s DomainStrategy) String() string { @@ -206,26 +106,6 @@ func (s *DomainStrategy) UnmarshalJSON(bytes []byte) error { return nil } -type Duration time.Duration - -func (d Duration) MarshalJSON() ([]byte, error) { - return json.Marshal((time.Duration)(d).String()) -} - -func (d *Duration) UnmarshalJSON(bytes []byte) error { - var value string - err := json.Unmarshal(bytes, &value) - if err != nil { - return err - } - duration, err := ParseDuration(value) - if err != nil { - return err - } - *d = Duration(duration) - return nil -} - type DNSQueryType uint16 func (t DNSQueryType) String() string { @@ -270,15 +150,3 @@ func DNSQueryTypeToString(queryType uint16) string { } return F.ToString(queryType) } - -type HTTPHeader map[string]Listable[string] - -func (h HTTPHeader) Build() http.Header { - header := make(http.Header) - for name, values := range h { - for _, value := range values { - header.Add(name, value) - } - } - return header -} diff --git a/option/v2ray_transport.go b/option/v2ray_transport.go index f87b175d..68c23858 100644 --- a/option/v2ray_transport.go +++ b/option/v2ray_transport.go @@ -5,6 +5,7 @@ import ( E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badjson" + "github.com/sagernet/sing/common/json/badoption" ) type _V2RayTransportOptions struct { @@ -67,33 +68,33 @@ func (o *V2RayTransportOptions) UnmarshalJSON(bytes []byte) error { } type V2RayHTTPOptions struct { - Host Listable[string] `json:"host,omitempty"` - Path string `json:"path,omitempty"` - Method string `json:"method,omitempty"` - Headers HTTPHeader `json:"headers,omitempty"` - IdleTimeout Duration `json:"idle_timeout,omitempty"` - PingTimeout Duration `json:"ping_timeout,omitempty"` + Host badoption.Listable[string] `json:"host,omitempty"` + Path string `json:"path,omitempty"` + Method string `json:"method,omitempty"` + Headers badoption.HTTPHeader `json:"headers,omitempty"` + IdleTimeout badoption.Duration `json:"idle_timeout,omitempty"` + PingTimeout badoption.Duration `json:"ping_timeout,omitempty"` } type V2RayWebsocketOptions struct { - Path string `json:"path,omitempty"` - Headers HTTPHeader `json:"headers,omitempty"` - MaxEarlyData uint32 `json:"max_early_data,omitempty"` - EarlyDataHeaderName string `json:"early_data_header_name,omitempty"` + Path string `json:"path,omitempty"` + Headers badoption.HTTPHeader `json:"headers,omitempty"` + MaxEarlyData uint32 `json:"max_early_data,omitempty"` + EarlyDataHeaderName string `json:"early_data_header_name,omitempty"` } type V2RayQUICOptions struct{} type V2RayGRPCOptions struct { - ServiceName string `json:"service_name,omitempty"` - IdleTimeout Duration `json:"idle_timeout,omitempty"` - PingTimeout Duration `json:"ping_timeout,omitempty"` - PermitWithoutStream bool `json:"permit_without_stream,omitempty"` - ForceLite bool `json:"-"` // for test + ServiceName string `json:"service_name,omitempty"` + IdleTimeout badoption.Duration `json:"idle_timeout,omitempty"` + PingTimeout badoption.Duration `json:"ping_timeout,omitempty"` + PermitWithoutStream bool `json:"permit_without_stream,omitempty"` + ForceLite bool `json:"-"` // for test } type V2RayHTTPUpgradeOptions struct { - Host string `json:"host,omitempty"` - Path string `json:"path,omitempty"` - Headers HTTPHeader `json:"headers,omitempty"` + Host string `json:"host,omitempty"` + Path string `json:"path,omitempty"` + Headers badoption.HTTPHeader `json:"headers,omitempty"` } diff --git a/option/wireguard.go b/option/wireguard.go index 65bfad20..ebdf159f 100644 --- a/option/wireguard.go +++ b/option/wireguard.go @@ -1,15 +1,19 @@ package option -import "net/netip" +import ( + "net/netip" + + "github.com/sagernet/sing/common/json/badoption" +) type WireGuardOutboundOptions struct { DialerOptions - SystemInterface bool `json:"system_interface,omitempty"` - GSO bool `json:"gso,omitempty"` - InterfaceName string `json:"interface_name,omitempty"` - LocalAddress Listable[netip.Prefix] `json:"local_address"` - PrivateKey string `json:"private_key"` - Peers []WireGuardPeer `json:"peers,omitempty"` + SystemInterface bool `json:"system_interface,omitempty"` + GSO bool `json:"gso,omitempty"` + InterfaceName string `json:"interface_name,omitempty"` + LocalAddress badoption.Listable[netip.Prefix] `json:"local_address"` + PrivateKey string `json:"private_key"` + Peers []WireGuardPeer `json:"peers,omitempty"` ServerOptions PeerPublicKey string `json:"peer_public_key"` PreSharedKey string `json:"pre_shared_key,omitempty"` @@ -21,8 +25,8 @@ type WireGuardOutboundOptions struct { type WireGuardPeer struct { ServerOptions - PublicKey string `json:"public_key,omitempty"` - PreSharedKey string `json:"pre_shared_key,omitempty"` - AllowedIPs Listable[string] `json:"allowed_ips,omitempty"` - Reserved []uint8 `json:"reserved,omitempty"` + PublicKey string `json:"public_key,omitempty"` + PreSharedKey string `json:"pre_shared_key,omitempty"` + AllowedIPs badoption.Listable[string] `json:"allowed_ips,omitempty"` + Reserved []uint8 `json:"reserved,omitempty"` } diff --git a/protocol/tun/inbound.go b/protocol/tun/inbound.go index 4be30d61..f2476223 100644 --- a/protocol/tun/inbound.go +++ b/protocol/tun/inbound.go @@ -21,6 +21,7 @@ import ( "github.com/sagernet/sing-tun" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" + "github.com/sagernet/sing/common/json/badoption" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" "github.com/sagernet/sing/common/ranges" @@ -257,7 +258,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo return inbound, nil } -func uidToRange(uidList option.Listable[uint32]) []ranges.Range[uint32] { +func uidToRange(uidList badoption.Listable[uint32]) []ranges.Range[uint32] { return common.Map(uidList, func(uid uint32) ranges.Range[uint32] { return ranges.NewSingle(uid) }) diff --git a/route/router.go b/route/router.go index ce480749..9a57328a 100644 --- a/route/router.go +++ b/route/router.go @@ -239,9 +239,9 @@ func NewRouter( } var clientSubnet netip.Prefix if server.ClientSubnet != nil { - clientSubnet = server.ClientSubnet.Build() + clientSubnet = netip.Prefix(common.PtrValueOrDefault(server.ClientSubnet)) } else if dnsOptions.ClientSubnet != nil { - clientSubnet = dnsOptions.ClientSubnet.Build() + clientSubnet = netip.Prefix(common.PtrValueOrDefault(dnsOptions.ClientSubnet)) } if serverProtocol == "" { serverProtocol = "transport" diff --git a/route/rule/rule_action.go b/route/rule/rule_action.go index 620260d0..0bf45ba2 100644 --- a/route/rule/rule_action.go +++ b/route/rule/rule_action.go @@ -88,13 +88,13 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction) Server: action.RouteOptions.Server, DisableCache: action.RouteOptions.DisableCache, RewriteTTL: action.RouteOptions.RewriteTTL, - ClientSubnet: action.RouteOptions.ClientSubnet.Build(), + ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptions.ClientSubnet)), } case C.RuleActionTypeRouteOptions: return &RuleActionDNSRouteOptions{ DisableCache: action.RouteOptionsOptions.DisableCache, RewriteTTL: action.RouteOptionsOptions.RewriteTTL, - ClientSubnet: action.RouteOptionsOptions.ClientSubnet.Build(), + ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptionsOptions.ClientSubnet)), } case C.RuleActionTypeReject: return &RuleActionReject{ diff --git a/test/brutal_test.go b/test/brutal_test.go index ce1d2c2a..cea0ad07 100644 --- a/test/brutal_test.go +++ b/test/brutal_test.go @@ -7,6 +7,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-shadowsocks/shadowaead_2022" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/gofrs/uuid/v5" ) @@ -15,13 +17,13 @@ func TestBrutalShadowsocks(t *testing.T) { method := shadowaead_2022.List[0] password := mkBase64(t, 16) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -30,7 +32,7 @@ func TestBrutalShadowsocks(t *testing.T) { Type: C.TypeShadowsocks, ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Method: method, @@ -100,13 +102,13 @@ func TestBrutalTrojan(t *testing.T) { _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") password := mkBase64(t, 16) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -115,7 +117,7 @@ func TestBrutalTrojan(t *testing.T) { Type: C.TypeTrojan, TrojanOptions: option.TrojanInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.TrojanUser{{Password: password}}, @@ -197,13 +199,13 @@ func TestBrutalTrojan(t *testing.T) { func TestBrutalVMess(t *testing.T) { user, _ := uuid.NewV4() startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -212,7 +214,7 @@ func TestBrutalVMess(t *testing.T) { Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{{UUID: user.String()}}, @@ -279,13 +281,13 @@ func TestBrutalVMess(t *testing.T) { func TestBrutalVLESS(t *testing.T) { user, _ := uuid.NewV4() startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -294,7 +296,7 @@ func TestBrutalVLESS(t *testing.T) { Type: C.TypeVLESS, VLESSOptions: option.VLESSInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VLESSUser{{UUID: user.String()}}, diff --git a/test/direct_test.go b/test/direct_test.go index c4fd8c5e..7e7740e5 100644 --- a/test/direct_test.go +++ b/test/direct_test.go @@ -6,18 +6,20 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) // Since this is a feature one-off added by outsiders, I won't address these anymore. func _TestProxyProtocol(t *testing.T) { startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -26,7 +28,7 @@ func _TestProxyProtocol(t *testing.T) { Type: C.TypeDirect, DirectOptions: option.DirectInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, ProxyProtocol: true, }, diff --git a/test/domain_inbound_test.go b/test/domain_inbound_test.go index c82b0d29..032b5f59 100644 --- a/test/domain_inbound_test.go +++ b/test/domain_inbound_test.go @@ -7,6 +7,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-dns" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/gofrs/uuid/v5" ) @@ -14,13 +16,13 @@ import ( func TestTUICDomainUDP(t *testing.T) { _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -29,7 +31,7 @@ func TestTUICDomainUDP(t *testing.T) { Type: C.TypeTUIC, TUICOptions: option.TUICInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, InboundOptions: option.InboundOptions{ DomainStrategy: option.DomainStrategy(dns.DomainStrategyUseIPv6), diff --git a/test/ech_test.go b/test/ech_test.go index eeac1acb..5dac5a0a 100644 --- a/test/ech_test.go +++ b/test/ech_test.go @@ -8,6 +8,7 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/gofrs/uuid/v5" ) @@ -16,13 +17,13 @@ func TestECH(t *testing.T) { _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false)) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -31,7 +32,7 @@ func TestECH(t *testing.T) { Type: C.TypeTrojan, TrojanOptions: option.TrojanInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.TrojanUser{ @@ -109,13 +110,13 @@ func TestECHQUIC(t *testing.T) { _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false)) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -124,7 +125,7 @@ func TestECHQUIC(t *testing.T) { Type: C.TypeTUIC, TUICOptions: option.TUICInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.TUICUser{{ @@ -199,13 +200,13 @@ func TestECHHysteria2(t *testing.T) { _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false)) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -214,7 +215,7 @@ func TestECHHysteria2(t *testing.T) { Type: C.TypeHysteria2, Hysteria2Options: option.Hysteria2InboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.Hysteria2User{{ diff --git a/test/go.mod b/test/go.mod index f9eefa16..72d593ff 100644 --- a/test/go.mod +++ b/test/go.mod @@ -12,10 +12,10 @@ require ( github.com/docker/docker v27.3.1+incompatible github.com/docker/go-connections v0.5.0 github.com/gofrs/uuid/v5 v5.3.0 - github.com/sagernet/quic-go v0.48.0-beta.1 - github.com/sagernet/sing v0.5.0-rc.4.0.20241022031908-cd17884118cb - github.com/sagernet/sing-dns v0.3.0-rc.2.0.20241021154031-a59e0fbba3ce - github.com/sagernet/sing-quic v0.3.0-rc.1 + github.com/sagernet/quic-go v0.48.1-beta.1 + github.com/sagernet/sing v0.5.1-0.20241107131656-6e1285b5d82f + github.com/sagernet/sing-dns v0.3.1-0.20241105104342-1914f319ddab + github.com/sagernet/sing-quic v0.3.0-rc.2 github.com/sagernet/sing-shadowsocks v0.2.7 github.com/sagernet/sing-shadowsocks2 v0.2.0 github.com/spyzhov/ajson v0.9.4 @@ -25,13 +25,11 @@ require ( ) require ( - berty.tech/go-libtor v1.0.385 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/caddyserver/certmagic v0.20.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/log v0.1.0 // indirect - github.com/cretz/bine v0.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/reference v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -42,8 +40,6 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/gobwas/httphead v0.1.0 // indirect - github.com/gobwas/pool v0.2.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -65,7 +61,6 @@ require ( github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/onsi/ginkgo/v2 v2.9.7 // indirect - github.com/ooni/go-libtor v1.1.8 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/oschwald/maxminddb-golang v1.12.0 // indirect @@ -81,13 +76,10 @@ require ( github.com/sagernet/nftables v0.3.0-beta.4 // indirect github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect github.com/sagernet/sing-mux v0.2.1-0.20241020175909-fe6153f7a9ec // indirect - github.com/sagernet/sing-shadowtls v0.1.4 // indirect - github.com/sagernet/sing-tun v0.4.0-rc.4.0.20241021153919-9ae45181180d // indirect + github.com/sagernet/sing-tun v0.4.0-rc.5.0.20241107062822-5a91eb99c90f // indirect github.com/sagernet/sing-vmess v0.1.12 // indirect github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect github.com/sagernet/utls v1.6.7 // indirect - github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 // indirect - github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 // indirect github.com/vishvananda/netns v0.0.4 // indirect github.com/zeebo/blake3 v0.2.3 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect diff --git a/test/go.sum b/test/go.sum index e851ebd3..7cb24e5f 100644 --- a/test/go.sum +++ b/test/go.sum @@ -1,5 +1,3 @@ -berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw= -berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -14,9 +12,6 @@ github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vc github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw= -github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo= -github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -43,10 +38,6 @@ github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= -github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gofrs/uuid/v5 v5.3.0 h1:m0mUMr+oVYUdxpMLgSYCZiXe7PuVPnI94+OMeVBNedk= github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -107,8 +98,6 @@ github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= -github.com/ooni/go-libtor v1.1.8 h1:Wo3V3DVTxl5vZdxtQakqYP+DAHx7pPtAFSl1bnAa08w= -github.com/ooni/go-libtor v1.1.8/go.mod h1:q1YyLwRD9GeMyeerVvwc0vJ2YgwDLTp2bdVcrh/JXyI= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= @@ -135,45 +124,37 @@ github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZN github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I= github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8= -github.com/sagernet/quic-go v0.48.0-beta.1 h1:86hQZrmuoARI3BpDRkQaP0iAVpywA4YsRrzJPYuPKWg= -github.com/sagernet/quic-go v0.48.0-beta.1/go.mod h1:1WgdDIVD1Gybp40JTWketeSfKA/+or9YMLaG5VeTk4k= +github.com/sagernet/quic-go v0.48.1-beta.1 h1:ElPaV5yzlXIKZpqFMAcUGax6vddi3zt4AEpT94Z0vwo= +github.com/sagernet/quic-go v0.48.1-beta.1/go.mod h1:1WgdDIVD1Gybp40JTWketeSfKA/+or9YMLaG5VeTk4k= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo= -github.com/sagernet/sing v0.5.0-rc.4.0.20241022031908-cd17884118cb h1:3IhGq2UmcbQfAcuqyE8RYKFapqEEa3eItS/MrZr+5l8= -github.com/sagernet/sing v0.5.0-rc.4.0.20241022031908-cd17884118cb/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= -github.com/sagernet/sing-dns v0.3.0-rc.2.0.20241021154031-a59e0fbba3ce h1:OfpxE5qnXMyU/9LtNgX4M7bGP11lJx4s+KZ3Sijb0HE= -github.com/sagernet/sing-dns v0.3.0-rc.2.0.20241021154031-a59e0fbba3ce/go.mod h1:TqLIelI+FAbVEdiTRolhGLOwvhVjY7oT+wezlOJUQ7M= +github.com/sagernet/sing v0.5.1-0.20241107131656-6e1285b5d82f h1:A6+OeV5P1mok0eEEbLh4PidymZ6VZnTZ2uHwfapXgdU= +github.com/sagernet/sing v0.5.1-0.20241107131656-6e1285b5d82f/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing-dns v0.3.1-0.20241105104342-1914f319ddab h1:djP4EY/KM5T62xscormLflVi7eDlHv6p7md1FHMSArE= +github.com/sagernet/sing-dns v0.3.1-0.20241105104342-1914f319ddab/go.mod h1:TqLIelI+FAbVEdiTRolhGLOwvhVjY7oT+wezlOJUQ7M= github.com/sagernet/sing-mux v0.2.1-0.20241020175909-fe6153f7a9ec h1:6Fd/VsEsw9qIjaGi1IBTZSb4b4v5JYtNcoiBtGsQC48= github.com/sagernet/sing-mux v0.2.1-0.20241020175909-fe6153f7a9ec/go.mod h1:RSwqqHwbtTOX3vs6ms8vMtBGH/0ZNyLm/uwt6TlmR84= -github.com/sagernet/sing-quic v0.3.0-rc.1 h1:SlzL1yfEAKJyRduub8vzOVtbyTLAX7RZEEBZxO5utts= -github.com/sagernet/sing-quic v0.3.0-rc.1/go.mod h1:uX+aUHA0fgIN6U3WViseDpSdTQriViZ7qz0Wbsf1mNQ= +github.com/sagernet/sing-quic v0.3.0-rc.2 h1:7vcC4bdS1GBJzHZhfmJiH0CfzQ4mYLUW51Z2RNHcGwc= +github.com/sagernet/sing-quic v0.3.0-rc.2/go.mod h1:3UOq51WVqzra7eCgod7t4hqnTaOiZzFUci9avMrtOqs= github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8= github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE= github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg= github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= -github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k= -github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= -github.com/sagernet/sing-tun v0.4.0-rc.4.0.20241021153919-9ae45181180d h1:zWcIQM3eAKJGzy7zhqkO7zm7ZI890OdR4vSwx2mevS0= -github.com/sagernet/sing-tun v0.4.0-rc.4.0.20241021153919-9ae45181180d/go.mod h1:Xhv+Mz2nE7HZTwResni8EtTa7AMJz/S6uQLT5lV23M8= +github.com/sagernet/sing-tun v0.4.0-rc.5.0.20241107062822-5a91eb99c90f h1:gQwTgN/E4oHe3VlseD3/RhPs866cWcTsPG4dP6a8f8o= +github.com/sagernet/sing-tun v0.4.0-rc.5.0.20241107062822-5a91eb99c90f/go.mod h1:Ehs5mZ3T8tTgV3H1Tx4Va5ixvyKjTAUPJ3G11dq7B/g= github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg= github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo= github.com/sagernet/utls v1.6.7 h1:Ep3+aJ8FUGGta+II2IEVNUc3EDhaRCZINWkj/LloIA8= github.com/sagernet/utls v1.6.7/go.mod h1:Uua1TKO/FFuAhLr9rkaVnnrTmmiItzDjv1BUb2+ERwM= -github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 h1:R0OMYAScomNAVpTfbHFpxqJpvwuhxSRi+g6z7gZhABs= -github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8/go.mod h1:K4J7/npM+VAMUeUmTa2JaA02JmyheP0GpRBOUvn3ecc= -github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc= -github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spyzhov/ajson v0.9.4 h1:MVibcTCgO7DY4IlskdqIlCmDOsUOZ9P7oKj8ifdcf84= github.com/spyzhov/ajson v0.9.4/go.mod h1:a6oSw0MMb7Z5aD2tPoPO+jq11ETKgXUr2XktHdT8Wt8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= @@ -211,10 +192,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= @@ -227,8 +206,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -237,23 +214,15 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= diff --git a/test/http_test.go b/test/http_test.go index 7e724005..dbf8b3bc 100644 --- a/test/http_test.go +++ b/test/http_test.go @@ -6,17 +6,19 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) func TestHTTPSelf(t *testing.T) { startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -25,7 +27,7 @@ func TestHTTPSelf(t *testing.T) { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, }, diff --git a/test/hysteria2_test.go b/test/hysteria2_test.go index 665da552..1e031f1c 100644 --- a/test/hysteria2_test.go +++ b/test/hysteria2_test.go @@ -7,6 +7,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-quic/hysteria2" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) func TestHysteria2Self(t *testing.T) { @@ -28,13 +30,13 @@ func testHysteria2Self(t *testing.T, salamanderPassword string) { } } startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -43,7 +45,7 @@ func testHysteria2Self(t *testing.T, salamanderPassword string) { Type: C.TypeHysteria2, Hysteria2Options: option.Hysteria2InboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, UpMbps: 100, @@ -115,12 +117,12 @@ func testHysteria2Self(t *testing.T, salamanderPassword string) { func TestHysteria2Inbound(t *testing.T) { caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeHysteria2, Hysteria2Options: option.Hysteria2InboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Obfs: &option.Hysteria2Obfs{ @@ -167,12 +169,12 @@ func TestHysteria2Outbound(t *testing.T) { }, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, diff --git a/test/hysteria_test.go b/test/hysteria_test.go index dce00390..e9467e18 100644 --- a/test/hysteria_test.go +++ b/test/hysteria_test.go @@ -6,18 +6,20 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) func TestHysteriaSelf(t *testing.T) { _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -26,7 +28,7 @@ func TestHysteriaSelf(t *testing.T) { Type: C.TypeHysteria, HysteriaOptions: option.HysteriaInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, UpMbps: 100, @@ -98,12 +100,12 @@ func TestHysteriaSelf(t *testing.T) { func TestHysteriaInbound(t *testing.T) { caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeHysteria, HysteriaOptions: option.HysteriaInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, UpMbps: 100, @@ -149,12 +151,12 @@ func TestHysteriaOutbound(t *testing.T) { }, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, diff --git a/test/inbound_detour_test.go b/test/inbound_detour_test.go index c26c81a7..4ae82bc9 100644 --- a/test/inbound_detour_test.go +++ b/test/inbound_detour_test.go @@ -7,19 +7,21 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-shadowsocks/shadowaead_2022" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) func TestChainedInbound(t *testing.T) { method := shadowaead_2022.List[0] password := mkBase64(t, 16) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -28,9 +30,11 @@ func TestChainedInbound(t *testing.T) { Type: C.TypeShadowsocks, ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, - Detour: "detour", + InboundOptions: option.InboundOptions{ + Detour: "detour", + }, }, Method: method, Password: password, @@ -41,7 +45,7 @@ func TestChainedInbound(t *testing.T) { Tag: "detour", ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: otherPort, }, Method: method, diff --git a/test/mux_cool_test.go b/test/mux_cool_test.go index e72f244f..2dceeb54 100644 --- a/test/mux_cool_test.go +++ b/test/mux_cool_test.go @@ -7,6 +7,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/spyzhov/ajson" "github.com/stretchr/testify/require" @@ -37,12 +39,12 @@ func TestMuxCoolServer(t *testing.T) { }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ @@ -81,12 +83,12 @@ func TestMuxCoolClient(t *testing.T) { }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -112,13 +114,13 @@ func TestMuxCoolClient(t *testing.T) { func TestMuxCoolSelf(t *testing.T) { user := newUUID() startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -127,7 +129,7 @@ func TestMuxCoolSelf(t *testing.T) { Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ diff --git a/test/mux_test.go b/test/mux_test.go index 335def2e..27c6b914 100644 --- a/test/mux_test.go +++ b/test/mux_test.go @@ -7,6 +7,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-shadowsocks/shadowaead_2022" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/gofrs/uuid/v5" ) @@ -55,13 +57,13 @@ func testShadowsocksMux(t *testing.T, options option.OutboundMultiplexOptions) { method := shadowaead_2022.List[0] password := mkBase64(t, 16) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -70,7 +72,7 @@ func testShadowsocksMux(t *testing.T, options option.OutboundMultiplexOptions) { Type: C.TypeShadowsocks, ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Method: method, @@ -125,13 +127,13 @@ func testShadowsocksMux(t *testing.T, options option.OutboundMultiplexOptions) { func testVMessMux(t *testing.T, options option.OutboundMultiplexOptions) { user, _ := uuid.NewV4() startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -140,7 +142,7 @@ func testVMessMux(t *testing.T, options option.OutboundMultiplexOptions) { Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ diff --git a/test/naive_test.go b/test/naive_test.go index fe3e7dce..d3cb395e 100644 --- a/test/naive_test.go +++ b/test/naive_test.go @@ -6,19 +6,21 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/auth" + "github.com/sagernet/sing/common/json/badoption" "github.com/sagernet/sing/common/network" ) func TestNaiveInboundWithNginx(t *testing.T) { caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeNaive, NaiveOptions: option.NaiveInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: otherPort, }, Users: []auth.User{ @@ -59,12 +61,12 @@ func TestNaiveInboundWithNginx(t *testing.T) { func TestNaiveInbound(t *testing.T) { caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeNaive, NaiveOptions: option.NaiveInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []auth.User{ @@ -103,12 +105,12 @@ func TestNaiveInbound(t *testing.T) { func TestNaiveHTTP3Inbound(t *testing.T) { caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeNaive, NaiveOptions: option.NaiveInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []auth.User{ diff --git a/test/shadowsocks_legacy_test.go b/test/shadowsocks_legacy_test.go index ae6f38e4..bbdbbde8 100644 --- a/test/shadowsocks_legacy_test.go +++ b/test/shadowsocks_legacy_test.go @@ -7,7 +7,9 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-shadowsocks2/shadowstream" + "github.com/sagernet/sing/common" F "github.com/sagernet/sing/common/format" + "github.com/sagernet/sing/common/json/badoption" ) func TestShadowsocksLegacy(t *testing.T) { @@ -24,12 +26,12 @@ func testShadowsocksLegacy(t *testing.T, method string) { }, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, diff --git a/test/shadowsocks_test.go b/test/shadowsocks_test.go index 0f7af765..c83734e4 100644 --- a/test/shadowsocks_test.go +++ b/test/shadowsocks_test.go @@ -9,7 +9,9 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-shadowsocks/shadowaead_2022" + "github.com/sagernet/sing/common" F "github.com/sagernet/sing/common/format" + "github.com/sagernet/sing/common/json/badoption" "github.com/stretchr/testify/require" ) @@ -99,12 +101,12 @@ func testShadowsocksInboundWithShadowsocksRust(t *testing.T, method string, pass Cmd: []string{"-s", F.ToString("127.0.0.1:", serverPort), "-b", F.ToString("0.0.0.0:", clientPort), "-m", method, "-k", password, "-U"}, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeShadowsocks, ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Method: method, @@ -124,12 +126,12 @@ func testShadowsocksOutboundWithShadowsocksRust(t *testing.T, method string, pas Cmd: []string{"-s", F.ToString("0.0.0.0:", serverPort), "-m", method, "-k", password, "-U"}, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -154,13 +156,13 @@ func testShadowsocksOutboundWithShadowsocksRust(t *testing.T, method string, pas func testShadowsocksSelf(t *testing.T, method string, password string) { startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -169,7 +171,7 @@ func testShadowsocksSelf(t *testing.T, method string, password string) { Type: C.TypeShadowsocks, ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Method: method, @@ -221,13 +223,13 @@ func TestShadowsocksUoT(t *testing.T) { method := shadowaead_2022.List[0] password := mkBase64(t, 16) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -236,7 +238,7 @@ func TestShadowsocksUoT(t *testing.T) { Type: C.TypeShadowsocks, ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Method: method, @@ -289,13 +291,13 @@ func TestShadowsocksUoT(t *testing.T) { func testShadowsocks2022EIH(t *testing.T, method string, password string) { startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -304,7 +306,7 @@ func testShadowsocks2022EIH(t *testing.T, method string, password string) { Type: C.TypeShadowsocks, ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Method: method, diff --git a/test/shadowtls_test.go b/test/shadowtls_test.go index 71e8d9fa..026c6f55 100644 --- a/test/shadowtls_test.go +++ b/test/shadowtls_test.go @@ -10,7 +10,9 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-shadowsocks/shadowaead_2022" + "github.com/sagernet/sing/common" F "github.com/sagernet/sing/common/format" + "github.com/sagernet/sing/common/json/badoption" "github.com/stretchr/testify/require" ) @@ -37,12 +39,12 @@ func testShadowTLS(t *testing.T, version int, password string, utlsEanbled bool) method := shadowaead_2022.List[0] ssPassword := mkBase64(t, 16) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -52,9 +54,12 @@ func testShadowTLS(t *testing.T, version int, password string, utlsEanbled bool) Tag: "in", ShadowTLSOptions: option.ShadowTLSInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, - Detour: "detour", + + InboundOptions: option.InboundOptions{ + Detour: "detour", + }, }, Handshake: option.ShadowTLSHandshakeOptions{ ServerOptions: option.ServerOptions{ @@ -72,7 +77,7 @@ func testShadowTLS(t *testing.T, version int, password string, utlsEanbled bool) Tag: "detour", ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: otherPort, }, Method: method, @@ -142,12 +147,12 @@ func testShadowTLS(t *testing.T, version int, password string, utlsEanbled bool) func TestShadowTLSFallback(t *testing.T) { startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeShadowTLS, ShadowTLSOptions: option.ShadowTLSInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Handshake: option.ShadowTLSHandshakeOptions{ @@ -189,13 +194,13 @@ func TestShadowTLSInbound(t *testing.T) { Cmd: []string{"--v3", "--threads", "1", "client", "--listen", "0.0.0.0:" + F.ToString(otherPort), "--server", "127.0.0.1:" + F.ToString(serverPort), "--sni", "google.com", "--password", password}, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -204,9 +209,11 @@ func TestShadowTLSInbound(t *testing.T) { Type: C.TypeShadowTLS, ShadowTLSOptions: option.ShadowTLSInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, - Detour: "detour", + InboundOptions: option.InboundOptions{ + Detour: "detour", + }, }, Handshake: option.ShadowTLSHandshakeOptions{ ServerOptions: option.ServerOptions{ @@ -225,7 +232,7 @@ func TestShadowTLSInbound(t *testing.T) { Tag: "detour", ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), }, Method: method, Password: password, @@ -283,12 +290,12 @@ func TestShadowTLSOutbound(t *testing.T) { Env: []string{"RUST_LOG=trace"}, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -298,7 +305,7 @@ func TestShadowTLSOutbound(t *testing.T) { Tag: "detour", ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: otherPort, }, Method: method, diff --git a/test/ss_plugin_test.go b/test/ss_plugin_test.go index 3f837b4e..b74c1356 100644 --- a/test/ss_plugin_test.go +++ b/test/ss_plugin_test.go @@ -6,6 +6,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) func TestShadowsocksObfs(t *testing.T) { @@ -33,12 +35,12 @@ func testShadowsocksPlugin(t *testing.T, name string, opts string, args string) }, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, diff --git a/test/tfo_test.go b/test/tfo_test.go index 458a936d..2587bc2c 100644 --- a/test/tfo_test.go +++ b/test/tfo_test.go @@ -7,19 +7,21 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-shadowsocks/shadowaead" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) func TestTCPSlowOpen(t *testing.T) { method := shadowaead.List[0] password := mkBase64(t, 16) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -28,7 +30,7 @@ func TestTCPSlowOpen(t *testing.T) { Type: C.TypeShadowsocks, ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, TCPFastOpen: true, }, diff --git a/test/tls_test.go b/test/tls_test.go index b42d924f..fb0c7a1b 100644 --- a/test/tls_test.go +++ b/test/tls_test.go @@ -6,18 +6,20 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) func TestUTLS(t *testing.T) { _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -26,7 +28,7 @@ func TestUTLS(t *testing.T) { Type: C.TypeTrojan, TrojanOptions: option.TrojanInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.TrojanUser{ diff --git a/test/trojan_test.go b/test/trojan_test.go index 1a206c66..08e3b4d8 100644 --- a/test/trojan_test.go +++ b/test/trojan_test.go @@ -6,6 +6,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) func TestTrojanOutbound(t *testing.T) { @@ -20,12 +22,12 @@ func TestTrojanOutbound(t *testing.T) { }, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -57,13 +59,13 @@ func TestTrojanOutbound(t *testing.T) { func TestTrojanSelf(t *testing.T) { _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -72,7 +74,7 @@ func TestTrojanSelf(t *testing.T) { Type: C.TypeTrojan, TrojanOptions: option.TrojanInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.TrojanUser{ @@ -140,13 +142,13 @@ func TestTrojanSelf(t *testing.T) { func TestTrojanPlainSelf(t *testing.T) { startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -155,7 +157,7 @@ func TestTrojanPlainSelf(t *testing.T) { Type: C.TypeTrojan, TrojanOptions: option.TrojanInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.TrojanUser{ diff --git a/test/tuic_test.go b/test/tuic_test.go index 41fb7599..0c5f277d 100644 --- a/test/tuic_test.go +++ b/test/tuic_test.go @@ -6,6 +6,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/gofrs/uuid/v5" ) @@ -29,13 +31,13 @@ func testTUICSelf(t *testing.T, udpStream bool, zeroRTTHandshake bool) { udpRelayMode = "quic" } startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -44,7 +46,7 @@ func testTUICSelf(t *testing.T, udpStream bool, zeroRTTHandshake bool) { Type: C.TypeTUIC, TUICOptions: option.TUICInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.TUICUser{{ @@ -113,12 +115,12 @@ func testTUICSelf(t *testing.T, udpStream bool, zeroRTTHandshake bool) { func TestTUICInbound(t *testing.T) { caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeTUIC, TUICOptions: option.TUICInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.TUICUser{{ @@ -160,12 +162,12 @@ func TestTUICOutbound(t *testing.T) { }, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, diff --git a/test/v2ray_api_test.go b/test/v2ray_api_test.go index cd7ae2c4..72e97b3f 100644 --- a/test/v2ray_api_test.go +++ b/test/v2ray_api_test.go @@ -8,19 +8,21 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/experimental/v2rayapi" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/stretchr/testify/require" ) func TestV2RayAPI(t *testing.T) { i := startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, diff --git a/test/v2ray_grpc_test.go b/test/v2ray_grpc_test.go index 5cf87543..30cb4bd5 100644 --- a/test/v2ray_grpc_test.go +++ b/test/v2ray_grpc_test.go @@ -7,6 +7,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/gofrs/uuid/v5" "github.com/spyzhov/ajson" @@ -27,12 +29,12 @@ func testV2RayGRPCInbound(t *testing.T, forceLite bool) { require.NoError(t, err) _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ @@ -126,13 +128,13 @@ func testV2RayGRPCOutbound(t *testing.T, forceLite bool) { }, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, diff --git a/test/v2ray_transport_test.go b/test/v2ray_transport_test.go index 27074e78..bc1a3157 100644 --- a/test/v2ray_transport_test.go +++ b/test/v2ray_transport_test.go @@ -6,6 +6,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/gofrs/uuid/v5" "github.com/stretchr/testify/require" @@ -44,13 +46,13 @@ func testVMessTransportSelf(t *testing.T, server *option.V2RayTransportOptions, require.NoError(t, err) _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -59,7 +61,7 @@ func testVMessTransportSelf(t *testing.T, server *option.V2RayTransportOptions, Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ @@ -133,13 +135,13 @@ func testTrojanTransportSelf(t *testing.T, server *option.V2RayTransportOptions, require.NoError(t, err) _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -148,7 +150,7 @@ func testTrojanTransportSelf(t *testing.T, server *option.V2RayTransportOptions, Type: C.TypeTrojan, TrojanOptions: option.TrojanInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.TrojanUser{ @@ -224,13 +226,13 @@ func TestVMessQUICSelf(t *testing.T) { require.NoError(t, err) _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -239,7 +241,7 @@ func TestVMessQUICSelf(t *testing.T) { Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ @@ -312,13 +314,13 @@ func testV2RayTransportNOTLSSelf(t *testing.T, transport *option.V2RayTransportO user, err := uuid.DefaultGenerator.NewV4() require.NoError(t, err) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -327,7 +329,7 @@ func testV2RayTransportNOTLSSelf(t *testing.T, transport *option.V2RayTransportO Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ diff --git a/test/v2ray_ws_test.go b/test/v2ray_ws_test.go index de8d4bdc..35f7a7c5 100644 --- a/test/v2ray_ws_test.go +++ b/test/v2ray_ws_test.go @@ -7,6 +7,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/gofrs/uuid/v5" "github.com/spyzhov/ajson" @@ -61,12 +63,12 @@ func testV2RayWebsocketInbound(t *testing.T, maxEarlyData uint32, earlyDataHeade require.NoError(t, err) _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ @@ -158,13 +160,13 @@ func testV2RayWebsocketOutbound(t *testing.T, maxEarlyData uint32, earlyDataHead }, }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, diff --git a/test/vmess_test.go b/test/vmess_test.go index 9f81d9a0..e0fd6549 100644 --- a/test/vmess_test.go +++ b/test/vmess_test.go @@ -7,6 +7,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" "github.com/gofrs/uuid/v5" "github.com/spyzhov/ajson" @@ -181,12 +183,12 @@ func testVMessInboundWithV2Ray(t *testing.T, security string, alterId int, authe }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ @@ -229,12 +231,12 @@ func testVMessOutboundWithV2Ray(t *testing.T, security string, globalPadding boo }) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -263,13 +265,13 @@ func testVMessOutboundWithV2Ray(t *testing.T, security string, globalPadding boo func testVMessSelf(t *testing.T, security string, alterId int, globalPadding bool, authenticatedLength bool, packetAddr bool) { user := newUUID() startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, @@ -278,7 +280,7 @@ func testVMessSelf(t *testing.T, security string, alterId int, globalPadding boo Type: C.TypeVMess, VMessOptions: option.VMessInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: serverPort, }, Users: []option.VMessUser{ diff --git a/test/wireguard_test.go b/test/wireguard_test.go index 70c0e5a5..a30d520e 100644 --- a/test/wireguard_test.go +++ b/test/wireguard_test.go @@ -7,6 +7,8 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/json/badoption" ) func _TestWireGuard(t *testing.T) { @@ -21,12 +23,12 @@ func _TestWireGuard(t *testing.T) { }) time.Sleep(5 * time.Second) startInstance(t, option.Options{ - Inbounds: []option.LegacyInbound{ + LegacyInbounds: []option.LegacyInbound{ { Type: C.TypeMixed, MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.IPv4Unspecified()), + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), ListenPort: clientPort, }, }, diff --git a/transport/sip003/v2ray.go b/transport/sip003/v2ray.go index c142180b..d7b752f6 100644 --- a/transport/sip003/v2ray.go +++ b/transport/sip003/v2ray.go @@ -12,6 +12,7 @@ import ( "github.com/sagernet/sing-box/transport/v2ray" "github.com/sagernet/sing-vmess" E "github.com/sagernet/sing/common/exceptions" + "github.com/sagernet/sing/common/json/badoption" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" ) @@ -67,7 +68,7 @@ func newV2RayPlugin(ctx context.Context, pluginOpts Args, router adapter.Router, transportOptions = option.V2RayTransportOptions{ Type: C.V2RayTransportTypeWebsocket, WebsocketOptions: option.V2RayWebsocketOptions{ - Headers: map[string]option.Listable[string]{ + Headers: map[string]badoption.Listable[string]{ "Host": []string{host}, }, Path: path,