mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-23 00:51:29 +00:00
Migrate bad options to library
This commit is contained in:
parent
322192a66b
commit
8742761e11
|
@ -3,6 +3,7 @@ package dialer
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
@ -102,7 +103,7 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
|
||||||
udpAddr4 string
|
udpAddr4 string
|
||||||
)
|
)
|
||||||
if options.Inet4BindAddress != nil {
|
if options.Inet4BindAddress != nil {
|
||||||
bindAddr := options.Inet4BindAddress.Build()
|
bindAddr := options.Inet4BindAddress.Build(netip.IPv4Unspecified())
|
||||||
dialer4.LocalAddr = &net.TCPAddr{IP: bindAddr.AsSlice()}
|
dialer4.LocalAddr = &net.TCPAddr{IP: bindAddr.AsSlice()}
|
||||||
udpDialer4.LocalAddr = &net.UDPAddr{IP: bindAddr.AsSlice()}
|
udpDialer4.LocalAddr = &net.UDPAddr{IP: bindAddr.AsSlice()}
|
||||||
udpAddr4 = M.SocksaddrFrom(bindAddr, 0).String()
|
udpAddr4 = M.SocksaddrFrom(bindAddr, 0).String()
|
||||||
|
@ -113,7 +114,7 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
|
||||||
udpAddr6 string
|
udpAddr6 string
|
||||||
)
|
)
|
||||||
if options.Inet6BindAddress != nil {
|
if options.Inet6BindAddress != nil {
|
||||||
bindAddr := options.Inet6BindAddress.Build()
|
bindAddr := options.Inet6BindAddress.Build(netip.IPv6Unspecified())
|
||||||
dialer6.LocalAddr = &net.TCPAddr{IP: bindAddr.AsSlice()}
|
dialer6.LocalAddr = &net.TCPAddr{IP: bindAddr.AsSlice()}
|
||||||
udpDialer6.LocalAddr = &net.UDPAddr{IP: bindAddr.AsSlice()}
|
udpDialer6.LocalAddr = &net.UDPAddr{IP: bindAddr.AsSlice()}
|
||||||
udpAddr6 = M.SocksaddrFrom(bindAddr, 0).String()
|
udpAddr6 = M.SocksaddrFrom(bindAddr, 0).String()
|
||||||
|
|
|
@ -3,6 +3,7 @@ package listener
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
@ -92,7 +93,7 @@ func (l *Listener) Start() error {
|
||||||
if l.setSystemProxy {
|
if l.setSystemProxy {
|
||||||
listenPort := M.SocksaddrFromNet(l.tcpListener.Addr()).Port
|
listenPort := M.SocksaddrFromNet(l.tcpListener.Addr()).Port
|
||||||
var listenAddrString string
|
var listenAddrString string
|
||||||
listenAddr := l.listenOptions.Listen.Build()
|
listenAddr := l.listenOptions.Listen.Build(netip.IPv4Unspecified())
|
||||||
if listenAddr.IsUnspecified() {
|
if listenAddr.IsUnspecified() {
|
||||||
listenAddrString = "127.0.0.1"
|
listenAddrString = "127.0.0.1"
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package listener
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
|
@ -16,7 +17,7 @@ import (
|
||||||
|
|
||||||
func (l *Listener) ListenTCP() (net.Listener, error) {
|
func (l *Listener) ListenTCP() (net.Listener, error) {
|
||||||
var err 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 tcpListener net.Listener
|
||||||
var listenConfig net.ListenConfig
|
var listenConfig net.ListenConfig
|
||||||
if l.listenOptions.TCPKeepAlive >= 0 {
|
if l.listenOptions.TCPKeepAlive >= 0 {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package listener
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (l *Listener) ListenUDP() (net.PacketConn, error) {
|
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 lc net.ListenConfig
|
||||||
var udpFragment bool
|
var udpFragment bool
|
||||||
if l.listenOptions.UDPFragment != nil {
|
if l.listenOptions.UDPFragment != nil {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package deprecated
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/sagernet/sing/service"
|
"github.com/sagernet/sing/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
import "net/netip"
|
import (
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
)
|
||||||
|
|
||||||
type DNSOptions struct {
|
type DNSOptions struct {
|
||||||
Servers []DNSServerOptions `json:"servers,omitempty"`
|
Servers []DNSServerOptions `json:"servers,omitempty"`
|
||||||
|
@ -12,22 +16,22 @@ type DNSOptions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNSServerOptions struct {
|
type DNSServerOptions struct {
|
||||||
Tag string `json:"tag,omitempty"`
|
Tag string `json:"tag,omitempty"`
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
AddressResolver string `json:"address_resolver,omitempty"`
|
AddressResolver string `json:"address_resolver,omitempty"`
|
||||||
AddressStrategy DomainStrategy `json:"address_strategy,omitempty"`
|
AddressStrategy DomainStrategy `json:"address_strategy,omitempty"`
|
||||||
AddressFallbackDelay Duration `json:"address_fallback_delay,omitempty"`
|
AddressFallbackDelay badoption.Duration `json:"address_fallback_delay,omitempty"`
|
||||||
Strategy DomainStrategy `json:"strategy,omitempty"`
|
Strategy DomainStrategy `json:"strategy,omitempty"`
|
||||||
Detour string `json:"detour,omitempty"`
|
Detour string `json:"detour,omitempty"`
|
||||||
ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"`
|
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNSClientOptions struct {
|
type DNSClientOptions struct {
|
||||||
Strategy DomainStrategy `json:"strategy,omitempty"`
|
Strategy DomainStrategy `json:"strategy,omitempty"`
|
||||||
DisableCache bool `json:"disable_cache,omitempty"`
|
DisableCache bool `json:"disable_cache,omitempty"`
|
||||||
DisableExpire bool `json:"disable_expire,omitempty"`
|
DisableExpire bool `json:"disable_expire,omitempty"`
|
||||||
IndependentCache bool `json:"independent_cache,omitempty"`
|
IndependentCache bool `json:"independent_cache,omitempty"`
|
||||||
ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"`
|
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNSFakeIPOptions struct {
|
type DNSFakeIPOptions struct {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
|
import "github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
type ExperimentalOptions struct {
|
type ExperimentalOptions struct {
|
||||||
CacheFile *CacheFileOptions `json:"cache_file,omitempty"`
|
CacheFile *CacheFileOptions `json:"cache_file,omitempty"`
|
||||||
ClashAPI *ClashAPIOptions `json:"clash_api,omitempty"`
|
ClashAPI *ClashAPIOptions `json:"clash_api,omitempty"`
|
||||||
|
@ -8,24 +10,24 @@ type ExperimentalOptions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CacheFileOptions struct {
|
type CacheFileOptions struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
CacheID string `json:"cache_id,omitempty"`
|
CacheID string `json:"cache_id,omitempty"`
|
||||||
StoreFakeIP bool `json:"store_fakeip,omitempty"`
|
StoreFakeIP bool `json:"store_fakeip,omitempty"`
|
||||||
StoreRDRC bool `json:"store_rdrc,omitempty"`
|
StoreRDRC bool `json:"store_rdrc,omitempty"`
|
||||||
RDRCTimeout Duration `json:"rdrc_timeout,omitempty"`
|
RDRCTimeout badoption.Duration `json:"rdrc_timeout,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClashAPIOptions struct {
|
type ClashAPIOptions struct {
|
||||||
ExternalController string `json:"external_controller,omitempty"`
|
ExternalController string `json:"external_controller,omitempty"`
|
||||||
ExternalUI string `json:"external_ui,omitempty"`
|
ExternalUI string `json:"external_ui,omitempty"`
|
||||||
ExternalUIDownloadURL string `json:"external_ui_download_url,omitempty"`
|
ExternalUIDownloadURL string `json:"external_ui_download_url,omitempty"`
|
||||||
ExternalUIDownloadDetour string `json:"external_ui_download_detour,omitempty"`
|
ExternalUIDownloadDetour string `json:"external_ui_download_detour,omitempty"`
|
||||||
Secret string `json:"secret,omitempty"`
|
Secret string `json:"secret,omitempty"`
|
||||||
DefaultMode string `json:"default_mode,omitempty"`
|
DefaultMode string `json:"default_mode,omitempty"`
|
||||||
ModeList []string `json:"-"`
|
ModeList []string `json:"-"`
|
||||||
AccessControlAllowOrigin Listable[string] `json:"access_control_allow_origin,omitempty"`
|
AccessControlAllowOrigin badoption.Listable[string] `json:"access_control_allow_origin,omitempty"`
|
||||||
AccessControlAllowPrivateNetwork bool `json:"access_control_allow_private_network,omitempty"`
|
AccessControlAllowPrivateNetwork bool `json:"access_control_allow_private_network,omitempty"`
|
||||||
|
|
||||||
// Deprecated: migrated to global cache file
|
// Deprecated: migrated to global cache file
|
||||||
CacheFile string `json:"cache_file,omitempty"`
|
CacheFile string `json:"cache_file,omitempty"`
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
|
import "github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
type SelectorOutboundOptions struct {
|
type SelectorOutboundOptions struct {
|
||||||
Outbounds []string `json:"outbounds"`
|
Outbounds []string `json:"outbounds"`
|
||||||
Default string `json:"default,omitempty"`
|
Default string `json:"default,omitempty"`
|
||||||
|
@ -7,10 +9,10 @@ type SelectorOutboundOptions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type URLTestOutboundOptions struct {
|
type URLTestOutboundOptions struct {
|
||||||
Outbounds []string `json:"outbounds"`
|
Outbounds []string `json:"outbounds"`
|
||||||
URL string `json:"url,omitempty"`
|
URL string `json:"url,omitempty"`
|
||||||
Interval Duration `json:"interval,omitempty"`
|
Interval badoption.Duration `json:"interval,omitempty"`
|
||||||
Tolerance uint16 `json:"tolerance,omitempty"`
|
Tolerance uint16 `json:"tolerance,omitempty"`
|
||||||
IdleTimeout Duration `json:"idle_timeout,omitempty"`
|
IdleTimeout badoption.Duration `json:"idle_timeout,omitempty"`
|
||||||
InterruptExistConnections bool `json:"interrupt_exist_connections,omitempty"`
|
InterruptExistConnections bool `json:"interrupt_exist_connections,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
"github.com/sagernet/sing/common/json/badjson"
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
"github.com/sagernet/sing/service"
|
"github.com/sagernet/sing/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,24 +50,24 @@ func (h *Inbound) UnmarshalJSONContext(ctx context.Context, content []byte) erro
|
||||||
|
|
||||||
// Deprecated: Use rule action instead
|
// Deprecated: Use rule action instead
|
||||||
type InboundOptions struct {
|
type InboundOptions struct {
|
||||||
SniffEnabled bool `json:"sniff,omitempty"`
|
SniffEnabled bool `json:"sniff,omitempty"`
|
||||||
SniffOverrideDestination bool `json:"sniff_override_destination,omitempty"`
|
SniffOverrideDestination bool `json:"sniff_override_destination,omitempty"`
|
||||||
SniffTimeout Duration `json:"sniff_timeout,omitempty"`
|
SniffTimeout badoption.Duration `json:"sniff_timeout,omitempty"`
|
||||||
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
|
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
|
||||||
UDPDisableDomainUnmapping bool `json:"udp_disable_domain_unmapping,omitempty"`
|
UDPDisableDomainUnmapping bool `json:"udp_disable_domain_unmapping,omitempty"`
|
||||||
Detour string `json:"detour,omitempty"`
|
Detour string `json:"detour,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListenOptions struct {
|
type ListenOptions struct {
|
||||||
Listen *ListenAddress `json:"listen,omitempty"`
|
Listen *badoption.Addr `json:"listen,omitempty"`
|
||||||
ListenPort uint16 `json:"listen_port,omitempty"`
|
ListenPort uint16 `json:"listen_port,omitempty"`
|
||||||
TCPKeepAlive Duration `json:"tcp_keep_alive,omitempty"`
|
TCPKeepAlive badoption.Duration `json:"tcp_keep_alive,omitempty"`
|
||||||
TCPKeepAliveInterval Duration `json:"tcp_keep_alive_interval,omitempty"`
|
TCPKeepAliveInterval badoption.Duration `json:"tcp_keep_alive_interval,omitempty"`
|
||||||
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
||||||
TCPMultiPath bool `json:"tcp_multi_path,omitempty"`
|
TCPMultiPath bool `json:"tcp_multi_path,omitempty"`
|
||||||
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
||||||
UDPFragmentDefault bool `json:"-"`
|
UDPFragmentDefault bool `json:"-"`
|
||||||
UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"`
|
UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"`
|
||||||
|
|
||||||
// Deprecated: removed
|
// Deprecated: removed
|
||||||
ProxyProtocol bool `json:"proxy_protocol,omitempty"`
|
ProxyProtocol bool `json:"proxy_protocol,omitempty"`
|
||||||
|
@ -75,7 +76,7 @@ type ListenOptions struct {
|
||||||
InboundOptions
|
InboundOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
type UDPTimeoutCompat Duration
|
type UDPTimeoutCompat badoption.Duration
|
||||||
|
|
||||||
func (c UDPTimeoutCompat) MarshalJSON() ([]byte, error) {
|
func (c UDPTimeoutCompat) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal((time.Duration)(c).String())
|
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))
|
*c = UDPTimeoutCompat(time.Second * time.Duration(valueNumber))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return json.Unmarshal(data, (*Duration)(c))
|
return json.Unmarshal(data, (*badoption.Duration)(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListenOptionsWrapper interface {
|
type ListenOptionsWrapper interface {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
|
import "github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
type NTPOptions struct {
|
type NTPOptions struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
Interval Duration `json:"interval,omitempty"`
|
Interval badoption.Duration `json:"interval,omitempty"`
|
||||||
WriteToSystem bool `json:"write_to_system,omitempty"`
|
WriteToSystem bool `json:"write_to_system,omitempty"`
|
||||||
ServerOptions
|
ServerOptions
|
||||||
DialerOptions
|
DialerOptions
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
"github.com/sagernet/sing/common/json/badjson"
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
"github.com/sagernet/sing/service"
|
"github.com/sagernet/sing/service"
|
||||||
)
|
)
|
||||||
|
@ -64,21 +65,21 @@ type DialerOptionsWrapper interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DialerOptions struct {
|
type DialerOptions struct {
|
||||||
Detour string `json:"detour,omitempty"`
|
Detour string `json:"detour,omitempty"`
|
||||||
BindInterface string `json:"bind_interface,omitempty"`
|
BindInterface string `json:"bind_interface,omitempty"`
|
||||||
Inet4BindAddress *ListenAddress `json:"inet4_bind_address,omitempty"`
|
Inet4BindAddress *badoption.Addr `json:"inet4_bind_address,omitempty"`
|
||||||
Inet6BindAddress *ListenAddress `json:"inet6_bind_address,omitempty"`
|
Inet6BindAddress *badoption.Addr `json:"inet6_bind_address,omitempty"`
|
||||||
ProtectPath string `json:"protect_path,omitempty"`
|
ProtectPath string `json:"protect_path,omitempty"`
|
||||||
RoutingMark uint32 `json:"routing_mark,omitempty"`
|
RoutingMark uint32 `json:"routing_mark,omitempty"`
|
||||||
ReuseAddr bool `json:"reuse_addr,omitempty"`
|
ReuseAddr bool `json:"reuse_addr,omitempty"`
|
||||||
ConnectTimeout Duration `json:"connect_timeout,omitempty"`
|
ConnectTimeout badoption.Duration `json:"connect_timeout,omitempty"`
|
||||||
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
||||||
TCPMultiPath bool `json:"tcp_multi_path,omitempty"`
|
TCPMultiPath bool `json:"tcp_multi_path,omitempty"`
|
||||||
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
||||||
UDPFragmentDefault bool `json:"-"`
|
UDPFragmentDefault bool `json:"-"`
|
||||||
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
|
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
|
||||||
FallbackDelay Duration `json:"fallback_delay,omitempty"`
|
FallbackDelay badoption.Duration `json:"fallback_delay,omitempty"`
|
||||||
IsWireGuardListener bool `json:"-"`
|
IsWireGuardListener bool `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *DialerOptions) TakeDialerOptions() DialerOptions {
|
func (o *DialerOptions) TakeDialerOptions() DialerOptions {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package option
|
||||||
import (
|
import (
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OnDemandOptions struct {
|
type OnDemandOptions struct {
|
||||||
|
@ -12,10 +13,10 @@ type OnDemandOptions struct {
|
||||||
|
|
||||||
type OnDemandRule struct {
|
type OnDemandRule struct {
|
||||||
Action *OnDemandRuleAction `json:"action,omitempty"`
|
Action *OnDemandRuleAction `json:"action,omitempty"`
|
||||||
DNSSearchDomainMatch Listable[string] `json:"dns_search_domain_match,omitempty"`
|
DNSSearchDomainMatch badoption.Listable[string] `json:"dns_search_domain_match,omitempty"`
|
||||||
DNSServerAddressMatch Listable[string] `json:"dns_server_address_match,omitempty"`
|
DNSServerAddressMatch badoption.Listable[string] `json:"dns_server_address_match,omitempty"`
|
||||||
InterfaceTypeMatch *OnDemandRuleInterfaceType `json:"interface_type_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"`
|
ProbeURL string `json:"probe_url,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
"github.com/sagernet/sing/common/json/badjson"
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _Rule struct {
|
type _Rule struct {
|
||||||
|
@ -66,39 +67,39 @@ func (r Rule) IsValid() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RawDefaultRule struct {
|
type RawDefaultRule struct {
|
||||||
Inbound Listable[string] `json:"inbound,omitempty"`
|
Inbound badoption.Listable[string] `json:"inbound,omitempty"`
|
||||||
IPVersion int `json:"ip_version,omitempty"`
|
IPVersion int `json:"ip_version,omitempty"`
|
||||||
Network Listable[string] `json:"network,omitempty"`
|
Network badoption.Listable[string] `json:"network,omitempty"`
|
||||||
AuthUser Listable[string] `json:"auth_user,omitempty"`
|
AuthUser badoption.Listable[string] `json:"auth_user,omitempty"`
|
||||||
Protocol Listable[string] `json:"protocol,omitempty"`
|
Protocol badoption.Listable[string] `json:"protocol,omitempty"`
|
||||||
Client Listable[string] `json:"client,omitempty"`
|
Client badoption.Listable[string] `json:"client,omitempty"`
|
||||||
Domain Listable[string] `json:"domain,omitempty"`
|
Domain badoption.Listable[string] `json:"domain,omitempty"`
|
||||||
DomainSuffix Listable[string] `json:"domain_suffix,omitempty"`
|
DomainSuffix badoption.Listable[string] `json:"domain_suffix,omitempty"`
|
||||||
DomainKeyword Listable[string] `json:"domain_keyword,omitempty"`
|
DomainKeyword badoption.Listable[string] `json:"domain_keyword,omitempty"`
|
||||||
DomainRegex Listable[string] `json:"domain_regex,omitempty"`
|
DomainRegex badoption.Listable[string] `json:"domain_regex,omitempty"`
|
||||||
Geosite Listable[string] `json:"geosite,omitempty"`
|
Geosite badoption.Listable[string] `json:"geosite,omitempty"`
|
||||||
SourceGeoIP Listable[string] `json:"source_geoip,omitempty"`
|
SourceGeoIP badoption.Listable[string] `json:"source_geoip,omitempty"`
|
||||||
GeoIP Listable[string] `json:"geoip,omitempty"`
|
GeoIP badoption.Listable[string] `json:"geoip,omitempty"`
|
||||||
SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"`
|
SourceIPCIDR badoption.Listable[string] `json:"source_ip_cidr,omitempty"`
|
||||||
SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"`
|
SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"`
|
||||||
IPCIDR Listable[string] `json:"ip_cidr,omitempty"`
|
IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"`
|
||||||
IPIsPrivate bool `json:"ip_is_private,omitempty"`
|
IPIsPrivate bool `json:"ip_is_private,omitempty"`
|
||||||
SourcePort Listable[uint16] `json:"source_port,omitempty"`
|
SourcePort badoption.Listable[uint16] `json:"source_port,omitempty"`
|
||||||
SourcePortRange Listable[string] `json:"source_port_range,omitempty"`
|
SourcePortRange badoption.Listable[string] `json:"source_port_range,omitempty"`
|
||||||
Port Listable[uint16] `json:"port,omitempty"`
|
Port badoption.Listable[uint16] `json:"port,omitempty"`
|
||||||
PortRange Listable[string] `json:"port_range,omitempty"`
|
PortRange badoption.Listable[string] `json:"port_range,omitempty"`
|
||||||
ProcessName Listable[string] `json:"process_name,omitempty"`
|
ProcessName badoption.Listable[string] `json:"process_name,omitempty"`
|
||||||
ProcessPath Listable[string] `json:"process_path,omitempty"`
|
ProcessPath badoption.Listable[string] `json:"process_path,omitempty"`
|
||||||
ProcessPathRegex Listable[string] `json:"process_path_regex,omitempty"`
|
ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"`
|
||||||
PackageName Listable[string] `json:"package_name,omitempty"`
|
PackageName badoption.Listable[string] `json:"package_name,omitempty"`
|
||||||
User Listable[string] `json:"user,omitempty"`
|
User badoption.Listable[string] `json:"user,omitempty"`
|
||||||
UserID Listable[int32] `json:"user_id,omitempty"`
|
UserID badoption.Listable[int32] `json:"user_id,omitempty"`
|
||||||
ClashMode string `json:"clash_mode,omitempty"`
|
ClashMode string `json:"clash_mode,omitempty"`
|
||||||
WIFISSID Listable[string] `json:"wifi_ssid,omitempty"`
|
WIFISSID badoption.Listable[string] `json:"wifi_ssid,omitempty"`
|
||||||
WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"`
|
WIFIBSSID badoption.Listable[string] `json:"wifi_bssid,omitempty"`
|
||||||
RuleSet Listable[string] `json:"rule_set,omitempty"`
|
RuleSet badoption.Listable[string] `json:"rule_set,omitempty"`
|
||||||
RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"`
|
RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"`
|
||||||
Invert bool `json:"invert,omitempty"`
|
Invert bool `json:"invert,omitempty"`
|
||||||
|
|
||||||
// Deprecated: renamed to rule_set_ip_cidr_match_source
|
// Deprecated: renamed to rule_set_ip_cidr_match_source
|
||||||
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
|
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
|
||||||
|
|
|
@ -3,6 +3,7 @@ package option
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
@ -11,6 +12,7 @@ import (
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
"github.com/sagernet/sing/common/json/badjson"
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _RuleAction struct {
|
type _RuleAction struct {
|
||||||
|
@ -177,7 +179,7 @@ type _DNSRouteActionOptions struct {
|
||||||
// Deprecated: Use DNSRouteOptionsActionOptions instead.
|
// Deprecated: Use DNSRouteOptionsActionOptions instead.
|
||||||
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
|
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
|
||||||
// Deprecated: Use DNSRouteOptionsActionOptions instead.
|
// Deprecated: Use DNSRouteOptionsActionOptions instead.
|
||||||
ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"`
|
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNSRouteActionOptions _DNSRouteActionOptions
|
type DNSRouteActionOptions _DNSRouteActionOptions
|
||||||
|
@ -197,9 +199,9 @@ func (r *DNSRouteActionOptions) UnmarshalJSONContext(ctx context.Context, data [
|
||||||
}
|
}
|
||||||
|
|
||||||
type _DNSRouteOptionsActionOptions struct {
|
type _DNSRouteOptionsActionOptions struct {
|
||||||
DisableCache bool `json:"disable_cache,omitempty"`
|
DisableCache bool `json:"disable_cache,omitempty"`
|
||||||
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
|
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
|
||||||
ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"`
|
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNSRouteOptionsActionOptions _DNSRouteOptionsActionOptions
|
type DNSRouteOptionsActionOptions _DNSRouteOptionsActionOptions
|
||||||
|
@ -225,10 +227,10 @@ func (d DirectActionOptions) Descriptions() []string {
|
||||||
descriptions = append(descriptions, "bind_interface="+d.BindInterface)
|
descriptions = append(descriptions, "bind_interface="+d.BindInterface)
|
||||||
}
|
}
|
||||||
if d.Inet4BindAddress != nil {
|
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 {
|
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 {
|
if d.RoutingMark != 0 {
|
||||||
descriptions = append(descriptions, "routing_mark="+fmt.Sprintf("0x%x", d.RoutingMark))
|
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 {
|
type RouteActionSniff struct {
|
||||||
Sniffer Listable[string] `json:"sniffer,omitempty"`
|
Sniffer badoption.Listable[string] `json:"sniffer,omitempty"`
|
||||||
Timeout Duration `json:"timeout,omitempty"`
|
Timeout badoption.Duration `json:"timeout,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RouteActionResolve struct {
|
type RouteActionResolve struct {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
"github.com/sagernet/sing/common/json/badjson"
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _DNSRule struct {
|
type _DNSRule struct {
|
||||||
|
@ -67,41 +68,41 @@ func (r DNSRule) IsValid() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RawDefaultDNSRule struct {
|
type RawDefaultDNSRule struct {
|
||||||
Inbound Listable[string] `json:"inbound,omitempty"`
|
Inbound badoption.Listable[string] `json:"inbound,omitempty"`
|
||||||
IPVersion int `json:"ip_version,omitempty"`
|
IPVersion int `json:"ip_version,omitempty"`
|
||||||
QueryType Listable[DNSQueryType] `json:"query_type,omitempty"`
|
QueryType badoption.Listable[DNSQueryType] `json:"query_type,omitempty"`
|
||||||
Network Listable[string] `json:"network,omitempty"`
|
Network badoption.Listable[string] `json:"network,omitempty"`
|
||||||
AuthUser Listable[string] `json:"auth_user,omitempty"`
|
AuthUser badoption.Listable[string] `json:"auth_user,omitempty"`
|
||||||
Protocol Listable[string] `json:"protocol,omitempty"`
|
Protocol badoption.Listable[string] `json:"protocol,omitempty"`
|
||||||
Domain Listable[string] `json:"domain,omitempty"`
|
Domain badoption.Listable[string] `json:"domain,omitempty"`
|
||||||
DomainSuffix Listable[string] `json:"domain_suffix,omitempty"`
|
DomainSuffix badoption.Listable[string] `json:"domain_suffix,omitempty"`
|
||||||
DomainKeyword Listable[string] `json:"domain_keyword,omitempty"`
|
DomainKeyword badoption.Listable[string] `json:"domain_keyword,omitempty"`
|
||||||
DomainRegex Listable[string] `json:"domain_regex,omitempty"`
|
DomainRegex badoption.Listable[string] `json:"domain_regex,omitempty"`
|
||||||
Geosite Listable[string] `json:"geosite,omitempty"`
|
Geosite badoption.Listable[string] `json:"geosite,omitempty"`
|
||||||
SourceGeoIP Listable[string] `json:"source_geoip,omitempty"`
|
SourceGeoIP badoption.Listable[string] `json:"source_geoip,omitempty"`
|
||||||
GeoIP Listable[string] `json:"geoip,omitempty"`
|
GeoIP badoption.Listable[string] `json:"geoip,omitempty"`
|
||||||
IPCIDR Listable[string] `json:"ip_cidr,omitempty"`
|
IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"`
|
||||||
IPIsPrivate bool `json:"ip_is_private,omitempty"`
|
IPIsPrivate bool `json:"ip_is_private,omitempty"`
|
||||||
SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"`
|
SourceIPCIDR badoption.Listable[string] `json:"source_ip_cidr,omitempty"`
|
||||||
SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"`
|
SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"`
|
||||||
SourcePort Listable[uint16] `json:"source_port,omitempty"`
|
SourcePort badoption.Listable[uint16] `json:"source_port,omitempty"`
|
||||||
SourcePortRange Listable[string] `json:"source_port_range,omitempty"`
|
SourcePortRange badoption.Listable[string] `json:"source_port_range,omitempty"`
|
||||||
Port Listable[uint16] `json:"port,omitempty"`
|
Port badoption.Listable[uint16] `json:"port,omitempty"`
|
||||||
PortRange Listable[string] `json:"port_range,omitempty"`
|
PortRange badoption.Listable[string] `json:"port_range,omitempty"`
|
||||||
ProcessName Listable[string] `json:"process_name,omitempty"`
|
ProcessName badoption.Listable[string] `json:"process_name,omitempty"`
|
||||||
ProcessPath Listable[string] `json:"process_path,omitempty"`
|
ProcessPath badoption.Listable[string] `json:"process_path,omitempty"`
|
||||||
ProcessPathRegex Listable[string] `json:"process_path_regex,omitempty"`
|
ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"`
|
||||||
PackageName Listable[string] `json:"package_name,omitempty"`
|
PackageName badoption.Listable[string] `json:"package_name,omitempty"`
|
||||||
User Listable[string] `json:"user,omitempty"`
|
User badoption.Listable[string] `json:"user,omitempty"`
|
||||||
UserID Listable[int32] `json:"user_id,omitempty"`
|
UserID badoption.Listable[int32] `json:"user_id,omitempty"`
|
||||||
Outbound Listable[string] `json:"outbound,omitempty"`
|
Outbound badoption.Listable[string] `json:"outbound,omitempty"`
|
||||||
ClashMode string `json:"clash_mode,omitempty"`
|
ClashMode string `json:"clash_mode,omitempty"`
|
||||||
WIFISSID Listable[string] `json:"wifi_ssid,omitempty"`
|
WIFISSID badoption.Listable[string] `json:"wifi_ssid,omitempty"`
|
||||||
WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"`
|
WIFIBSSID badoption.Listable[string] `json:"wifi_bssid,omitempty"`
|
||||||
RuleSet Listable[string] `json:"rule_set,omitempty"`
|
RuleSet badoption.Listable[string] `json:"rule_set,omitempty"`
|
||||||
RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"`
|
RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"`
|
||||||
RuleSetIPCIDRAcceptEmpty bool `json:"rule_set_ip_cidr_accept_empty,omitempty"`
|
RuleSetIPCIDRAcceptEmpty bool `json:"rule_set_ip_cidr_accept_empty,omitempty"`
|
||||||
Invert bool `json:"invert,omitempty"`
|
Invert bool `json:"invert,omitempty"`
|
||||||
|
|
||||||
// Deprecated: renamed to rule_set_ip_cidr_match_source
|
// Deprecated: renamed to rule_set_ip_cidr_match_source
|
||||||
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
|
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
F "github.com/sagernet/sing/common/format"
|
F "github.com/sagernet/sing/common/format"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
"github.com/sagernet/sing/common/json/badjson"
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
"go4.org/netipx"
|
"go4.org/netipx"
|
||||||
)
|
)
|
||||||
|
@ -84,9 +85,9 @@ type LocalRuleSet struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RemoteRuleSet struct {
|
type RemoteRuleSet struct {
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
DownloadDetour string `json:"download_detour,omitempty"`
|
DownloadDetour string `json:"download_detour,omitempty"`
|
||||||
UpdateInterval Duration `json:"update_interval,omitempty"`
|
UpdateInterval badoption.Duration `json:"update_interval,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type _HeadlessRule struct {
|
type _HeadlessRule struct {
|
||||||
|
@ -145,32 +146,32 @@ func (r HeadlessRule) IsValid() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DefaultHeadlessRule struct {
|
type DefaultHeadlessRule struct {
|
||||||
QueryType Listable[DNSQueryType] `json:"query_type,omitempty"`
|
QueryType badoption.Listable[DNSQueryType] `json:"query_type,omitempty"`
|
||||||
Network Listable[string] `json:"network,omitempty"`
|
Network badoption.Listable[string] `json:"network,omitempty"`
|
||||||
Domain Listable[string] `json:"domain,omitempty"`
|
Domain badoption.Listable[string] `json:"domain,omitempty"`
|
||||||
DomainSuffix Listable[string] `json:"domain_suffix,omitempty"`
|
DomainSuffix badoption.Listable[string] `json:"domain_suffix,omitempty"`
|
||||||
DomainKeyword Listable[string] `json:"domain_keyword,omitempty"`
|
DomainKeyword badoption.Listable[string] `json:"domain_keyword,omitempty"`
|
||||||
DomainRegex Listable[string] `json:"domain_regex,omitempty"`
|
DomainRegex badoption.Listable[string] `json:"domain_regex,omitempty"`
|
||||||
SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"`
|
SourceIPCIDR badoption.Listable[string] `json:"source_ip_cidr,omitempty"`
|
||||||
IPCIDR Listable[string] `json:"ip_cidr,omitempty"`
|
IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"`
|
||||||
SourcePort Listable[uint16] `json:"source_port,omitempty"`
|
SourcePort badoption.Listable[uint16] `json:"source_port,omitempty"`
|
||||||
SourcePortRange Listable[string] `json:"source_port_range,omitempty"`
|
SourcePortRange badoption.Listable[string] `json:"source_port_range,omitempty"`
|
||||||
Port Listable[uint16] `json:"port,omitempty"`
|
Port badoption.Listable[uint16] `json:"port,omitempty"`
|
||||||
PortRange Listable[string] `json:"port_range,omitempty"`
|
PortRange badoption.Listable[string] `json:"port_range,omitempty"`
|
||||||
ProcessName Listable[string] `json:"process_name,omitempty"`
|
ProcessName badoption.Listable[string] `json:"process_name,omitempty"`
|
||||||
ProcessPath Listable[string] `json:"process_path,omitempty"`
|
ProcessPath badoption.Listable[string] `json:"process_path,omitempty"`
|
||||||
ProcessPathRegex Listable[string] `json:"process_path_regex,omitempty"`
|
ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"`
|
||||||
PackageName Listable[string] `json:"package_name,omitempty"`
|
PackageName badoption.Listable[string] `json:"package_name,omitempty"`
|
||||||
WIFISSID Listable[string] `json:"wifi_ssid,omitempty"`
|
WIFISSID badoption.Listable[string] `json:"wifi_ssid,omitempty"`
|
||||||
WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"`
|
WIFIBSSID badoption.Listable[string] `json:"wifi_bssid,omitempty"`
|
||||||
Invert bool `json:"invert,omitempty"`
|
Invert bool `json:"invert,omitempty"`
|
||||||
|
|
||||||
DomainMatcher *domain.Matcher `json:"-"`
|
DomainMatcher *domain.Matcher `json:"-"`
|
||||||
SourceIPSet *netipx.IPSet `json:"-"`
|
SourceIPSet *netipx.IPSet `json:"-"`
|
||||||
IPSet *netipx.IPSet `json:"-"`
|
IPSet *netipx.IPSet `json:"-"`
|
||||||
|
|
||||||
AdGuardDomain Listable[string] `json:"-"`
|
AdGuardDomain badoption.Listable[string] `json:"-"`
|
||||||
AdGuardDomainMatcher *domain.AdGuardMatcher `json:"-"`
|
AdGuardDomainMatcher *domain.AdGuardMatcher `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r DefaultHeadlessRule) IsValid() bool {
|
func (r DefaultHeadlessRule) IsValid() bool {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package option
|
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 {
|
type SocksInboundOptions struct {
|
||||||
ListenOptions
|
ListenOptions
|
||||||
|
@ -30,6 +33,6 @@ type HTTPOutboundOptions struct {
|
||||||
Username string `json:"username,omitempty"`
|
Username string `json:"username,omitempty"`
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
OutboundTLSOptionsContainer
|
OutboundTLSOptionsContainer
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Headers HTTPHeader `json:"headers,omitempty"`
|
Headers badoption.HTTPHeader `json:"headers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
|
import "github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
type SSHOutboundOptions struct {
|
type SSHOutboundOptions struct {
|
||||||
DialerOptions
|
DialerOptions
|
||||||
ServerOptions
|
ServerOptions
|
||||||
User string `json:"user,omitempty"`
|
User string `json:"user,omitempty"`
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
PrivateKey Listable[string] `json:"private_key,omitempty"`
|
PrivateKey badoption.Listable[string] `json:"private_key,omitempty"`
|
||||||
PrivateKeyPath string `json:"private_key_path,omitempty"`
|
PrivateKeyPath string `json:"private_key_path,omitempty"`
|
||||||
PrivateKeyPassphrase string `json:"private_key_passphrase,omitempty"`
|
PrivateKeyPassphrase string `json:"private_key_passphrase,omitempty"`
|
||||||
HostKey Listable[string] `json:"host_key,omitempty"`
|
HostKey badoption.Listable[string] `json:"host_key,omitempty"`
|
||||||
HostKeyAlgorithms Listable[string] `json:"host_key_algorithms,omitempty"`
|
HostKeyAlgorithms badoption.Listable[string] `json:"host_key_algorithms,omitempty"`
|
||||||
ClientVersion string `json:"client_version,omitempty"`
|
ClientVersion string `json:"client_version,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -1,20 +1,22 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
|
import "github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
type InboundTLSOptions struct {
|
type InboundTLSOptions struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
ServerName string `json:"server_name,omitempty"`
|
ServerName string `json:"server_name,omitempty"`
|
||||||
Insecure bool `json:"insecure,omitempty"`
|
Insecure bool `json:"insecure,omitempty"`
|
||||||
ALPN Listable[string] `json:"alpn,omitempty"`
|
ALPN badoption.Listable[string] `json:"alpn,omitempty"`
|
||||||
MinVersion string `json:"min_version,omitempty"`
|
MinVersion string `json:"min_version,omitempty"`
|
||||||
MaxVersion string `json:"max_version,omitempty"`
|
MaxVersion string `json:"max_version,omitempty"`
|
||||||
CipherSuites Listable[string] `json:"cipher_suites,omitempty"`
|
CipherSuites badoption.Listable[string] `json:"cipher_suites,omitempty"`
|
||||||
Certificate Listable[string] `json:"certificate,omitempty"`
|
Certificate badoption.Listable[string] `json:"certificate,omitempty"`
|
||||||
CertificatePath string `json:"certificate_path,omitempty"`
|
CertificatePath string `json:"certificate_path,omitempty"`
|
||||||
Key Listable[string] `json:"key,omitempty"`
|
Key badoption.Listable[string] `json:"key,omitempty"`
|
||||||
KeyPath string `json:"key_path,omitempty"`
|
KeyPath string `json:"key_path,omitempty"`
|
||||||
ACME *InboundACMEOptions `json:"acme,omitempty"`
|
ACME *InboundACMEOptions `json:"acme,omitempty"`
|
||||||
ECH *InboundECHOptions `json:"ech,omitempty"`
|
ECH *InboundECHOptions `json:"ech,omitempty"`
|
||||||
Reality *InboundRealityOptions `json:"reality,omitempty"`
|
Reality *InboundRealityOptions `json:"reality,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type InboundTLSOptionsContainer struct {
|
type InboundTLSOptionsContainer struct {
|
||||||
|
@ -35,19 +37,19 @@ func (o *InboundTLSOptionsContainer) ReplaceInboundTLSOptions(options *InboundTL
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundTLSOptions struct {
|
type OutboundTLSOptions struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
DisableSNI bool `json:"disable_sni,omitempty"`
|
DisableSNI bool `json:"disable_sni,omitempty"`
|
||||||
ServerName string `json:"server_name,omitempty"`
|
ServerName string `json:"server_name,omitempty"`
|
||||||
Insecure bool `json:"insecure,omitempty"`
|
Insecure bool `json:"insecure,omitempty"`
|
||||||
ALPN Listable[string] `json:"alpn,omitempty"`
|
ALPN badoption.Listable[string] `json:"alpn,omitempty"`
|
||||||
MinVersion string `json:"min_version,omitempty"`
|
MinVersion string `json:"min_version,omitempty"`
|
||||||
MaxVersion string `json:"max_version,omitempty"`
|
MaxVersion string `json:"max_version,omitempty"`
|
||||||
CipherSuites Listable[string] `json:"cipher_suites,omitempty"`
|
CipherSuites badoption.Listable[string] `json:"cipher_suites,omitempty"`
|
||||||
Certificate Listable[string] `json:"certificate,omitempty"`
|
Certificate badoption.Listable[string] `json:"certificate,omitempty"`
|
||||||
CertificatePath string `json:"certificate_path,omitempty"`
|
CertificatePath string `json:"certificate_path,omitempty"`
|
||||||
ECH *OutboundECHOptions `json:"ech,omitempty"`
|
ECH *OutboundECHOptions `json:"ech,omitempty"`
|
||||||
UTLS *OutboundUTLSOptions `json:"utls,omitempty"`
|
UTLS *OutboundUTLSOptions `json:"utls,omitempty"`
|
||||||
Reality *OutboundRealityOptions `json:"reality,omitempty"`
|
Reality *OutboundRealityOptions `json:"reality,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundTLSOptionsContainer struct {
|
type OutboundTLSOptionsContainer struct {
|
||||||
|
@ -71,8 +73,8 @@ type InboundRealityOptions struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
Handshake InboundRealityHandshakeOptions `json:"handshake,omitempty"`
|
Handshake InboundRealityHandshakeOptions `json:"handshake,omitempty"`
|
||||||
PrivateKey string `json:"private_key,omitempty"`
|
PrivateKey string `json:"private_key,omitempty"`
|
||||||
ShortID Listable[string] `json:"short_id,omitempty"`
|
ShortID badoption.Listable[string] `json:"short_id,omitempty"`
|
||||||
MaxTimeDifference Duration `json:"max_time_difference,omitempty"`
|
MaxTimeDifference badoption.Duration `json:"max_time_difference,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type InboundRealityHandshakeOptions struct {
|
type InboundRealityHandshakeOptions struct {
|
||||||
|
@ -81,19 +83,19 @@ type InboundRealityHandshakeOptions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type InboundECHOptions struct {
|
type InboundECHOptions struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"`
|
PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"`
|
||||||
DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"`
|
DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"`
|
||||||
Key Listable[string] `json:"key,omitempty"`
|
Key badoption.Listable[string] `json:"key,omitempty"`
|
||||||
KeyPath string `json:"key_path,omitempty"`
|
KeyPath string `json:"key_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundECHOptions struct {
|
type OutboundECHOptions struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"`
|
PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"`
|
||||||
DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"`
|
DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"`
|
||||||
Config Listable[string] `json:"config,omitempty"`
|
Config badoption.Listable[string] `json:"config,omitempty"`
|
||||||
ConfigPath string `json:"config_path,omitempty"`
|
ConfigPath string `json:"config_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundUTLSOptions struct {
|
type OutboundUTLSOptions struct {
|
||||||
|
|
|
@ -5,10 +5,11 @@ import (
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
"github.com/sagernet/sing/common/json/badjson"
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InboundACMEOptions struct {
|
type InboundACMEOptions struct {
|
||||||
Domain Listable[string] `json:"domain,omitempty"`
|
Domain badoption.Listable[string] `json:"domain,omitempty"`
|
||||||
DataDirectory string `json:"data_directory,omitempty"`
|
DataDirectory string `json:"data_directory,omitempty"`
|
||||||
DefaultServerName string `json:"default_server_name,omitempty"`
|
DefaultServerName string `json:"default_server_name,omitempty"`
|
||||||
Email string `json:"email,omitempty"`
|
Email string `json:"email,omitempty"`
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
|
import "github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
type TUICInboundOptions struct {
|
type TUICInboundOptions struct {
|
||||||
ListenOptions
|
ListenOptions
|
||||||
Users []TUICUser `json:"users,omitempty"`
|
Users []TUICUser `json:"users,omitempty"`
|
||||||
CongestionControl string `json:"congestion_control,omitempty"`
|
CongestionControl string `json:"congestion_control,omitempty"`
|
||||||
AuthTimeout Duration `json:"auth_timeout,omitempty"`
|
AuthTimeout badoption.Duration `json:"auth_timeout,omitempty"`
|
||||||
ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"`
|
ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"`
|
||||||
Heartbeat Duration `json:"heartbeat,omitempty"`
|
Heartbeat badoption.Duration `json:"heartbeat,omitempty"`
|
||||||
InboundTLSOptionsContainer
|
InboundTLSOptionsContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,13 +21,13 @@ type TUICUser struct {
|
||||||
type TUICOutboundOptions struct {
|
type TUICOutboundOptions struct {
|
||||||
DialerOptions
|
DialerOptions
|
||||||
ServerOptions
|
ServerOptions
|
||||||
UUID string `json:"uuid,omitempty"`
|
UUID string `json:"uuid,omitempty"`
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
CongestionControl string `json:"congestion_control,omitempty"`
|
CongestionControl string `json:"congestion_control,omitempty"`
|
||||||
UDPRelayMode string `json:"udp_relay_mode,omitempty"`
|
UDPRelayMode string `json:"udp_relay_mode,omitempty"`
|
||||||
UDPOverStream bool `json:"udp_over_stream,omitempty"`
|
UDPOverStream bool `json:"udp_over_stream,omitempty"`
|
||||||
ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"`
|
ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"`
|
||||||
Heartbeat Duration `json:"heartbeat,omitempty"`
|
Heartbeat badoption.Duration `json:"heartbeat,omitempty"`
|
||||||
Network NetworkList `json:"network,omitempty"`
|
Network NetworkList `json:"network,omitempty"`
|
||||||
OutboundTLSOptionsContainer
|
OutboundTLSOptionsContainer
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,51 +7,52 @@ import (
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
F "github.com/sagernet/sing/common/format"
|
F "github.com/sagernet/sing/common/format"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TunInboundOptions struct {
|
type TunInboundOptions struct {
|
||||||
InterfaceName string `json:"interface_name,omitempty"`
|
InterfaceName string `json:"interface_name,omitempty"`
|
||||||
MTU uint32 `json:"mtu,omitempty"`
|
MTU uint32 `json:"mtu,omitempty"`
|
||||||
GSO bool `json:"gso,omitempty"`
|
GSO bool `json:"gso,omitempty"`
|
||||||
Address Listable[netip.Prefix] `json:"address,omitempty"`
|
Address badoption.Listable[netip.Prefix] `json:"address,omitempty"`
|
||||||
AutoRoute bool `json:"auto_route,omitempty"`
|
AutoRoute bool `json:"auto_route,omitempty"`
|
||||||
IPRoute2TableIndex int `json:"iproute2_table_index,omitempty"`
|
IPRoute2TableIndex int `json:"iproute2_table_index,omitempty"`
|
||||||
IPRoute2RuleIndex int `json:"iproute2_rule_index,omitempty"`
|
IPRoute2RuleIndex int `json:"iproute2_rule_index,omitempty"`
|
||||||
AutoRedirect bool `json:"auto_redirect,omitempty"`
|
AutoRedirect bool `json:"auto_redirect,omitempty"`
|
||||||
AutoRedirectInputMark FwMark `json:"auto_redirect_input_mark,omitempty"`
|
AutoRedirectInputMark FwMark `json:"auto_redirect_input_mark,omitempty"`
|
||||||
AutoRedirectOutputMark FwMark `json:"auto_redirect_output_mark,omitempty"`
|
AutoRedirectOutputMark FwMark `json:"auto_redirect_output_mark,omitempty"`
|
||||||
StrictRoute bool `json:"strict_route,omitempty"`
|
StrictRoute bool `json:"strict_route,omitempty"`
|
||||||
RouteAddress Listable[netip.Prefix] `json:"route_address,omitempty"`
|
RouteAddress badoption.Listable[netip.Prefix] `json:"route_address,omitempty"`
|
||||||
RouteAddressSet Listable[string] `json:"route_address_set,omitempty"`
|
RouteAddressSet badoption.Listable[string] `json:"route_address_set,omitempty"`
|
||||||
RouteExcludeAddress Listable[netip.Prefix] `json:"route_exclude_address,omitempty"`
|
RouteExcludeAddress badoption.Listable[netip.Prefix] `json:"route_exclude_address,omitempty"`
|
||||||
RouteExcludeAddressSet Listable[string] `json:"route_exclude_address_set,omitempty"`
|
RouteExcludeAddressSet badoption.Listable[string] `json:"route_exclude_address_set,omitempty"`
|
||||||
IncludeInterface Listable[string] `json:"include_interface,omitempty"`
|
IncludeInterface badoption.Listable[string] `json:"include_interface,omitempty"`
|
||||||
ExcludeInterface Listable[string] `json:"exclude_interface,omitempty"`
|
ExcludeInterface badoption.Listable[string] `json:"exclude_interface,omitempty"`
|
||||||
IncludeUID Listable[uint32] `json:"include_uid,omitempty"`
|
IncludeUID badoption.Listable[uint32] `json:"include_uid,omitempty"`
|
||||||
IncludeUIDRange Listable[string] `json:"include_uid_range,omitempty"`
|
IncludeUIDRange badoption.Listable[string] `json:"include_uid_range,omitempty"`
|
||||||
ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"`
|
ExcludeUID badoption.Listable[uint32] `json:"exclude_uid,omitempty"`
|
||||||
ExcludeUIDRange Listable[string] `json:"exclude_uid_range,omitempty"`
|
ExcludeUIDRange badoption.Listable[string] `json:"exclude_uid_range,omitempty"`
|
||||||
IncludeAndroidUser Listable[int] `json:"include_android_user,omitempty"`
|
IncludeAndroidUser badoption.Listable[int] `json:"include_android_user,omitempty"`
|
||||||
IncludePackage Listable[string] `json:"include_package,omitempty"`
|
IncludePackage badoption.Listable[string] `json:"include_package,omitempty"`
|
||||||
ExcludePackage Listable[string] `json:"exclude_package,omitempty"`
|
ExcludePackage badoption.Listable[string] `json:"exclude_package,omitempty"`
|
||||||
EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"`
|
EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"`
|
||||||
UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"`
|
UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"`
|
||||||
Stack string `json:"stack,omitempty"`
|
Stack string `json:"stack,omitempty"`
|
||||||
Platform *TunPlatformOptions `json:"platform,omitempty"`
|
Platform *TunPlatformOptions `json:"platform,omitempty"`
|
||||||
InboundOptions
|
InboundOptions
|
||||||
|
|
||||||
// Deprecated: merged to Address
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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
|
type FwMark uint32
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
|
import "github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
type TunPlatformOptions struct {
|
type TunPlatformOptions struct {
|
||||||
HTTPProxy *HTTPProxyOptions `json:"http_proxy,omitempty"`
|
HTTPProxy *HTTPProxyOptions `json:"http_proxy,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -7,6 +9,6 @@ type TunPlatformOptions struct {
|
||||||
type HTTPProxyOptions struct {
|
type HTTPProxyOptions struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
ServerOptions
|
ServerOptions
|
||||||
BypassDomain Listable[string] `json:"bypass_domain,omitempty"`
|
BypassDomain badoption.Listable[string] `json:"bypass_domain,omitempty"`
|
||||||
MatchDomain Listable[string] `json:"match_domain,omitempty"`
|
MatchDomain badoption.Listable[string] `json:"match_domain,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
132
option/types.go
132
option/types.go
|
@ -1,10 +1,7 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
|
||||||
"net/netip"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/sagernet/sing-dns"
|
"github.com/sagernet/sing-dns"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
@ -15,79 +12,6 @@ import (
|
||||||
mDNS "github.com/miekg/dns"
|
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
|
type NetworkList string
|
||||||
|
|
||||||
func (v *NetworkList) UnmarshalJSON(content []byte) error {
|
func (v *NetworkList) UnmarshalJSON(content []byte) error {
|
||||||
|
@ -120,30 +44,6 @@ func (v NetworkList) Build() []string {
|
||||||
return strings.Split(string(v), "\n")
|
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
|
type DomainStrategy dns.DomainStrategy
|
||||||
|
|
||||||
func (s DomainStrategy) String() string {
|
func (s DomainStrategy) String() string {
|
||||||
|
@ -206,26 +106,6 @@ func (s *DomainStrategy) UnmarshalJSON(bytes []byte) error {
|
||||||
return nil
|
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
|
type DNSQueryType uint16
|
||||||
|
|
||||||
func (t DNSQueryType) String() string {
|
func (t DNSQueryType) String() string {
|
||||||
|
@ -270,15 +150,3 @@ func DNSQueryTypeToString(queryType uint16) string {
|
||||||
}
|
}
|
||||||
return F.ToString(queryType)
|
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/json"
|
"github.com/sagernet/sing/common/json"
|
||||||
"github.com/sagernet/sing/common/json/badjson"
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _V2RayTransportOptions struct {
|
type _V2RayTransportOptions struct {
|
||||||
|
@ -67,33 +68,33 @@ func (o *V2RayTransportOptions) UnmarshalJSON(bytes []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type V2RayHTTPOptions struct {
|
type V2RayHTTPOptions struct {
|
||||||
Host Listable[string] `json:"host,omitempty"`
|
Host badoption.Listable[string] `json:"host,omitempty"`
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Method string `json:"method,omitempty"`
|
Method string `json:"method,omitempty"`
|
||||||
Headers HTTPHeader `json:"headers,omitempty"`
|
Headers badoption.HTTPHeader `json:"headers,omitempty"`
|
||||||
IdleTimeout Duration `json:"idle_timeout,omitempty"`
|
IdleTimeout badoption.Duration `json:"idle_timeout,omitempty"`
|
||||||
PingTimeout Duration `json:"ping_timeout,omitempty"`
|
PingTimeout badoption.Duration `json:"ping_timeout,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type V2RayWebsocketOptions struct {
|
type V2RayWebsocketOptions struct {
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Headers HTTPHeader `json:"headers,omitempty"`
|
Headers badoption.HTTPHeader `json:"headers,omitempty"`
|
||||||
MaxEarlyData uint32 `json:"max_early_data,omitempty"`
|
MaxEarlyData uint32 `json:"max_early_data,omitempty"`
|
||||||
EarlyDataHeaderName string `json:"early_data_header_name,omitempty"`
|
EarlyDataHeaderName string `json:"early_data_header_name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type V2RayQUICOptions struct{}
|
type V2RayQUICOptions struct{}
|
||||||
|
|
||||||
type V2RayGRPCOptions struct {
|
type V2RayGRPCOptions struct {
|
||||||
ServiceName string `json:"service_name,omitempty"`
|
ServiceName string `json:"service_name,omitempty"`
|
||||||
IdleTimeout Duration `json:"idle_timeout,omitempty"`
|
IdleTimeout badoption.Duration `json:"idle_timeout,omitempty"`
|
||||||
PingTimeout Duration `json:"ping_timeout,omitempty"`
|
PingTimeout badoption.Duration `json:"ping_timeout,omitempty"`
|
||||||
PermitWithoutStream bool `json:"permit_without_stream,omitempty"`
|
PermitWithoutStream bool `json:"permit_without_stream,omitempty"`
|
||||||
ForceLite bool `json:"-"` // for test
|
ForceLite bool `json:"-"` // for test
|
||||||
}
|
}
|
||||||
|
|
||||||
type V2RayHTTPUpgradeOptions struct {
|
type V2RayHTTPUpgradeOptions struct {
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Headers HTTPHeader `json:"headers,omitempty"`
|
Headers badoption.HTTPHeader `json:"headers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
import "net/netip"
|
import (
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
)
|
||||||
|
|
||||||
type WireGuardOutboundOptions struct {
|
type WireGuardOutboundOptions struct {
|
||||||
DialerOptions
|
DialerOptions
|
||||||
SystemInterface bool `json:"system_interface,omitempty"`
|
SystemInterface bool `json:"system_interface,omitempty"`
|
||||||
GSO bool `json:"gso,omitempty"`
|
GSO bool `json:"gso,omitempty"`
|
||||||
InterfaceName string `json:"interface_name,omitempty"`
|
InterfaceName string `json:"interface_name,omitempty"`
|
||||||
LocalAddress Listable[netip.Prefix] `json:"local_address"`
|
LocalAddress badoption.Listable[netip.Prefix] `json:"local_address"`
|
||||||
PrivateKey string `json:"private_key"`
|
PrivateKey string `json:"private_key"`
|
||||||
Peers []WireGuardPeer `json:"peers,omitempty"`
|
Peers []WireGuardPeer `json:"peers,omitempty"`
|
||||||
ServerOptions
|
ServerOptions
|
||||||
PeerPublicKey string `json:"peer_public_key"`
|
PeerPublicKey string `json:"peer_public_key"`
|
||||||
PreSharedKey string `json:"pre_shared_key,omitempty"`
|
PreSharedKey string `json:"pre_shared_key,omitempty"`
|
||||||
|
@ -21,8 +25,8 @@ type WireGuardOutboundOptions struct {
|
||||||
|
|
||||||
type WireGuardPeer struct {
|
type WireGuardPeer struct {
|
||||||
ServerOptions
|
ServerOptions
|
||||||
PublicKey string `json:"public_key,omitempty"`
|
PublicKey string `json:"public_key,omitempty"`
|
||||||
PreSharedKey string `json:"pre_shared_key,omitempty"`
|
PreSharedKey string `json:"pre_shared_key,omitempty"`
|
||||||
AllowedIPs Listable[string] `json:"allowed_ips,omitempty"`
|
AllowedIPs badoption.Listable[string] `json:"allowed_ips,omitempty"`
|
||||||
Reserved []uint8 `json:"reserved,omitempty"`
|
Reserved []uint8 `json:"reserved,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/sagernet/sing-tun"
|
"github.com/sagernet/sing-tun"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
"github.com/sagernet/sing/common/ranges"
|
"github.com/sagernet/sing/common/ranges"
|
||||||
|
@ -257,7 +258,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||||
return inbound, nil
|
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 common.Map(uidList, func(uid uint32) ranges.Range[uint32] {
|
||||||
return ranges.NewSingle(uid)
|
return ranges.NewSingle(uid)
|
||||||
})
|
})
|
||||||
|
|
|
@ -239,9 +239,9 @@ func NewRouter(
|
||||||
}
|
}
|
||||||
var clientSubnet netip.Prefix
|
var clientSubnet netip.Prefix
|
||||||
if server.ClientSubnet != nil {
|
if server.ClientSubnet != nil {
|
||||||
clientSubnet = server.ClientSubnet.Build()
|
clientSubnet = netip.Prefix(common.PtrValueOrDefault(server.ClientSubnet))
|
||||||
} else if dnsOptions.ClientSubnet != nil {
|
} else if dnsOptions.ClientSubnet != nil {
|
||||||
clientSubnet = dnsOptions.ClientSubnet.Build()
|
clientSubnet = netip.Prefix(common.PtrValueOrDefault(dnsOptions.ClientSubnet))
|
||||||
}
|
}
|
||||||
if serverProtocol == "" {
|
if serverProtocol == "" {
|
||||||
serverProtocol = "transport"
|
serverProtocol = "transport"
|
||||||
|
|
|
@ -88,13 +88,13 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
|
||||||
Server: action.RouteOptions.Server,
|
Server: action.RouteOptions.Server,
|
||||||
DisableCache: action.RouteOptions.DisableCache,
|
DisableCache: action.RouteOptions.DisableCache,
|
||||||
RewriteTTL: action.RouteOptions.RewriteTTL,
|
RewriteTTL: action.RouteOptions.RewriteTTL,
|
||||||
ClientSubnet: action.RouteOptions.ClientSubnet.Build(),
|
ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptions.ClientSubnet)),
|
||||||
}
|
}
|
||||||
case C.RuleActionTypeRouteOptions:
|
case C.RuleActionTypeRouteOptions:
|
||||||
return &RuleActionDNSRouteOptions{
|
return &RuleActionDNSRouteOptions{
|
||||||
DisableCache: action.RouteOptionsOptions.DisableCache,
|
DisableCache: action.RouteOptionsOptions.DisableCache,
|
||||||
RewriteTTL: action.RouteOptionsOptions.RewriteTTL,
|
RewriteTTL: action.RouteOptionsOptions.RewriteTTL,
|
||||||
ClientSubnet: action.RouteOptionsOptions.ClientSubnet.Build(),
|
ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptionsOptions.ClientSubnet)),
|
||||||
}
|
}
|
||||||
case C.RuleActionTypeReject:
|
case C.RuleActionTypeReject:
|
||||||
return &RuleActionReject{
|
return &RuleActionReject{
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
"github.com/gofrs/uuid/v5"
|
"github.com/gofrs/uuid/v5"
|
||||||
)
|
)
|
||||||
|
@ -15,13 +17,13 @@ func TestBrutalShadowsocks(t *testing.T) {
|
||||||
method := shadowaead_2022.List[0]
|
method := shadowaead_2022.List[0]
|
||||||
password := mkBase64(t, 16)
|
password := mkBase64(t, 16)
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -30,7 +32,7 @@ func TestBrutalShadowsocks(t *testing.T) {
|
||||||
Type: C.TypeShadowsocks,
|
Type: C.TypeShadowsocks,
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
|
@ -100,13 +102,13 @@ func TestBrutalTrojan(t *testing.T) {
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
password := mkBase64(t, 16)
|
password := mkBase64(t, 16)
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -115,7 +117,7 @@ func TestBrutalTrojan(t *testing.T) {
|
||||||
Type: C.TypeTrojan,
|
Type: C.TypeTrojan,
|
||||||
TrojanOptions: option.TrojanInboundOptions{
|
TrojanOptions: option.TrojanInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.TrojanUser{{Password: password}},
|
Users: []option.TrojanUser{{Password: password}},
|
||||||
|
@ -197,13 +199,13 @@ func TestBrutalTrojan(t *testing.T) {
|
||||||
func TestBrutalVMess(t *testing.T) {
|
func TestBrutalVMess(t *testing.T) {
|
||||||
user, _ := uuid.NewV4()
|
user, _ := uuid.NewV4()
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -212,7 +214,7 @@ func TestBrutalVMess(t *testing.T) {
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{{UUID: user.String()}},
|
Users: []option.VMessUser{{UUID: user.String()}},
|
||||||
|
@ -279,13 +281,13 @@ func TestBrutalVMess(t *testing.T) {
|
||||||
func TestBrutalVLESS(t *testing.T) {
|
func TestBrutalVLESS(t *testing.T) {
|
||||||
user, _ := uuid.NewV4()
|
user, _ := uuid.NewV4()
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -294,7 +296,7 @@ func TestBrutalVLESS(t *testing.T) {
|
||||||
Type: C.TypeVLESS,
|
Type: C.TypeVLESS,
|
||||||
VLESSOptions: option.VLESSInboundOptions{
|
VLESSOptions: option.VLESSInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VLESSUser{{UUID: user.String()}},
|
Users: []option.VLESSUser{{UUID: user.String()}},
|
||||||
|
|
|
@ -6,18 +6,20 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"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.
|
// Since this is a feature one-off added by outsiders, I won't address these anymore.
|
||||||
func _TestProxyProtocol(t *testing.T) {
|
func _TestProxyProtocol(t *testing.T) {
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -26,7 +28,7 @@ func _TestProxyProtocol(t *testing.T) {
|
||||||
Type: C.TypeDirect,
|
Type: C.TypeDirect,
|
||||||
DirectOptions: option.DirectInboundOptions{
|
DirectOptions: option.DirectInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
ProxyProtocol: true,
|
ProxyProtocol: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-dns"
|
"github.com/sagernet/sing-dns"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
"github.com/gofrs/uuid/v5"
|
"github.com/gofrs/uuid/v5"
|
||||||
)
|
)
|
||||||
|
@ -14,13 +16,13 @@ import (
|
||||||
func TestTUICDomainUDP(t *testing.T) {
|
func TestTUICDomainUDP(t *testing.T) {
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -29,7 +31,7 @@ func TestTUICDomainUDP(t *testing.T) {
|
||||||
Type: C.TypeTUIC,
|
Type: C.TypeTUIC,
|
||||||
TUICOptions: option.TUICInboundOptions{
|
TUICOptions: option.TUICInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
InboundOptions: option.InboundOptions{
|
InboundOptions: option.InboundOptions{
|
||||||
DomainStrategy: option.DomainStrategy(dns.DomainStrategyUseIPv6),
|
DomainStrategy: option.DomainStrategy(dns.DomainStrategyUseIPv6),
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
"github.com/gofrs/uuid/v5"
|
"github.com/gofrs/uuid/v5"
|
||||||
)
|
)
|
||||||
|
@ -16,13 +17,13 @@ func TestECH(t *testing.T) {
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false))
|
echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false))
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -31,7 +32,7 @@ func TestECH(t *testing.T) {
|
||||||
Type: C.TypeTrojan,
|
Type: C.TypeTrojan,
|
||||||
TrojanOptions: option.TrojanInboundOptions{
|
TrojanOptions: option.TrojanInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.TrojanUser{
|
Users: []option.TrojanUser{
|
||||||
|
@ -109,13 +110,13 @@ func TestECHQUIC(t *testing.T) {
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false))
|
echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false))
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -124,7 +125,7 @@ func TestECHQUIC(t *testing.T) {
|
||||||
Type: C.TypeTUIC,
|
Type: C.TypeTUIC,
|
||||||
TUICOptions: option.TUICInboundOptions{
|
TUICOptions: option.TUICInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.TUICUser{{
|
Users: []option.TUICUser{{
|
||||||
|
@ -199,13 +200,13 @@ func TestECHHysteria2(t *testing.T) {
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false))
|
echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false))
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -214,7 +215,7 @@ func TestECHHysteria2(t *testing.T) {
|
||||||
Type: C.TypeHysteria2,
|
Type: C.TypeHysteria2,
|
||||||
Hysteria2Options: option.Hysteria2InboundOptions{
|
Hysteria2Options: option.Hysteria2InboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.Hysteria2User{{
|
Users: []option.Hysteria2User{{
|
||||||
|
|
18
test/go.mod
18
test/go.mod
|
@ -12,10 +12,10 @@ require (
|
||||||
github.com/docker/docker v27.3.1+incompatible
|
github.com/docker/docker v27.3.1+incompatible
|
||||||
github.com/docker/go-connections v0.5.0
|
github.com/docker/go-connections v0.5.0
|
||||||
github.com/gofrs/uuid/v5 v5.3.0
|
github.com/gofrs/uuid/v5 v5.3.0
|
||||||
github.com/sagernet/quic-go v0.48.0-beta.1
|
github.com/sagernet/quic-go v0.48.1-beta.1
|
||||||
github.com/sagernet/sing v0.5.0-rc.4.0.20241022031908-cd17884118cb
|
github.com/sagernet/sing v0.5.1-0.20241107131656-6e1285b5d82f
|
||||||
github.com/sagernet/sing-dns v0.3.0-rc.2.0.20241021154031-a59e0fbba3ce
|
github.com/sagernet/sing-dns v0.3.1-0.20241105104342-1914f319ddab
|
||||||
github.com/sagernet/sing-quic v0.3.0-rc.1
|
github.com/sagernet/sing-quic v0.3.0-rc.2
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.7
|
github.com/sagernet/sing-shadowsocks v0.2.7
|
||||||
github.com/sagernet/sing-shadowsocks2 v0.2.0
|
github.com/sagernet/sing-shadowsocks2 v0.2.0
|
||||||
github.com/spyzhov/ajson v0.9.4
|
github.com/spyzhov/ajson v0.9.4
|
||||||
|
@ -25,13 +25,11 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
berty.tech/go-libtor v1.0.385 // indirect
|
|
||||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||||
github.com/caddyserver/certmagic v0.20.0 // indirect
|
github.com/caddyserver/certmagic v0.20.0 // indirect
|
||||||
github.com/cloudflare/circl v1.3.7 // indirect
|
github.com/cloudflare/circl v1.3.7 // indirect
|
||||||
github.com/containerd/log v0.1.0 // 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/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/distribution/reference v0.5.0 // indirect
|
github.com/distribution/reference v0.5.0 // indirect
|
||||||
github.com/docker/go-units 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-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-ole/go-ole v1.3.0 // 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/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/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/google/btree v1.1.3 // indirect
|
github.com/google/btree v1.1.3 // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // 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/moby/term v0.5.0 // indirect
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.9.7 // 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/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||||
github.com/oschwald/maxminddb-golang v1.12.0 // 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/nftables v0.3.0-beta.4 // indirect
|
||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // 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-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.5.0.20241107062822-5a91eb99c90f // indirect
|
||||||
github.com/sagernet/sing-tun v0.4.0-rc.4.0.20241021153919-9ae45181180d // indirect
|
|
||||||
github.com/sagernet/sing-vmess v0.1.12 // indirect
|
github.com/sagernet/sing-vmess v0.1.12 // indirect
|
||||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
|
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
|
||||||
github.com/sagernet/utls v1.6.7 // 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/vishvananda/netns v0.0.4 // indirect
|
||||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect
|
||||||
|
|
51
test/go.sum
51
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 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
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=
|
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/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 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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-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 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
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 h1:m0mUMr+oVYUdxpMLgSYCZiXe7PuVPnI94+OMeVBNedk=
|
||||||
github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
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/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 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
|
||||||
github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4=
|
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 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
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/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 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
|
||||||
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
|
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.1-beta.1 h1:ElPaV5yzlXIKZpqFMAcUGax6vddi3zt4AEpT94Z0vwo=
|
||||||
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/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 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
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.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.1-0.20241107131656-6e1285b5d82f h1:A6+OeV5P1mok0eEEbLh4PidymZ6VZnTZ2uHwfapXgdU=
|
||||||
github.com/sagernet/sing v0.5.0-rc.4.0.20241022031908-cd17884118cb/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
github.com/sagernet/sing v0.5.1-0.20241107131656-6e1285b5d82f/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.1-0.20241105104342-1914f319ddab h1:djP4EY/KM5T62xscormLflVi7eDlHv6p7md1FHMSArE=
|
||||||
github.com/sagernet/sing-dns v0.3.0-rc.2.0.20241021154031-a59e0fbba3ce/go.mod h1:TqLIelI+FAbVEdiTRolhGLOwvhVjY7oT+wezlOJUQ7M=
|
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 h1:6Fd/VsEsw9qIjaGi1IBTZSb4b4v5JYtNcoiBtGsQC48=
|
||||||
github.com/sagernet/sing-mux v0.2.1-0.20241020175909-fe6153f7a9ec/go.mod h1:RSwqqHwbtTOX3vs6ms8vMtBGH/0ZNyLm/uwt6TlmR84=
|
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.2 h1:7vcC4bdS1GBJzHZhfmJiH0CfzQ4mYLUW51Z2RNHcGwc=
|
||||||
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/go.mod h1:3UOq51WVqzra7eCgod7t4hqnTaOiZzFUci9avMrtOqs=
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
|
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-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 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=
|
||||||
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
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-tun v0.4.0-rc.5.0.20241107062822-5a91eb99c90f h1:gQwTgN/E4oHe3VlseD3/RhPs866cWcTsPG4dP6a8f8o=
|
||||||
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
|
github.com/sagernet/sing-tun v0.4.0-rc.5.0.20241107062822-5a91eb99c90f/go.mod h1:Ehs5mZ3T8tTgV3H1Tx4Va5ixvyKjTAUPJ3G11dq7B/g=
|
||||||
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-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
|
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/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 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
|
||||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo=
|
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 h1:Ep3+aJ8FUGGta+II2IEVNUc3EDhaRCZINWkj/LloIA8=
|
||||||
github.com/sagernet/utls v1.6.7/go.mod h1:Uua1TKO/FFuAhLr9rkaVnnrTmmiItzDjv1BUb2+ERwM=
|
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 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
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 h1:MVibcTCgO7DY4IlskdqIlCmDOsUOZ9P7oKj8ifdcf84=
|
||||||
github.com/spyzhov/ajson v0.9.4/go.mod h1:a6oSw0MMb7Z5aD2tPoPO+jq11ETKgXUr2XktHdT8Wt8=
|
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/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.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 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
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 h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
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-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-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-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 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
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-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-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-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 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
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=
|
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 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
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-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-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-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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.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.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 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
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.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.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 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||||
|
|
|
@ -6,17 +6,19 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHTTPSelf(t *testing.T) {
|
func TestHTTPSelf(t *testing.T) {
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -25,7 +27,7 @@ func TestHTTPSelf(t *testing.T) {
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-quic/hysteria2"
|
"github.com/sagernet/sing-quic/hysteria2"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHysteria2Self(t *testing.T) {
|
func TestHysteria2Self(t *testing.T) {
|
||||||
|
@ -28,13 +30,13 @@ func testHysteria2Self(t *testing.T, salamanderPassword string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -43,7 +45,7 @@ func testHysteria2Self(t *testing.T, salamanderPassword string) {
|
||||||
Type: C.TypeHysteria2,
|
Type: C.TypeHysteria2,
|
||||||
Hysteria2Options: option.Hysteria2InboundOptions{
|
Hysteria2Options: option.Hysteria2InboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
UpMbps: 100,
|
UpMbps: 100,
|
||||||
|
@ -115,12 +117,12 @@ func testHysteria2Self(t *testing.T, salamanderPassword string) {
|
||||||
func TestHysteria2Inbound(t *testing.T) {
|
func TestHysteria2Inbound(t *testing.T) {
|
||||||
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeHysteria2,
|
Type: C.TypeHysteria2,
|
||||||
Hysteria2Options: option.Hysteria2InboundOptions{
|
Hysteria2Options: option.Hysteria2InboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Obfs: &option.Hysteria2Obfs{
|
Obfs: &option.Hysteria2Obfs{
|
||||||
|
@ -167,12 +169,12 @@ func TestHysteria2Outbound(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,18 +6,20 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHysteriaSelf(t *testing.T) {
|
func TestHysteriaSelf(t *testing.T) {
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -26,7 +28,7 @@ func TestHysteriaSelf(t *testing.T) {
|
||||||
Type: C.TypeHysteria,
|
Type: C.TypeHysteria,
|
||||||
HysteriaOptions: option.HysteriaInboundOptions{
|
HysteriaOptions: option.HysteriaInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
UpMbps: 100,
|
UpMbps: 100,
|
||||||
|
@ -98,12 +100,12 @@ func TestHysteriaSelf(t *testing.T) {
|
||||||
func TestHysteriaInbound(t *testing.T) {
|
func TestHysteriaInbound(t *testing.T) {
|
||||||
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeHysteria,
|
Type: C.TypeHysteria,
|
||||||
HysteriaOptions: option.HysteriaInboundOptions{
|
HysteriaOptions: option.HysteriaInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
UpMbps: 100,
|
UpMbps: 100,
|
||||||
|
@ -149,12 +151,12 @@ func TestHysteriaOutbound(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,19 +7,21 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChainedInbound(t *testing.T) {
|
func TestChainedInbound(t *testing.T) {
|
||||||
method := shadowaead_2022.List[0]
|
method := shadowaead_2022.List[0]
|
||||||
password := mkBase64(t, 16)
|
password := mkBase64(t, 16)
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -28,9 +30,11 @@ func TestChainedInbound(t *testing.T) {
|
||||||
Type: C.TypeShadowsocks,
|
Type: C.TypeShadowsocks,
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
Detour: "detour",
|
InboundOptions: option.InboundOptions{
|
||||||
|
Detour: "detour",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
Password: password,
|
Password: password,
|
||||||
|
@ -41,7 +45,7 @@ func TestChainedInbound(t *testing.T) {
|
||||||
Tag: "detour",
|
Tag: "detour",
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: otherPort,
|
ListenPort: otherPort,
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
"github.com/spyzhov/ajson"
|
"github.com/spyzhov/ajson"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -37,12 +39,12 @@ func TestMuxCoolServer(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
@ -81,12 +83,12 @@ func TestMuxCoolClient(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -112,13 +114,13 @@ func TestMuxCoolClient(t *testing.T) {
|
||||||
func TestMuxCoolSelf(t *testing.T) {
|
func TestMuxCoolSelf(t *testing.T) {
|
||||||
user := newUUID()
|
user := newUUID()
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -127,7 +129,7 @@ func TestMuxCoolSelf(t *testing.T) {
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
"github.com/gofrs/uuid/v5"
|
"github.com/gofrs/uuid/v5"
|
||||||
)
|
)
|
||||||
|
@ -55,13 +57,13 @@ func testShadowsocksMux(t *testing.T, options option.OutboundMultiplexOptions) {
|
||||||
method := shadowaead_2022.List[0]
|
method := shadowaead_2022.List[0]
|
||||||
password := mkBase64(t, 16)
|
password := mkBase64(t, 16)
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -70,7 +72,7 @@ func testShadowsocksMux(t *testing.T, options option.OutboundMultiplexOptions) {
|
||||||
Type: C.TypeShadowsocks,
|
Type: C.TypeShadowsocks,
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
|
@ -125,13 +127,13 @@ func testShadowsocksMux(t *testing.T, options option.OutboundMultiplexOptions) {
|
||||||
func testVMessMux(t *testing.T, options option.OutboundMultiplexOptions) {
|
func testVMessMux(t *testing.T, options option.OutboundMultiplexOptions) {
|
||||||
user, _ := uuid.NewV4()
|
user, _ := uuid.NewV4()
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -140,7 +142,7 @@ func testVMessMux(t *testing.T, options option.OutboundMultiplexOptions) {
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
|
|
@ -6,19 +6,21 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
"github.com/sagernet/sing/common/auth"
|
"github.com/sagernet/sing/common/auth"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
"github.com/sagernet/sing/common/network"
|
"github.com/sagernet/sing/common/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNaiveInboundWithNginx(t *testing.T) {
|
func TestNaiveInboundWithNginx(t *testing.T) {
|
||||||
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeNaive,
|
Type: C.TypeNaive,
|
||||||
NaiveOptions: option.NaiveInboundOptions{
|
NaiveOptions: option.NaiveInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: otherPort,
|
ListenPort: otherPort,
|
||||||
},
|
},
|
||||||
Users: []auth.User{
|
Users: []auth.User{
|
||||||
|
@ -59,12 +61,12 @@ func TestNaiveInboundWithNginx(t *testing.T) {
|
||||||
func TestNaiveInbound(t *testing.T) {
|
func TestNaiveInbound(t *testing.T) {
|
||||||
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeNaive,
|
Type: C.TypeNaive,
|
||||||
NaiveOptions: option.NaiveInboundOptions{
|
NaiveOptions: option.NaiveInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []auth.User{
|
Users: []auth.User{
|
||||||
|
@ -103,12 +105,12 @@ func TestNaiveInbound(t *testing.T) {
|
||||||
func TestNaiveHTTP3Inbound(t *testing.T) {
|
func TestNaiveHTTP3Inbound(t *testing.T) {
|
||||||
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeNaive,
|
Type: C.TypeNaive,
|
||||||
NaiveOptions: option.NaiveInboundOptions{
|
NaiveOptions: option.NaiveInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []auth.User{
|
Users: []auth.User{
|
||||||
|
|
|
@ -7,7 +7,9 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-shadowsocks2/shadowstream"
|
"github.com/sagernet/sing-shadowsocks2/shadowstream"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
F "github.com/sagernet/sing/common/format"
|
F "github.com/sagernet/sing/common/format"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShadowsocksLegacy(t *testing.T) {
|
func TestShadowsocksLegacy(t *testing.T) {
|
||||||
|
@ -24,12 +26,12 @@ func testShadowsocksLegacy(t *testing.T, method string) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,9 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
F "github.com/sagernet/sing/common/format"
|
F "github.com/sagernet/sing/common/format"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"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"},
|
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{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeShadowsocks,
|
Type: C.TypeShadowsocks,
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Method: method,
|
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"},
|
Cmd: []string{"-s", F.ToString("0.0.0.0:", serverPort), "-m", method, "-k", password, "-U"},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -154,13 +156,13 @@ func testShadowsocksOutboundWithShadowsocksRust(t *testing.T, method string, pas
|
||||||
|
|
||||||
func testShadowsocksSelf(t *testing.T, method string, password string) {
|
func testShadowsocksSelf(t *testing.T, method string, password string) {
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -169,7 +171,7 @@ func testShadowsocksSelf(t *testing.T, method string, password string) {
|
||||||
Type: C.TypeShadowsocks,
|
Type: C.TypeShadowsocks,
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
|
@ -221,13 +223,13 @@ func TestShadowsocksUoT(t *testing.T) {
|
||||||
method := shadowaead_2022.List[0]
|
method := shadowaead_2022.List[0]
|
||||||
password := mkBase64(t, 16)
|
password := mkBase64(t, 16)
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -236,7 +238,7 @@ func TestShadowsocksUoT(t *testing.T) {
|
||||||
Type: C.TypeShadowsocks,
|
Type: C.TypeShadowsocks,
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
|
@ -289,13 +291,13 @@ func TestShadowsocksUoT(t *testing.T) {
|
||||||
|
|
||||||
func testShadowsocks2022EIH(t *testing.T, method string, password string) {
|
func testShadowsocks2022EIH(t *testing.T, method string, password string) {
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -304,7 +306,7 @@ func testShadowsocks2022EIH(t *testing.T, method string, password string) {
|
||||||
Type: C.TypeShadowsocks,
|
Type: C.TypeShadowsocks,
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
|
|
|
@ -10,7 +10,9 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
F "github.com/sagernet/sing/common/format"
|
F "github.com/sagernet/sing/common/format"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"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]
|
method := shadowaead_2022.List[0]
|
||||||
ssPassword := mkBase64(t, 16)
|
ssPassword := mkBase64(t, 16)
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -52,9 +54,12 @@ func testShadowTLS(t *testing.T, version int, password string, utlsEanbled bool)
|
||||||
Tag: "in",
|
Tag: "in",
|
||||||
ShadowTLSOptions: option.ShadowTLSInboundOptions{
|
ShadowTLSOptions: option.ShadowTLSInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
Detour: "detour",
|
|
||||||
|
InboundOptions: option.InboundOptions{
|
||||||
|
Detour: "detour",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Handshake: option.ShadowTLSHandshakeOptions{
|
Handshake: option.ShadowTLSHandshakeOptions{
|
||||||
ServerOptions: option.ServerOptions{
|
ServerOptions: option.ServerOptions{
|
||||||
|
@ -72,7 +77,7 @@ func testShadowTLS(t *testing.T, version int, password string, utlsEanbled bool)
|
||||||
Tag: "detour",
|
Tag: "detour",
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: otherPort,
|
ListenPort: otherPort,
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
|
@ -142,12 +147,12 @@ func testShadowTLS(t *testing.T, version int, password string, utlsEanbled bool)
|
||||||
|
|
||||||
func TestShadowTLSFallback(t *testing.T) {
|
func TestShadowTLSFallback(t *testing.T) {
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeShadowTLS,
|
Type: C.TypeShadowTLS,
|
||||||
ShadowTLSOptions: option.ShadowTLSInboundOptions{
|
ShadowTLSOptions: option.ShadowTLSInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Handshake: option.ShadowTLSHandshakeOptions{
|
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},
|
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{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "in",
|
Tag: "in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -204,9 +209,11 @@ func TestShadowTLSInbound(t *testing.T) {
|
||||||
Type: C.TypeShadowTLS,
|
Type: C.TypeShadowTLS,
|
||||||
ShadowTLSOptions: option.ShadowTLSInboundOptions{
|
ShadowTLSOptions: option.ShadowTLSInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
Detour: "detour",
|
InboundOptions: option.InboundOptions{
|
||||||
|
Detour: "detour",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Handshake: option.ShadowTLSHandshakeOptions{
|
Handshake: option.ShadowTLSHandshakeOptions{
|
||||||
ServerOptions: option.ServerOptions{
|
ServerOptions: option.ServerOptions{
|
||||||
|
@ -225,7 +232,7 @@ func TestShadowTLSInbound(t *testing.T) {
|
||||||
Tag: "detour",
|
Tag: "detour",
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
Password: password,
|
Password: password,
|
||||||
|
@ -283,12 +290,12 @@ func TestShadowTLSOutbound(t *testing.T) {
|
||||||
Env: []string{"RUST_LOG=trace"},
|
Env: []string{"RUST_LOG=trace"},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -298,7 +305,7 @@ func TestShadowTLSOutbound(t *testing.T) {
|
||||||
Tag: "detour",
|
Tag: "detour",
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: otherPort,
|
ListenPort: otherPort,
|
||||||
},
|
},
|
||||||
Method: method,
|
Method: method,
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShadowsocksObfs(t *testing.T) {
|
func TestShadowsocksObfs(t *testing.T) {
|
||||||
|
@ -33,12 +35,12 @@ func testShadowsocksPlugin(t *testing.T, name string, opts string, args string)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,19 +7,21 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-shadowsocks/shadowaead"
|
"github.com/sagernet/sing-shadowsocks/shadowaead"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTCPSlowOpen(t *testing.T) {
|
func TestTCPSlowOpen(t *testing.T) {
|
||||||
method := shadowaead.List[0]
|
method := shadowaead.List[0]
|
||||||
password := mkBase64(t, 16)
|
password := mkBase64(t, 16)
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -28,7 +30,7 @@ func TestTCPSlowOpen(t *testing.T) {
|
||||||
Type: C.TypeShadowsocks,
|
Type: C.TypeShadowsocks,
|
||||||
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
ShadowsocksOptions: option.ShadowsocksInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
TCPFastOpen: true,
|
TCPFastOpen: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,18 +6,20 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUTLS(t *testing.T) {
|
func TestUTLS(t *testing.T) {
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -26,7 +28,7 @@ func TestUTLS(t *testing.T) {
|
||||||
Type: C.TypeTrojan,
|
Type: C.TypeTrojan,
|
||||||
TrojanOptions: option.TrojanInboundOptions{
|
TrojanOptions: option.TrojanInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.TrojanUser{
|
Users: []option.TrojanUser{
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTrojanOutbound(t *testing.T) {
|
func TestTrojanOutbound(t *testing.T) {
|
||||||
|
@ -20,12 +22,12 @@ func TestTrojanOutbound(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -57,13 +59,13 @@ func TestTrojanOutbound(t *testing.T) {
|
||||||
func TestTrojanSelf(t *testing.T) {
|
func TestTrojanSelf(t *testing.T) {
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -72,7 +74,7 @@ func TestTrojanSelf(t *testing.T) {
|
||||||
Type: C.TypeTrojan,
|
Type: C.TypeTrojan,
|
||||||
TrojanOptions: option.TrojanInboundOptions{
|
TrojanOptions: option.TrojanInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.TrojanUser{
|
Users: []option.TrojanUser{
|
||||||
|
@ -140,13 +142,13 @@ func TestTrojanSelf(t *testing.T) {
|
||||||
|
|
||||||
func TestTrojanPlainSelf(t *testing.T) {
|
func TestTrojanPlainSelf(t *testing.T) {
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -155,7 +157,7 @@ func TestTrojanPlainSelf(t *testing.T) {
|
||||||
Type: C.TypeTrojan,
|
Type: C.TypeTrojan,
|
||||||
TrojanOptions: option.TrojanInboundOptions{
|
TrojanOptions: option.TrojanInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.TrojanUser{
|
Users: []option.TrojanUser{
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"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/gofrs/uuid/v5"
|
||||||
)
|
)
|
||||||
|
@ -29,13 +31,13 @@ func testTUICSelf(t *testing.T, udpStream bool, zeroRTTHandshake bool) {
|
||||||
udpRelayMode = "quic"
|
udpRelayMode = "quic"
|
||||||
}
|
}
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -44,7 +46,7 @@ func testTUICSelf(t *testing.T, udpStream bool, zeroRTTHandshake bool) {
|
||||||
Type: C.TypeTUIC,
|
Type: C.TypeTUIC,
|
||||||
TUICOptions: option.TUICInboundOptions{
|
TUICOptions: option.TUICInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.TUICUser{{
|
Users: []option.TUICUser{{
|
||||||
|
@ -113,12 +115,12 @@ func testTUICSelf(t *testing.T, udpStream bool, zeroRTTHandshake bool) {
|
||||||
func TestTUICInbound(t *testing.T) {
|
func TestTUICInbound(t *testing.T) {
|
||||||
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeTUIC,
|
Type: C.TypeTUIC,
|
||||||
TUICOptions: option.TUICInboundOptions{
|
TUICOptions: option.TUICInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.TUICUser{{
|
Users: []option.TUICUser{{
|
||||||
|
@ -160,12 +162,12 @@ func TestTUICOutbound(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,19 +8,21 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/experimental/v2rayapi"
|
"github.com/sagernet/sing-box/experimental/v2rayapi"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestV2RayAPI(t *testing.T) {
|
func TestV2RayAPI(t *testing.T) {
|
||||||
i := startInstance(t, option.Options{
|
i := startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "in",
|
Tag: "in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"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/gofrs/uuid/v5"
|
||||||
"github.com/spyzhov/ajson"
|
"github.com/spyzhov/ajson"
|
||||||
|
@ -27,12 +29,12 @@ func testV2RayGRPCInbound(t *testing.T, forceLite bool) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
@ -126,13 +128,13 @@ func testV2RayGRPCOutbound(t *testing.T, forceLite bool) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"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/gofrs/uuid/v5"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -44,13 +46,13 @@ func testVMessTransportSelf(t *testing.T, server *option.V2RayTransportOptions,
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -59,7 +61,7 @@ func testVMessTransportSelf(t *testing.T, server *option.V2RayTransportOptions,
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
@ -133,13 +135,13 @@ func testTrojanTransportSelf(t *testing.T, server *option.V2RayTransportOptions,
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -148,7 +150,7 @@ func testTrojanTransportSelf(t *testing.T, server *option.V2RayTransportOptions,
|
||||||
Type: C.TypeTrojan,
|
Type: C.TypeTrojan,
|
||||||
TrojanOptions: option.TrojanInboundOptions{
|
TrojanOptions: option.TrojanInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.TrojanUser{
|
Users: []option.TrojanUser{
|
||||||
|
@ -224,13 +226,13 @@ func TestVMessQUICSelf(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -239,7 +241,7 @@ func TestVMessQUICSelf(t *testing.T) {
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
@ -312,13 +314,13 @@ func testV2RayTransportNOTLSSelf(t *testing.T, transport *option.V2RayTransportO
|
||||||
user, err := uuid.DefaultGenerator.NewV4()
|
user, err := uuid.DefaultGenerator.NewV4()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -327,7 +329,7 @@ func testV2RayTransportNOTLSSelf(t *testing.T, transport *option.V2RayTransportO
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"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/gofrs/uuid/v5"
|
||||||
"github.com/spyzhov/ajson"
|
"github.com/spyzhov/ajson"
|
||||||
|
@ -61,12 +63,12 @@ func testV2RayWebsocketInbound(t *testing.T, maxEarlyData uint32, earlyDataHeade
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
@ -158,13 +160,13 @@ func testV2RayWebsocketOutbound(t *testing.T, maxEarlyData uint32, earlyDataHead
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"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/gofrs/uuid/v5"
|
||||||
"github.com/spyzhov/ajson"
|
"github.com/spyzhov/ajson"
|
||||||
|
@ -181,12 +183,12 @@ func testVMessInboundWithV2Ray(t *testing.T, security string, alterId int, authe
|
||||||
})
|
})
|
||||||
|
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
@ -229,12 +231,12 @@ func testVMessOutboundWithV2Ray(t *testing.T, security string, globalPadding boo
|
||||||
})
|
})
|
||||||
|
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
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) {
|
func testVMessSelf(t *testing.T, security string, alterId int, globalPadding bool, authenticatedLength bool, packetAddr bool) {
|
||||||
user := newUUID()
|
user := newUUID()
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
Tag: "mixed-in",
|
Tag: "mixed-in",
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -278,7 +280,7 @@ func testVMessSelf(t *testing.T, security string, alterId int, globalPadding boo
|
||||||
Type: C.TypeVMess,
|
Type: C.TypeVMess,
|
||||||
VMessOptions: option.VMessInboundOptions{
|
VMessOptions: option.VMessInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: serverPort,
|
ListenPort: serverPort,
|
||||||
},
|
},
|
||||||
Users: []option.VMessUser{
|
Users: []option.VMessUser{
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
|
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func _TestWireGuard(t *testing.T) {
|
func _TestWireGuard(t *testing.T) {
|
||||||
|
@ -21,12 +23,12 @@ func _TestWireGuard(t *testing.T) {
|
||||||
})
|
})
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
startInstance(t, option.Options{
|
startInstance(t, option.Options{
|
||||||
Inbounds: []option.LegacyInbound{
|
LegacyInbounds: []option.LegacyInbound{
|
||||||
{
|
{
|
||||||
Type: C.TypeMixed,
|
Type: C.TypeMixed,
|
||||||
MixedOptions: option.HTTPMixedInboundOptions{
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
ListenOptions: option.ListenOptions{
|
ListenOptions: option.ListenOptions{
|
||||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
|
||||||
ListenPort: clientPort,
|
ListenPort: clientPort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/sagernet/sing-box/transport/v2ray"
|
"github.com/sagernet/sing-box/transport/v2ray"
|
||||||
"github.com/sagernet/sing-vmess"
|
"github.com/sagernet/sing-vmess"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
"github.com/sagernet/sing/common/json/badoption"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
)
|
)
|
||||||
|
@ -67,7 +68,7 @@ func newV2RayPlugin(ctx context.Context, pluginOpts Args, router adapter.Router,
|
||||||
transportOptions = option.V2RayTransportOptions{
|
transportOptions = option.V2RayTransportOptions{
|
||||||
Type: C.V2RayTransportTypeWebsocket,
|
Type: C.V2RayTransportTypeWebsocket,
|
||||||
WebsocketOptions: option.V2RayWebsocketOptions{
|
WebsocketOptions: option.V2RayWebsocketOptions{
|
||||||
Headers: map[string]option.Listable[string]{
|
Headers: map[string]badoption.Listable[string]{
|
||||||
"Host": []string{host},
|
"Host": []string{host},
|
||||||
},
|
},
|
||||||
Path: path,
|
Path: path,
|
||||||
|
|
Loading…
Reference in a new issue