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