github.com/sagernet/sing-box@v1.2.7/option/dns.go (about) 1 package option 2 3 import ( 4 "reflect" 5 6 "github.com/sagernet/sing-box/common/json" 7 C "github.com/sagernet/sing-box/constant" 8 "github.com/sagernet/sing/common" 9 E "github.com/sagernet/sing/common/exceptions" 10 ) 11 12 type DNSOptions struct { 13 Servers []DNSServerOptions `json:"servers,omitempty"` 14 Rules []DNSRule `json:"rules,omitempty"` 15 Final string `json:"final,omitempty"` 16 DNSClientOptions 17 } 18 19 type DNSClientOptions struct { 20 Strategy DomainStrategy `json:"strategy,omitempty"` 21 DisableCache bool `json:"disable_cache,omitempty"` 22 DisableExpire bool `json:"disable_expire,omitempty"` 23 } 24 25 type DNSServerOptions struct { 26 Tag string `json:"tag,omitempty"` 27 Address string `json:"address"` 28 AddressResolver string `json:"address_resolver,omitempty"` 29 AddressStrategy DomainStrategy `json:"address_strategy,omitempty"` 30 AddressFallbackDelay Duration `json:"address_fallback_delay,omitempty"` 31 Strategy DomainStrategy `json:"strategy,omitempty"` 32 Detour string `json:"detour,omitempty"` 33 } 34 35 type _DNSRule struct { 36 Type string `json:"type,omitempty"` 37 DefaultOptions DefaultDNSRule `json:"-"` 38 LogicalOptions LogicalDNSRule `json:"-"` 39 } 40 41 type DNSRule _DNSRule 42 43 func (r DNSRule) MarshalJSON() ([]byte, error) { 44 var v any 45 switch r.Type { 46 case C.RuleTypeDefault: 47 r.Type = "" 48 v = r.DefaultOptions 49 case C.RuleTypeLogical: 50 v = r.LogicalOptions 51 default: 52 return nil, E.New("unknown rule type: " + r.Type) 53 } 54 return MarshallObjects((_DNSRule)(r), v) 55 } 56 57 func (r *DNSRule) UnmarshalJSON(bytes []byte) error { 58 err := json.Unmarshal(bytes, (*_DNSRule)(r)) 59 if err != nil { 60 return err 61 } 62 var v any 63 switch r.Type { 64 case "", C.RuleTypeDefault: 65 r.Type = C.RuleTypeDefault 66 v = &r.DefaultOptions 67 case C.RuleTypeLogical: 68 v = &r.LogicalOptions 69 default: 70 return E.New("unknown rule type: " + r.Type) 71 } 72 err = UnmarshallExcluded(bytes, (*_DNSRule)(r), v) 73 if err != nil { 74 return E.Cause(err, "dns route rule") 75 } 76 return nil 77 } 78 79 type DefaultDNSRule struct { 80 Inbound Listable[string] `json:"inbound,omitempty"` 81 IPVersion int `json:"ip_version,omitempty"` 82 QueryType Listable[DNSQueryType] `json:"query_type,omitempty"` 83 Network string `json:"network,omitempty"` 84 AuthUser Listable[string] `json:"auth_user,omitempty"` 85 Protocol Listable[string] `json:"protocol,omitempty"` 86 Domain Listable[string] `json:"domain,omitempty"` 87 DomainSuffix Listable[string] `json:"domain_suffix,omitempty"` 88 DomainKeyword Listable[string] `json:"domain_keyword,omitempty"` 89 DomainRegex Listable[string] `json:"domain_regex,omitempty"` 90 Geosite Listable[string] `json:"geosite,omitempty"` 91 SourceGeoIP Listable[string] `json:"source_geoip,omitempty"` 92 SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"` 93 SourcePort Listable[uint16] `json:"source_port,omitempty"` 94 SourcePortRange Listable[string] `json:"source_port_range,omitempty"` 95 Port Listable[uint16] `json:"port,omitempty"` 96 PortRange Listable[string] `json:"port_range,omitempty"` 97 ProcessName Listable[string] `json:"process_name,omitempty"` 98 ProcessPath Listable[string] `json:"process_path,omitempty"` 99 PackageName Listable[string] `json:"package_name,omitempty"` 100 User Listable[string] `json:"user,omitempty"` 101 UserID Listable[int32] `json:"user_id,omitempty"` 102 Outbound Listable[string] `json:"outbound,omitempty"` 103 ClashMode string `json:"clash_mode,omitempty"` 104 Invert bool `json:"invert,omitempty"` 105 Server string `json:"server,omitempty"` 106 DisableCache bool `json:"disable_cache,omitempty"` 107 } 108 109 func (r DefaultDNSRule) IsValid() bool { 110 var defaultValue DefaultDNSRule 111 defaultValue.Invert = r.Invert 112 defaultValue.Server = r.Server 113 defaultValue.DisableCache = r.DisableCache 114 return !reflect.DeepEqual(r, defaultValue) 115 } 116 117 type LogicalDNSRule struct { 118 Mode string `json:"mode"` 119 Rules []DefaultDNSRule `json:"rules,omitempty"` 120 Invert bool `json:"invert,omitempty"` 121 Server string `json:"server,omitempty"` 122 DisableCache bool `json:"disable_cache,omitempty"` 123 } 124 125 func (r LogicalDNSRule) IsValid() bool { 126 return len(r.Rules) > 0 && common.All(r.Rules, DefaultDNSRule.IsValid) 127 }