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