| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- package option
- import (
- "context"
- "net/netip"
- C "github.com/sagernet/sing-box/constant"
- E "github.com/sagernet/sing/common/exceptions"
- "github.com/sagernet/sing/common/json"
- "github.com/sagernet/sing/common/json/badjson"
- "github.com/sagernet/sing/common/json/badoption"
- M "github.com/sagernet/sing/common/metadata"
- "github.com/sagernet/sing/service"
- )
- type RawDNSOptions struct {
- Servers []DNSServerOptions `json:"servers,omitempty"`
- Rules []DNSRule `json:"rules,omitempty"`
- Final string `json:"final,omitempty"`
- ReverseMapping bool `json:"reverse_mapping,omitempty"`
- DNSClientOptions
- }
- type DNSOptions struct {
- RawDNSOptions
- }
- const (
- legacyDNSFakeIPRemovedMessage = "legacy DNS fakeip options are deprecated in sing-box 1.12.0 and removed in sing-box 1.14.0, checkout migration: https://sing-box.sagernet.org/migration/#migrate-to-new-dns-server-formats"
- legacyDNSServerRemovedMessage = "legacy DNS server formats are deprecated in sing-box 1.12.0 and removed in sing-box 1.14.0, checkout migration: https://sing-box.sagernet.org/migration/#migrate-to-new-dns-server-formats"
- )
- type removedLegacyDNSOptions struct {
- FakeIP json.RawMessage `json:"fakeip,omitempty"`
- }
- func (o *DNSOptions) UnmarshalJSONContext(ctx context.Context, content []byte) error {
- var legacyOptions removedLegacyDNSOptions
- err := json.UnmarshalContext(ctx, content, &legacyOptions)
- if err != nil {
- return err
- }
- if len(legacyOptions.FakeIP) != 0 {
- return E.New(legacyDNSFakeIPRemovedMessage)
- }
- return badjson.UnmarshallExcludedContext(ctx, content, legacyOptions, &o.RawDNSOptions)
- }
- type DNSClientOptions struct {
- Strategy DomainStrategy `json:"strategy,omitempty"`
- DisableCache bool `json:"disable_cache,omitempty"`
- DisableExpire bool `json:"disable_expire,omitempty"`
- IndependentCache bool `json:"independent_cache,omitempty"`
- CacheCapacity uint32 `json:"cache_capacity,omitempty"`
- Optimistic *OptimisticDNSOptions `json:"optimistic,omitempty"`
- ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
- }
- type _OptimisticDNSOptions struct {
- Enabled bool `json:"enabled,omitempty"`
- Timeout badoption.Duration `json:"timeout,omitempty"`
- }
- type OptimisticDNSOptions _OptimisticDNSOptions
- func (o OptimisticDNSOptions) MarshalJSON() ([]byte, error) {
- if o.Timeout == 0 {
- return json.Marshal(o.Enabled)
- }
- return json.Marshal((_OptimisticDNSOptions)(o))
- }
- func (o *OptimisticDNSOptions) UnmarshalJSON(bytes []byte) error {
- err := json.Unmarshal(bytes, &o.Enabled)
- if err == nil {
- return nil
- }
- return json.UnmarshalDisallowUnknownFields(bytes, (*_OptimisticDNSOptions)(o))
- }
- type DNSTransportOptionsRegistry interface {
- CreateOptions(transportType string) (any, bool)
- }
- type _DNSServerOptions struct {
- Type string `json:"type,omitempty"`
- Tag string `json:"tag,omitempty"`
- Options any `json:"-"`
- }
- type DNSServerOptions _DNSServerOptions
- func (o *DNSServerOptions) MarshalJSONContext(ctx context.Context) ([]byte, error) {
- return badjson.MarshallObjectsContext(ctx, (*_DNSServerOptions)(o), o.Options)
- }
- func (o *DNSServerOptions) UnmarshalJSONContext(ctx context.Context, content []byte) error {
- err := json.UnmarshalContext(ctx, content, (*_DNSServerOptions)(o))
- if err != nil {
- return err
- }
- registry := service.FromContext[DNSTransportOptionsRegistry](ctx)
- if registry == nil {
- return E.New("missing DNS transport options registry in context")
- }
- var options any
- switch o.Type {
- case "", C.DNSTypeLegacy:
- return E.New(legacyDNSServerRemovedMessage)
- default:
- var loaded bool
- options, loaded = registry.CreateOptions(o.Type)
- if !loaded {
- return E.New("unknown transport type: ", o.Type)
- }
- }
- err = badjson.UnmarshallExcludedContext(ctx, content, (*_DNSServerOptions)(o), options)
- if err != nil {
- return err
- }
- o.Options = options
- return nil
- }
- type DNSServerAddressOptions struct {
- Server string `json:"server"`
- ServerPort uint16 `json:"server_port,omitempty"`
- }
- func (o DNSServerAddressOptions) Build() M.Socksaddr {
- return M.ParseSocksaddrHostPort(o.Server, o.ServerPort)
- }
- func (o DNSServerAddressOptions) ServerIsDomain() bool {
- return o.Build().IsDomain()
- }
- func (o *DNSServerAddressOptions) TakeServerOptions() ServerOptions {
- return ServerOptions(*o)
- }
- func (o *DNSServerAddressOptions) ReplaceServerOptions(options ServerOptions) {
- *o = DNSServerAddressOptions(options)
- }
- type HostsDNSServerOptions struct {
- Path badoption.Listable[string] `json:"path,omitempty"`
- Predefined *badjson.TypedMap[string, badoption.Listable[netip.Addr]] `json:"predefined,omitempty"`
- }
- type RawLocalDNSServerOptions struct {
- DialerOptions
- }
- type LocalDNSServerOptions struct {
- RawLocalDNSServerOptions
- PreferGo bool `json:"prefer_go,omitempty"`
- }
- type RemoteDNSServerOptions struct {
- RawLocalDNSServerOptions
- DNSServerAddressOptions
- }
- type RemoteTLSDNSServerOptions struct {
- RemoteDNSServerOptions
- OutboundTLSOptionsContainer
- }
- type RemoteHTTPSDNSServerOptions struct {
- RemoteTLSDNSServerOptions
- Path string `json:"path,omitempty"`
- Method string `json:"method,omitempty"`
- Headers badoption.HTTPHeader `json:"headers,omitempty"`
- }
- type FakeIPDNSServerOptions struct {
- Inet4Range *badoption.Prefix `json:"inet4_range,omitempty"`
- Inet6Range *badoption.Prefix `json:"inet6_range,omitempty"`
- }
- type DHCPDNSServerOptions struct {
- LocalDNSServerOptions
- Interface string `json:"interface,omitempty"`
- }
|