github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/infra/conf/fakedns.go (about)

     1  package conf
     2  
     3  import (
     4  	"encoding/json"
     5  	"strings"
     6  
     7  	"github.com/xtls/xray-core/app/dns/fakedns"
     8  	"github.com/xtls/xray-core/features/dns"
     9  )
    10  
    11  type FakeDNSPoolElementConfig struct {
    12  	IPPool  string `json:"ipPool"`
    13  	LRUSize int64  `json:"poolSize"`
    14  }
    15  
    16  type FakeDNSConfig struct {
    17  	pool  *FakeDNSPoolElementConfig
    18  	pools []*FakeDNSPoolElementConfig
    19  }
    20  
    21  // UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
    22  func (f *FakeDNSConfig) UnmarshalJSON(data []byte) error {
    23  	var pool FakeDNSPoolElementConfig
    24  	var pools []*FakeDNSPoolElementConfig
    25  	switch {
    26  	case json.Unmarshal(data, &pool) == nil:
    27  		f.pool = &pool
    28  	case json.Unmarshal(data, &pools) == nil:
    29  		f.pools = pools
    30  	default:
    31  		return newError("invalid fakedns config")
    32  	}
    33  	return nil
    34  }
    35  
    36  func (f *FakeDNSConfig) Build() (*fakedns.FakeDnsPoolMulti, error) {
    37  	fakeDNSPool := fakedns.FakeDnsPoolMulti{}
    38  
    39  	if f.pool != nil {
    40  		fakeDNSPool.Pools = append(fakeDNSPool.Pools, &fakedns.FakeDnsPool{
    41  			IpPool:  f.pool.IPPool,
    42  			LruSize: f.pool.LRUSize,
    43  		})
    44  		return &fakeDNSPool, nil
    45  	}
    46  
    47  	if f.pools != nil {
    48  		for _, v := range f.pools {
    49  			fakeDNSPool.Pools = append(fakeDNSPool.Pools, &fakedns.FakeDnsPool{IpPool: v.IPPool, LruSize: v.LRUSize})
    50  		}
    51  		return &fakeDNSPool, nil
    52  	}
    53  
    54  	return nil, newError("no valid FakeDNS config")
    55  }
    56  
    57  type FakeDNSPostProcessingStage struct{}
    58  
    59  func (FakeDNSPostProcessingStage) Process(config *Config) error {
    60  	fakeDNSInUse := false
    61  	isIPv4Enable, isIPv6Enable := true, true
    62  
    63  	if config.DNSConfig != nil {
    64  		for _, v := range config.DNSConfig.Servers {
    65  			if v.Address.Family().IsDomain() && strings.EqualFold(v.Address.Domain(), "fakedns") {
    66  				fakeDNSInUse = true
    67  			}
    68  		}
    69  
    70  		switch strings.ToLower(config.DNSConfig.QueryStrategy) {
    71  		case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4":
    72  			isIPv4Enable, isIPv6Enable = true, false
    73  		case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6":
    74  			isIPv4Enable, isIPv6Enable = false, true
    75  		}
    76  	}
    77  
    78  	if fakeDNSInUse {
    79  		// Add a Fake DNS Config if there is none
    80  		if config.FakeDNS == nil {
    81  			config.FakeDNS = &FakeDNSConfig{}
    82  			switch {
    83  			case isIPv4Enable && isIPv6Enable:
    84  				config.FakeDNS.pools = []*FakeDNSPoolElementConfig{
    85  					{
    86  						IPPool:  dns.FakeIPv4Pool,
    87  						LRUSize: 32768,
    88  					},
    89  					{
    90  						IPPool:  dns.FakeIPv6Pool,
    91  						LRUSize: 32768,
    92  					},
    93  				}
    94  			case !isIPv4Enable && isIPv6Enable:
    95  				config.FakeDNS.pool = &FakeDNSPoolElementConfig{
    96  					IPPool:  dns.FakeIPv6Pool,
    97  					LRUSize: 65535,
    98  				}
    99  			case isIPv4Enable && !isIPv6Enable:
   100  				config.FakeDNS.pool = &FakeDNSPoolElementConfig{
   101  					IPPool:  dns.FakeIPv4Pool,
   102  					LRUSize: 65535,
   103  				}
   104  			}
   105  		}
   106  
   107  		found := false
   108  		// Check if there is a Outbound with necessary sniffer on
   109  		var inbounds []InboundDetourConfig
   110  
   111  		if len(config.InboundConfigs) > 0 {
   112  			inbounds = append(inbounds, config.InboundConfigs...)
   113  		}
   114  		for _, v := range inbounds {
   115  			if v.SniffingConfig != nil && v.SniffingConfig.Enabled && v.SniffingConfig.DestOverride != nil {
   116  				for _, dov := range *v.SniffingConfig.DestOverride {
   117  					if strings.EqualFold(dov, "fakedns") || strings.EqualFold(dov, "fakedns+others") {
   118  						found = true
   119  						break
   120  					}
   121  				}
   122  			}
   123  		}
   124  		if !found {
   125  			newError("Defined FakeDNS but haven't enabled FakeDNS destOverride at any inbound.").AtWarning().WriteToLog()
   126  		}
   127  	}
   128  
   129  	return nil
   130  }