mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 00:21:30 +00:00
Improve config struct
This commit is contained in:
parent
1f05420745
commit
cc78f0347d
2
go.mod
2
go.mod
|
@ -12,7 +12,7 @@ require (
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||||
github.com/oschwald/maxminddb-golang v1.9.0
|
github.com/oschwald/maxminddb-golang v1.9.0
|
||||||
github.com/sagernet/sing v0.0.0-20220722081142-8311d6e9709c
|
github.com/sagernet/sing v0.0.0-20220725031620-096223b346f3
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175
|
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220717063942-45a2ad9cd41f
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220717063942-45a2ad9cd41f
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220720051454-d35c334b46c9
|
github.com/sagernet/sing-tun v0.0.0-20220720051454-d35c334b46c9
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -37,8 +37,8 @@ github.com/oschwald/maxminddb-golang v1.9.0/go.mod h1:TK+s/Z2oZq0rSl4PSeAEoP0bgm
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sagernet/sing v0.0.0-20220722081142-8311d6e9709c h1:Y+4UoqqksclZfp7qVenaw10bQ/O5XH9JFiB7Xhfrip4=
|
github.com/sagernet/sing v0.0.0-20220725031620-096223b346f3 h1:Qm57CtqzaZ6Cq0ZDz1dX4vSNUoTYKn7qfXnpleKE0z0=
|
||||||
github.com/sagernet/sing v0.0.0-20220722081142-8311d6e9709c/go.mod h1:GbtQfZSpmtD3cXeD1qX2LCMwY8dH+bnnInDTqd92IsM=
|
github.com/sagernet/sing v0.0.0-20220725031620-096223b346f3/go.mod h1:GbtQfZSpmtD3cXeD1qX2LCMwY8dH+bnnInDTqd92IsM=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175 h1:YpacS9+rDFcLG8lSkmwU21capz2gewk4LQfCE/x73U0=
|
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175 h1:YpacS9+rDFcLG8lSkmwU21capz2gewk4LQfCE/x73U0=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175/go.mod h1:2A34p89do4H4E9Ke046cJCMTdVqmvsXGWXzRwgeO2TQ=
|
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175/go.mod h1:2A34p89do4H4E9Ke046cJCMTdVqmvsXGWXzRwgeO2TQ=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220717063942-45a2ad9cd41f h1:F6yiuKbBoXgWiuoP7R0YA14pDEl3emxA1mL7M16Q7gc=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220717063942-45a2ad9cd41f h1:F6yiuKbBoXgWiuoP7R0YA14pDEl3emxA1mL7M16Q7gc=
|
||||||
|
|
|
@ -7,13 +7,12 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.Inbound) (adapter.Inbound, error) {
|
func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.Inbound) (adapter.Inbound, error) {
|
||||||
if common.IsEmptyByEquals(options) {
|
if options.Type == "" {
|
||||||
return nil, E.New("empty inbound config")
|
return nil, E.New("missing inbound type")
|
||||||
}
|
}
|
||||||
switch options.Type {
|
switch options.Type {
|
||||||
case C.TypeTun:
|
case C.TypeTun:
|
||||||
|
|
19
option/clash.go
Normal file
19
option/clash.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
type ClashAPIOptions struct {
|
||||||
|
ExternalController string `json:"external_controller,omitempty"`
|
||||||
|
ExternalUI string `json:"external_ui,omitempty"`
|
||||||
|
Secret string `json:"secret,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SelectorOutboundOptions struct {
|
||||||
|
Outbounds []string `json:"outbounds"`
|
||||||
|
Default string `json:"default,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type URLTestOutboundOptions struct {
|
||||||
|
Outbounds []string `json:"outbounds"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
Interval Duration `json:"interval,omitempty"`
|
||||||
|
Tolerance uint16 `json:"tolerance,omitempty"`
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/common/json"
|
"github.com/sagernet/sing-box/common/json"
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,15 +35,6 @@ func (o *Options) UnmarshalJSON(content []byte) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Options) Equals(other Options) bool {
|
|
||||||
return common.ComparablePtrEquals(o.Log, other.Log) &&
|
|
||||||
common.PtrEquals(o.DNS, other.DNS) &&
|
|
||||||
common.SliceEquals(o.Inbounds, other.Inbounds) &&
|
|
||||||
common.SliceEquals(o.Outbounds, other.Outbounds) &&
|
|
||||||
common.PtrEquals(o.Route, other.Route) &&
|
|
||||||
common.ComparablePtrEquals(o.Experimental, other.Experimental)
|
|
||||||
}
|
|
||||||
|
|
||||||
type LogOptions struct {
|
type LogOptions struct {
|
||||||
Disabled bool `json:"disabled,omitempty"`
|
Disabled bool `json:"disabled,omitempty"`
|
||||||
Level string `json:"level,omitempty"`
|
Level string `json:"level,omitempty"`
|
||||||
|
|
14
option/direct.go
Normal file
14
option/direct.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
type DirectInboundOptions struct {
|
||||||
|
ListenOptions
|
||||||
|
Network NetworkList `json:"network,omitempty"`
|
||||||
|
OverrideAddress string `json:"override_address,omitempty"`
|
||||||
|
OverridePort uint16 `json:"override_port,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DirectOutboundOptions struct {
|
||||||
|
OutboundDialerOptions
|
||||||
|
OverrideAddress string `json:"override_address,omitempty"`
|
||||||
|
OverridePort uint16 `json:"override_port,omitempty"`
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/common/json"
|
"github.com/sagernet/sing-box/common/json"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
@ -14,13 +16,6 @@ type DNSOptions struct {
|
||||||
DNSClientOptions
|
DNSClientOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o DNSOptions) Equals(other DNSOptions) bool {
|
|
||||||
return common.ComparableSliceEquals(o.Servers, other.Servers) &&
|
|
||||||
common.SliceEquals(o.Rules, other.Rules) &&
|
|
||||||
o.Final == other.Final &&
|
|
||||||
o.DNSClientOptions == other.DNSClientOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
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"`
|
||||||
|
@ -44,12 +39,6 @@ type _DNSRule struct {
|
||||||
|
|
||||||
type DNSRule _DNSRule
|
type DNSRule _DNSRule
|
||||||
|
|
||||||
func (r DNSRule) Equals(other DNSRule) bool {
|
|
||||||
return r.Type == other.Type &&
|
|
||||||
r.DefaultOptions.Equals(other.DefaultOptions) &&
|
|
||||||
r.LogicalOptions.Equals(other.LogicalOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r DNSRule) MarshalJSON() ([]byte, error) {
|
func (r DNSRule) MarshalJSON() ([]byte, error) {
|
||||||
var v any
|
var v any
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
|
@ -116,33 +105,10 @@ type DefaultDNSRule struct {
|
||||||
|
|
||||||
func (r DefaultDNSRule) IsValid() bool {
|
func (r DefaultDNSRule) IsValid() bool {
|
||||||
var defaultValue DefaultDNSRule
|
var defaultValue DefaultDNSRule
|
||||||
|
defaultValue.Invert = r.Invert
|
||||||
defaultValue.Server = r.Server
|
defaultValue.Server = r.Server
|
||||||
return !r.Equals(defaultValue)
|
defaultValue.DisableCache = r.DisableCache
|
||||||
}
|
return !reflect.DeepEqual(r, defaultValue)
|
||||||
|
|
||||||
func (r DefaultDNSRule) Equals(other DefaultDNSRule) bool {
|
|
||||||
return common.ComparableSliceEquals(r.Inbound, other.Inbound) &&
|
|
||||||
r.Network == other.Network &&
|
|
||||||
common.ComparableSliceEquals(r.User, other.User) &&
|
|
||||||
common.ComparableSliceEquals(r.Protocol, other.Protocol) &&
|
|
||||||
common.ComparableSliceEquals(r.Domain, other.Domain) &&
|
|
||||||
common.ComparableSliceEquals(r.DomainSuffix, other.DomainSuffix) &&
|
|
||||||
common.ComparableSliceEquals(r.DomainKeyword, other.DomainKeyword) &&
|
|
||||||
common.ComparableSliceEquals(r.DomainRegex, other.DomainRegex) &&
|
|
||||||
common.ComparableSliceEquals(r.Geosite, other.Geosite) &&
|
|
||||||
common.ComparableSliceEquals(r.SourceGeoIP, other.SourceGeoIP) &&
|
|
||||||
common.ComparableSliceEquals(r.SourceIPCIDR, other.SourceIPCIDR) &&
|
|
||||||
common.ComparableSliceEquals(r.SourcePort, other.SourcePort) &&
|
|
||||||
common.ComparableSliceEquals(r.SourcePortRange, other.SourcePortRange) &&
|
|
||||||
common.ComparableSliceEquals(r.Port, other.Port) &&
|
|
||||||
common.ComparableSliceEquals(r.PortRange, other.PortRange) &&
|
|
||||||
common.ComparableSliceEquals(r.ProcessName, other.ProcessName) &&
|
|
||||||
common.ComparableSliceEquals(r.UserID, other.UserID) &&
|
|
||||||
common.ComparableSliceEquals(r.PackageName, other.PackageName) &&
|
|
||||||
common.ComparableSliceEquals(r.Outbound, other.Outbound) &&
|
|
||||||
r.Invert == other.Invert &&
|
|
||||||
r.Server == other.Server &&
|
|
||||||
r.DisableCache == other.DisableCache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogicalDNSRule struct {
|
type LogicalDNSRule struct {
|
||||||
|
@ -156,11 +122,3 @@ type LogicalDNSRule struct {
|
||||||
func (r LogicalDNSRule) IsValid() bool {
|
func (r LogicalDNSRule) IsValid() bool {
|
||||||
return len(r.Rules) > 0 && common.All(r.Rules, DefaultDNSRule.IsValid)
|
return len(r.Rules) > 0 && common.All(r.Rules, DefaultDNSRule.IsValid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r LogicalDNSRule) Equals(other LogicalDNSRule) bool {
|
|
||||||
return r.Mode == other.Mode &&
|
|
||||||
common.SliceEquals(r.Rules, other.Rules) &&
|
|
||||||
r.Invert == other.Invert &&
|
|
||||||
r.Server == other.Server &&
|
|
||||||
r.DisableCache == other.DisableCache
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,9 +3,3 @@ package option
|
||||||
type ExperimentalOptions struct {
|
type ExperimentalOptions struct {
|
||||||
ClashAPI *ClashAPIOptions `json:"clash_api,omitempty"`
|
ClashAPI *ClashAPIOptions `json:"clash_api,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClashAPIOptions struct {
|
|
||||||
ExternalController string `json:"external_controller,omitempty"`
|
|
||||||
ExternalUI string `json:"external_ui,omitempty"`
|
|
||||||
Secret string `json:"secret,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,8 +3,6 @@ package option
|
||||||
import (
|
import (
|
||||||
"github.com/sagernet/sing-box/common/json"
|
"github.com/sagernet/sing-box/common/json"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
"github.com/sagernet/sing/common/auth"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,20 +22,6 @@ type _Inbound struct {
|
||||||
|
|
||||||
type Inbound _Inbound
|
type Inbound _Inbound
|
||||||
|
|
||||||
func (h Inbound) Equals(other Inbound) bool {
|
|
||||||
return h.Type == other.Type &&
|
|
||||||
h.Tag == other.Tag &&
|
|
||||||
h.TunOptions == other.TunOptions &&
|
|
||||||
h.RedirectOptions == other.RedirectOptions &&
|
|
||||||
h.TProxyOptions == other.TProxyOptions &&
|
|
||||||
h.DirectOptions == other.DirectOptions &&
|
|
||||||
h.SocksOptions.Equals(other.SocksOptions) &&
|
|
||||||
h.HTTPOptions.Equals(other.HTTPOptions) &&
|
|
||||||
h.MixedOptions.Equals(other.MixedOptions) &&
|
|
||||||
h.ShadowsocksOptions.Equals(other.ShadowsocksOptions) &&
|
|
||||||
h.VMessOptions.Equals(other.VMessOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h Inbound) MarshalJSON() ([]byte, error) {
|
func (h Inbound) MarshalJSON() ([]byte, error) {
|
||||||
var v any
|
var v any
|
||||||
switch h.Type {
|
switch h.Type {
|
||||||
|
@ -113,103 +97,3 @@ type ListenOptions struct {
|
||||||
UDPTimeout int64 `json:"udp_timeout,omitempty"`
|
UDPTimeout int64 `json:"udp_timeout,omitempty"`
|
||||||
InboundOptions
|
InboundOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
type SocksInboundOptions struct {
|
|
||||||
ListenOptions
|
|
||||||
Users []auth.User `json:"users,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o SocksInboundOptions) Equals(other SocksInboundOptions) bool {
|
|
||||||
return o.ListenOptions == other.ListenOptions &&
|
|
||||||
common.ComparableSliceEquals(o.Users, other.Users)
|
|
||||||
}
|
|
||||||
|
|
||||||
type HTTPMixedInboundOptions struct {
|
|
||||||
ListenOptions
|
|
||||||
Users []auth.User `json:"users,omitempty"`
|
|
||||||
SetSystemProxy bool `json:"set_system_proxy,omitempty"`
|
|
||||||
TLS *InboundTLSOptions `json:"tls,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o HTTPMixedInboundOptions) Equals(other HTTPMixedInboundOptions) bool {
|
|
||||||
return o.ListenOptions == other.ListenOptions &&
|
|
||||||
common.ComparableSliceEquals(o.Users, other.Users) &&
|
|
||||||
o.SetSystemProxy == other.SetSystemProxy &&
|
|
||||||
common.PtrEquals(o.TLS, other.TLS)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DirectInboundOptions struct {
|
|
||||||
ListenOptions
|
|
||||||
Network NetworkList `json:"network,omitempty"`
|
|
||||||
OverrideAddress string `json:"override_address,omitempty"`
|
|
||||||
OverridePort uint16 `json:"override_port,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShadowsocksInboundOptions struct {
|
|
||||||
ListenOptions
|
|
||||||
Network NetworkList `json:"network,omitempty"`
|
|
||||||
Method string `json:"method"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Users []ShadowsocksUser `json:"users,omitempty"`
|
|
||||||
Destinations []ShadowsocksDestination `json:"destinations,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o ShadowsocksInboundOptions) Equals(other ShadowsocksInboundOptions) bool {
|
|
||||||
return o.ListenOptions == other.ListenOptions &&
|
|
||||||
o.Network == other.Network &&
|
|
||||||
o.Method == other.Method &&
|
|
||||||
o.Password == other.Password &&
|
|
||||||
common.ComparableSliceEquals(o.Users, other.Users) &&
|
|
||||||
common.ComparableSliceEquals(o.Destinations, other.Destinations)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShadowsocksUser struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShadowsocksDestination struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
ServerOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
type VMessInboundOptions struct {
|
|
||||||
ListenOptions
|
|
||||||
Users []VMessUser `json:"users,omitempty"`
|
|
||||||
TLS *InboundTLSOptions `json:"tls,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o VMessInboundOptions) Equals(other VMessInboundOptions) bool {
|
|
||||||
return o.ListenOptions == other.ListenOptions &&
|
|
||||||
common.ComparableSliceEquals(o.Users, other.Users) &&
|
|
||||||
common.PtrEquals(o.TLS, other.TLS)
|
|
||||||
}
|
|
||||||
|
|
||||||
type VMessUser struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
UUID string `json:"uuid"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TunInboundOptions struct {
|
|
||||||
InterfaceName string `json:"interface_name,omitempty"`
|
|
||||||
MTU uint32 `json:"mtu,omitempty"`
|
|
||||||
Inet4Address *ListenPrefix `json:"inet4_address,omitempty"`
|
|
||||||
Inet6Address *ListenPrefix `json:"inet6_address,omitempty"`
|
|
||||||
AutoRoute bool `json:"auto_route,omitempty"`
|
|
||||||
InboundOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
type RedirectInboundOptions struct {
|
|
||||||
ListenOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
type TProxyInboundOptions struct {
|
|
||||||
ListenOptions
|
|
||||||
Network NetworkList `json:"network,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DNSInboundOptions struct {
|
|
||||||
ListenOptions
|
|
||||||
Network NetworkList `json:"network,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package option
|
||||||
import (
|
import (
|
||||||
"github.com/sagernet/sing-box/common/json"
|
"github.com/sagernet/sing-box/common/json"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
)
|
)
|
||||||
|
@ -22,18 +21,6 @@ type _Outbound struct {
|
||||||
|
|
||||||
type Outbound _Outbound
|
type Outbound _Outbound
|
||||||
|
|
||||||
func (h Outbound) Equals(other Outbound) bool {
|
|
||||||
return h.Type == other.Type &&
|
|
||||||
h.Tag == other.Tag &&
|
|
||||||
h.DirectOptions == other.DirectOptions &&
|
|
||||||
h.SocksOptions == other.SocksOptions &&
|
|
||||||
h.HTTPOptions == other.HTTPOptions &&
|
|
||||||
h.ShadowsocksOptions == other.ShadowsocksOptions &&
|
|
||||||
h.VMessOptions == other.VMessOptions &&
|
|
||||||
common.Equals(h.SelectorOptions, other.SelectorOptions) &&
|
|
||||||
common.Equals(h.URLTestOptions, other.URLTestOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h Outbound) MarshalJSON() ([]byte, error) {
|
func (h Outbound) MarshalJSON() ([]byte, error) {
|
||||||
var v any
|
var v any
|
||||||
switch h.Type {
|
switch h.Type {
|
||||||
|
@ -116,75 +103,3 @@ type ServerOptions struct {
|
||||||
func (o ServerOptions) Build() M.Socksaddr {
|
func (o ServerOptions) Build() M.Socksaddr {
|
||||||
return M.ParseSocksaddrHostPort(o.Server, o.ServerPort)
|
return M.ParseSocksaddrHostPort(o.Server, o.ServerPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DirectOutboundOptions struct {
|
|
||||||
OutboundDialerOptions
|
|
||||||
OverrideAddress string `json:"override_address,omitempty"`
|
|
||||||
OverridePort uint16 `json:"override_port,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SocksOutboundOptions struct {
|
|
||||||
OutboundDialerOptions
|
|
||||||
ServerOptions
|
|
||||||
Version string `json:"version,omitempty"`
|
|
||||||
Username string `json:"username,omitempty"`
|
|
||||||
Password string `json:"password,omitempty"`
|
|
||||||
Network NetworkList `json:"network,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type HTTPOutboundOptions struct {
|
|
||||||
OutboundDialerOptions
|
|
||||||
ServerOptions
|
|
||||||
Username string `json:"username,omitempty"`
|
|
||||||
Password string `json:"password,omitempty"`
|
|
||||||
TLSOptions *OutboundTLSOptions `json:"tls,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShadowsocksOutboundOptions struct {
|
|
||||||
OutboundDialerOptions
|
|
||||||
ServerOptions
|
|
||||||
Method string `json:"method"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Network NetworkList `json:"network,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type VMessOutboundOptions struct {
|
|
||||||
OutboundDialerOptions
|
|
||||||
ServerOptions
|
|
||||||
UUID string `json:"uuid"`
|
|
||||||
Security string `json:"security"`
|
|
||||||
AlterId int `json:"alter_id,omitempty"`
|
|
||||||
GlobalPadding bool `json:"global_padding,omitempty"`
|
|
||||||
AuthenticatedLength bool `json:"authenticated_length,omitempty"`
|
|
||||||
Network NetworkList `json:"network,omitempty"`
|
|
||||||
TLSOptions *OutboundTLSOptions `json:"tls,omitempty"`
|
|
||||||
TransportOptions *VMessTransportOptions `json:"transport,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type VMessTransportOptions struct {
|
|
||||||
Network string `json:"network,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SelectorOutboundOptions struct {
|
|
||||||
Outbounds []string `json:"outbounds"`
|
|
||||||
Default string `json:"default,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o SelectorOutboundOptions) Equals(other SelectorOutboundOptions) bool {
|
|
||||||
return common.ComparableSliceEquals(o.Outbounds, other.Outbounds) &&
|
|
||||||
o.Default == other.Default
|
|
||||||
}
|
|
||||||
|
|
||||||
type URLTestOutboundOptions struct {
|
|
||||||
Outbounds []string `json:"outbounds"`
|
|
||||||
URL string `json:"url,omitempty"`
|
|
||||||
Interval Duration `json:"interval,omitempty"`
|
|
||||||
Tolerance uint16 `json:"tolerance,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o URLTestOutboundOptions) Equals(other URLTestOutboundOptions) bool {
|
|
||||||
return common.ComparableSliceEquals(o.Outbounds, other.Outbounds) &&
|
|
||||||
o.URL == other.URL &&
|
|
||||||
o.Interval == other.Interval &&
|
|
||||||
o.Tolerance == other.Tolerance
|
|
||||||
}
|
|
||||||
|
|
10
option/redir.go
Normal file
10
option/redir.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
type RedirectInboundOptions struct {
|
||||||
|
ListenOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
type TProxyInboundOptions struct {
|
||||||
|
ListenOptions
|
||||||
|
Network NetworkList `json:"network,omitempty"`
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package option
|
package option
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/common/json"
|
"github.com/sagernet/sing-box/common/json"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
@ -18,17 +20,6 @@ type RouteOptions struct {
|
||||||
DefaultMark int `json:"default_mark,omitempty"`
|
DefaultMark int `json:"default_mark,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o RouteOptions) Equals(other RouteOptions) bool {
|
|
||||||
return common.ComparablePtrEquals(o.GeoIP, other.GeoIP) &&
|
|
||||||
common.ComparablePtrEquals(o.Geosite, other.Geosite) &&
|
|
||||||
common.SliceEquals(o.Rules, other.Rules) &&
|
|
||||||
o.Final == other.Final &&
|
|
||||||
o.FindProcess == other.FindProcess &&
|
|
||||||
o.AutoDetectInterface == other.AutoDetectInterface &&
|
|
||||||
o.DefaultInterface == other.DefaultInterface &&
|
|
||||||
o.DefaultMark == other.DefaultMark
|
|
||||||
}
|
|
||||||
|
|
||||||
type GeoIPOptions struct {
|
type GeoIPOptions struct {
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
DownloadURL string `json:"download_url,omitempty"`
|
DownloadURL string `json:"download_url,omitempty"`
|
||||||
|
@ -49,12 +40,6 @@ type _Rule struct {
|
||||||
|
|
||||||
type Rule _Rule
|
type Rule _Rule
|
||||||
|
|
||||||
func (r Rule) Equals(other Rule) bool {
|
|
||||||
return r.Type == other.Type &&
|
|
||||||
r.DefaultOptions.Equals(other.DefaultOptions) &&
|
|
||||||
r.LogicalOptions.Equals(other.LogicalOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r Rule) MarshalJSON() ([]byte, error) {
|
func (r Rule) MarshalJSON() ([]byte, error) {
|
||||||
var v any
|
var v any
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
|
@ -120,35 +105,9 @@ type DefaultRule struct {
|
||||||
|
|
||||||
func (r DefaultRule) IsValid() bool {
|
func (r DefaultRule) IsValid() bool {
|
||||||
var defaultValue DefaultRule
|
var defaultValue DefaultRule
|
||||||
|
defaultValue.Invert = r.Invert
|
||||||
defaultValue.Outbound = r.Outbound
|
defaultValue.Outbound = r.Outbound
|
||||||
return !r.Equals(defaultValue)
|
return !reflect.DeepEqual(r, defaultValue)
|
||||||
}
|
|
||||||
|
|
||||||
func (r DefaultRule) Equals(other DefaultRule) bool {
|
|
||||||
return common.ComparableSliceEquals(r.Inbound, other.Inbound) &&
|
|
||||||
r.IPVersion == other.IPVersion &&
|
|
||||||
r.Network == other.Network &&
|
|
||||||
common.ComparableSliceEquals(r.User, other.User) &&
|
|
||||||
common.ComparableSliceEquals(r.Protocol, other.Protocol) &&
|
|
||||||
common.ComparableSliceEquals(r.Domain, other.Domain) &&
|
|
||||||
common.ComparableSliceEquals(r.DomainSuffix, other.DomainSuffix) &&
|
|
||||||
common.ComparableSliceEquals(r.DomainKeyword, other.DomainKeyword) &&
|
|
||||||
common.ComparableSliceEquals(r.DomainRegex, other.DomainRegex) &&
|
|
||||||
common.ComparableSliceEquals(r.Geosite, other.Geosite) &&
|
|
||||||
common.ComparableSliceEquals(r.SourceGeoIP, other.SourceGeoIP) &&
|
|
||||||
common.ComparableSliceEquals(r.GeoIP, other.GeoIP) &&
|
|
||||||
common.ComparableSliceEquals(r.SourceIPCIDR, other.SourceIPCIDR) &&
|
|
||||||
common.ComparableSliceEquals(r.IPCIDR, other.IPCIDR) &&
|
|
||||||
common.ComparableSliceEquals(r.SourcePort, other.SourcePort) &&
|
|
||||||
common.ComparableSliceEquals(r.SourcePortRange, other.SourcePortRange) &&
|
|
||||||
common.ComparableSliceEquals(r.Port, other.Port) &&
|
|
||||||
common.ComparableSliceEquals(r.PortRange, other.PortRange) &&
|
|
||||||
common.ComparableSliceEquals(r.ProcessName, other.ProcessName) &&
|
|
||||||
common.ComparableSliceEquals(r.PackageName, other.PackageName) &&
|
|
||||||
common.ComparableSliceEquals(r.User, other.User) &&
|
|
||||||
common.ComparableSliceEquals(r.UserID, other.UserID) &&
|
|
||||||
r.Invert == other.Invert &&
|
|
||||||
r.Outbound == other.Outbound
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogicalRule struct {
|
type LogicalRule struct {
|
||||||
|
@ -161,10 +120,3 @@ type LogicalRule struct {
|
||||||
func (r LogicalRule) IsValid() bool {
|
func (r LogicalRule) IsValid() bool {
|
||||||
return len(r.Rules) > 0 && common.All(r.Rules, DefaultRule.IsValid)
|
return len(r.Rules) > 0 && common.All(r.Rules, DefaultRule.IsValid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r LogicalRule) Equals(other LogicalRule) bool {
|
|
||||||
return r.Mode == other.Mode &&
|
|
||||||
common.SliceEquals(r.Rules, other.Rules) &&
|
|
||||||
r.Invert == other.Invert &&
|
|
||||||
r.Outbound == other.Outbound
|
|
||||||
}
|
|
||||||
|
|
29
option/shadowsocks.go
Normal file
29
option/shadowsocks.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
type ShadowsocksInboundOptions struct {
|
||||||
|
ListenOptions
|
||||||
|
Network NetworkList `json:"network,omitempty"`
|
||||||
|
Method string `json:"method"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Users []ShadowsocksUser `json:"users,omitempty"`
|
||||||
|
Destinations []ShadowsocksDestination `json:"destinations,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShadowsocksUser struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShadowsocksDestination struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
ServerOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShadowsocksOutboundOptions struct {
|
||||||
|
OutboundDialerOptions
|
||||||
|
ServerOptions
|
||||||
|
Method string `json:"method"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Network NetworkList `json:"network,omitempty"`
|
||||||
|
}
|
32
option/simple.go
Normal file
32
option/simple.go
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
import "github.com/sagernet/sing/common/auth"
|
||||||
|
|
||||||
|
type SocksInboundOptions struct {
|
||||||
|
ListenOptions
|
||||||
|
Users []auth.User `json:"users,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPMixedInboundOptions struct {
|
||||||
|
ListenOptions
|
||||||
|
Users []auth.User `json:"users,omitempty"`
|
||||||
|
SetSystemProxy bool `json:"set_system_proxy,omitempty"`
|
||||||
|
TLS *InboundTLSOptions `json:"tls,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SocksOutboundOptions struct {
|
||||||
|
OutboundDialerOptions
|
||||||
|
ServerOptions
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
Password string `json:"password,omitempty"`
|
||||||
|
Network NetworkList `json:"network,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPOutboundOptions struct {
|
||||||
|
OutboundDialerOptions
|
||||||
|
ServerOptions
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
Password string `json:"password,omitempty"`
|
||||||
|
TLSOptions *OutboundTLSOptions `json:"tls,omitempty"`
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ package option
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,19 +19,6 @@ type InboundTLSOptions struct {
|
||||||
KeyPath string `json:"key_path,omitempty"`
|
KeyPath string `json:"key_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o InboundTLSOptions) Equals(other InboundTLSOptions) bool {
|
|
||||||
return o.Enabled == other.Enabled &&
|
|
||||||
o.ServerName == other.ServerName &&
|
|
||||||
common.ComparableSliceEquals(o.ALPN, other.ALPN) &&
|
|
||||||
o.MinVersion == other.MinVersion &&
|
|
||||||
o.MaxVersion == other.MaxVersion &&
|
|
||||||
common.ComparableSliceEquals(o.CipherSuites, other.CipherSuites) &&
|
|
||||||
o.Certificate == other.Certificate &&
|
|
||||||
o.CertificatePath == other.CertificatePath &&
|
|
||||||
o.Key == other.Key &&
|
|
||||||
o.KeyPath == other.KeyPath
|
|
||||||
}
|
|
||||||
|
|
||||||
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"`
|
||||||
|
@ -47,20 +33,6 @@ type OutboundTLSOptions struct {
|
||||||
CertificatePath string `json:"certificate_path,omitempty"`
|
CertificatePath string `json:"certificate_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o OutboundTLSOptions) Equals(other OutboundTLSOptions) bool {
|
|
||||||
return o.Enabled == other.Enabled &&
|
|
||||||
o.DisableSNI == other.DisableSNI &&
|
|
||||||
o.ServerName == other.ServerName &&
|
|
||||||
o.Insecure == other.Insecure &&
|
|
||||||
common.ComparableSliceEquals(o.ALPN, other.ALPN) &&
|
|
||||||
o.MinVersion == other.MinVersion &&
|
|
||||||
o.MaxVersion == other.MaxVersion &&
|
|
||||||
common.ComparableSliceEquals(o.CipherSuites, other.CipherSuites) &&
|
|
||||||
o.DisableSystemRoot == other.DisableSystemRoot &&
|
|
||||||
o.Certificate == other.Certificate &&
|
|
||||||
o.CertificatePath == other.CertificatePath
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseTLSVersion(version string) (uint16, error) {
|
func ParseTLSVersion(version string) (uint16, error) {
|
||||||
switch version {
|
switch version {
|
||||||
case "1.0":
|
case "1.0":
|
||||||
|
|
10
option/tun.go
Normal file
10
option/tun.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
type TunInboundOptions struct {
|
||||||
|
InterfaceName string `json:"interface_name,omitempty"`
|
||||||
|
MTU uint32 `json:"mtu,omitempty"`
|
||||||
|
Inet4Address *ListenPrefix `json:"inet4_address,omitempty"`
|
||||||
|
Inet6Address *ListenPrefix `json:"inet6_address,omitempty"`
|
||||||
|
AutoRoute bool `json:"auto_route,omitempty"`
|
||||||
|
InboundOptions
|
||||||
|
}
|
54
option/vmess.go
Normal file
54
option/vmess.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package option
|
||||||
|
|
||||||
|
import (
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VMessInboundOptions struct {
|
||||||
|
ListenOptions
|
||||||
|
Users []VMessUser `json:"users,omitempty"`
|
||||||
|
TLS *InboundTLSOptions `json:"tls,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VMessUser struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
UUID string `json:"uuid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VMessOutboundOptions struct {
|
||||||
|
OutboundDialerOptions
|
||||||
|
ServerOptions
|
||||||
|
UUID string `json:"uuid"`
|
||||||
|
Security string `json:"security"`
|
||||||
|
AlterId int `json:"alter_id,omitempty"`
|
||||||
|
GlobalPadding bool `json:"global_padding,omitempty"`
|
||||||
|
AuthenticatedLength bool `json:"authenticated_length,omitempty"`
|
||||||
|
Network NetworkList `json:"network,omitempty"`
|
||||||
|
TLSOptions *OutboundTLSOptions `json:"tls,omitempty"`
|
||||||
|
TransportOptions *VMessOutboundTransportOptions `json:"transport,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type _VMessOutboundTransportOptions struct {
|
||||||
|
Type string `json:"network,omitempty"`
|
||||||
|
HTTPOptions *VMessOutboundHTTPOptions `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VMessOutboundTransportOptions _VMessOutboundTransportOptions
|
||||||
|
|
||||||
|
func (o VMessOutboundTransportOptions) MarshalJSON() ([]byte, error) {
|
||||||
|
var v any
|
||||||
|
switch o.Type {
|
||||||
|
case "http":
|
||||||
|
v = o.HTTPOptions
|
||||||
|
default:
|
||||||
|
return nil, E.New("unknown transport type: ", o.Type)
|
||||||
|
}
|
||||||
|
return MarshallObjects(_VMessOutboundTransportOptions(o), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
type VMessOutboundHTTPOptions struct {
|
||||||
|
Method string `json:"method,omitempty"`
|
||||||
|
Host string `json:"host,omitempty"`
|
||||||
|
Path []string `proxy:"path,omitempty"`
|
||||||
|
Headers map[string]string `proxy:"headers,omitempty"`
|
||||||
|
}
|
|
@ -5,13 +5,12 @@ import (
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(router adapter.Router, logger log.ContextLogger, options option.Outbound) (adapter.Outbound, error) {
|
func New(router adapter.Router, logger log.ContextLogger, options option.Outbound) (adapter.Outbound, error) {
|
||||||
if common.IsEmptyByEquals(options) {
|
if options.Type == "" {
|
||||||
return nil, E.New("empty outbound config")
|
return nil, E.New("missing outbound type")
|
||||||
}
|
}
|
||||||
switch options.Type {
|
switch options.Type {
|
||||||
case C.TypeDirect:
|
case C.TypeDirect:
|
||||||
|
|
|
@ -13,9 +13,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRule(router adapter.Router, logger log.ContextLogger, options option.Rule) (adapter.Rule, error) {
|
func NewRule(router adapter.Router, logger log.ContextLogger, options option.Rule) (adapter.Rule, error) {
|
||||||
if common.IsEmptyByEquals(options) {
|
|
||||||
return nil, E.New("empty rule config")
|
|
||||||
}
|
|
||||||
switch options.Type {
|
switch options.Type {
|
||||||
case "", C.RuleTypeDefault:
|
case "", C.RuleTypeDefault:
|
||||||
if !options.DefaultOptions.IsValid() {
|
if !options.DefaultOptions.IsValid() {
|
||||||
|
|
|
@ -13,9 +13,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.DNSRule) (adapter.DNSRule, error) {
|
func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.DNSRule) (adapter.DNSRule, error) {
|
||||||
if common.IsEmptyByEquals(options) {
|
|
||||||
return nil, E.New("empty rule config")
|
|
||||||
}
|
|
||||||
switch options.Type {
|
switch options.Type {
|
||||||
case "", C.RuleTypeDefault:
|
case "", C.RuleTypeDefault:
|
||||||
if !options.DefaultOptions.IsValid() {
|
if !options.DefaultOptions.IsValid() {
|
||||||
|
|
|
@ -10,7 +10,7 @@ require (
|
||||||
github.com/docker/docker v20.10.17+incompatible
|
github.com/docker/docker v20.10.17+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/gofrs/uuid v4.2.0+incompatible
|
github.com/gofrs/uuid v4.2.0+incompatible
|
||||||
github.com/sagernet/sing v0.0.0-20220722081142-8311d6e9709c
|
github.com/sagernet/sing v0.0.0-20220725031620-096223b346f3
|
||||||
github.com/spyzhov/ajson v0.7.1
|
github.com/spyzhov/ajson v0.7.1
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
|
||||||
|
|
|
@ -64,8 +64,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/sagernet/sing v0.0.0-20220722081142-8311d6e9709c h1:Y+4UoqqksclZfp7qVenaw10bQ/O5XH9JFiB7Xhfrip4=
|
github.com/sagernet/sing v0.0.0-20220725031620-096223b346f3 h1:Qm57CtqzaZ6Cq0ZDz1dX4vSNUoTYKn7qfXnpleKE0z0=
|
||||||
github.com/sagernet/sing v0.0.0-20220722081142-8311d6e9709c/go.mod h1:GbtQfZSpmtD3cXeD1qX2LCMwY8dH+bnnInDTqd92IsM=
|
github.com/sagernet/sing v0.0.0-20220725031620-096223b346f3/go.mod h1:GbtQfZSpmtD3cXeD1qX2LCMwY8dH+bnnInDTqd92IsM=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175 h1:YpacS9+rDFcLG8lSkmwU21capz2gewk4LQfCE/x73U0=
|
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175 h1:YpacS9+rDFcLG8lSkmwU21capz2gewk4LQfCE/x73U0=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175/go.mod h1:2A34p89do4H4E9Ke046cJCMTdVqmvsXGWXzRwgeO2TQ=
|
github.com/sagernet/sing-dns v0.0.0-20220724053927-eb8d0d542175/go.mod h1:2A34p89do4H4E9Ke046cJCMTdVqmvsXGWXzRwgeO2TQ=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220717063942-45a2ad9cd41f h1:F6yiuKbBoXgWiuoP7R0YA14pDEl3emxA1mL7M16Q7gc=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220717063942-45a2ad9cd41f h1:F6yiuKbBoXgWiuoP7R0YA14pDEl3emxA1mL7M16Q7gc=
|
||||||
|
|
Loading…
Reference in a new issue