Feature: move hosts to the top
This commit is contained in:
parent
376516c7af
commit
4994510c87
6 changed files with 164 additions and 122 deletions
|
@ -44,7 +44,6 @@ type DNS struct {
|
||||||
IPv6 bool `yaml:"ipv6"`
|
IPv6 bool `yaml:"ipv6"`
|
||||||
NameServer []dns.NameServer `yaml:"nameserver"`
|
NameServer []dns.NameServer `yaml:"nameserver"`
|
||||||
Fallback []dns.NameServer `yaml:"fallback"`
|
Fallback []dns.NameServer `yaml:"fallback"`
|
||||||
Hosts *trie.Trie `yaml:"-"`
|
|
||||||
Listen string `yaml:"listen"`
|
Listen string `yaml:"listen"`
|
||||||
EnhancedMode dns.EnhancedMode `yaml:"enhanced-mode"`
|
EnhancedMode dns.EnhancedMode `yaml:"enhanced-mode"`
|
||||||
FakeIPRange *fakeip.Pool
|
FakeIPRange *fakeip.Pool
|
||||||
|
@ -60,6 +59,7 @@ type Config struct {
|
||||||
General *General
|
General *General
|
||||||
DNS *DNS
|
DNS *DNS
|
||||||
Experimental *Experimental
|
Experimental *Experimental
|
||||||
|
Hosts *trie.Trie
|
||||||
Rules []C.Rule
|
Rules []C.Rule
|
||||||
Users []auth.AuthUser
|
Users []auth.AuthUser
|
||||||
Proxies map[string]C.Proxy
|
Proxies map[string]C.Proxy
|
||||||
|
@ -69,7 +69,6 @@ type rawDNS struct {
|
||||||
Enable bool `yaml:"enable"`
|
Enable bool `yaml:"enable"`
|
||||||
IPv6 bool `yaml:"ipv6"`
|
IPv6 bool `yaml:"ipv6"`
|
||||||
NameServer []string `yaml:"nameserver"`
|
NameServer []string `yaml:"nameserver"`
|
||||||
Hosts map[string]string `yaml:"hosts"`
|
|
||||||
Fallback []string `yaml:"fallback"`
|
Fallback []string `yaml:"fallback"`
|
||||||
Listen string `yaml:"listen"`
|
Listen string `yaml:"listen"`
|
||||||
EnhancedMode dns.EnhancedMode `yaml:"enhanced-mode"`
|
EnhancedMode dns.EnhancedMode `yaml:"enhanced-mode"`
|
||||||
|
@ -89,6 +88,7 @@ type rawConfig struct {
|
||||||
ExternalUI string `yaml:"external-ui"`
|
ExternalUI string `yaml:"external-ui"`
|
||||||
Secret string `yaml:"secret"`
|
Secret string `yaml:"secret"`
|
||||||
|
|
||||||
|
Hosts map[string]string `yaml:"hosts"`
|
||||||
DNS rawDNS `yaml:"dns"`
|
DNS rawDNS `yaml:"dns"`
|
||||||
Experimental Experimental `yaml:"experimental"`
|
Experimental Experimental `yaml:"experimental"`
|
||||||
Proxy []map[string]interface{} `yaml:"Proxy"`
|
Proxy []map[string]interface{} `yaml:"Proxy"`
|
||||||
|
@ -135,6 +135,7 @@ func readConfig(path string) (*rawConfig, error) {
|
||||||
Mode: T.Rule,
|
Mode: T.Rule,
|
||||||
Authentication: []string{},
|
Authentication: []string{},
|
||||||
LogLevel: log.INFO,
|
LogLevel: log.INFO,
|
||||||
|
Hosts: map[string]string{},
|
||||||
Rule: []string{},
|
Rule: []string{},
|
||||||
Proxy: []map[string]interface{}{},
|
Proxy: []map[string]interface{}{},
|
||||||
ProxyGroup: []map[string]interface{}{},
|
ProxyGroup: []map[string]interface{}{},
|
||||||
|
@ -144,7 +145,6 @@ func readConfig(path string) (*rawConfig, error) {
|
||||||
DNS: rawDNS{
|
DNS: rawDNS{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
FakeIPRange: "198.18.0.1/16",
|
FakeIPRange: "198.18.0.1/16",
|
||||||
Hosts: map[string]string{},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err = yaml.Unmarshal([]byte(data), &rawConfig)
|
err = yaml.Unmarshal([]byte(data), &rawConfig)
|
||||||
|
@ -185,6 +185,12 @@ func Parse(path string) (*Config, error) {
|
||||||
}
|
}
|
||||||
config.DNS = dnsCfg
|
config.DNS = dnsCfg
|
||||||
|
|
||||||
|
hosts, err := parseHosts(rawCfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.Hosts = hosts
|
||||||
|
|
||||||
config.Users = parseAuthentication(rawCfg.Authentication)
|
config.Users = parseAuthentication(rawCfg.Authentication)
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
|
@ -460,6 +466,21 @@ func parseRules(cfg *rawConfig, proxies map[string]C.Proxy) ([]C.Rule, error) {
|
||||||
return rules, nil
|
return rules, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseHosts(cfg *rawConfig) (*trie.Trie, error) {
|
||||||
|
tree := trie.New()
|
||||||
|
if len(cfg.Hosts) != 0 {
|
||||||
|
for domain, ipStr := range cfg.Hosts {
|
||||||
|
ip := net.ParseIP(ipStr)
|
||||||
|
if ip == nil {
|
||||||
|
return nil, fmt.Errorf("%s is not a valid IP", ipStr)
|
||||||
|
}
|
||||||
|
tree.Insert(domain, ip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tree, nil
|
||||||
|
}
|
||||||
|
|
||||||
func hostWithDefaultPort(host string, defPort string) (string, error) {
|
func hostWithDefaultPort(host string, defPort string) (string, error) {
|
||||||
if !strings.Contains(host, ":") {
|
if !strings.Contains(host, ":") {
|
||||||
host += ":"
|
host += ":"
|
||||||
|
@ -544,18 +565,6 @@ func parseDNS(cfg rawDNS) (*DNS, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.Hosts) != 0 {
|
|
||||||
tree := trie.New()
|
|
||||||
for domain, ipStr := range cfg.Hosts {
|
|
||||||
ip := net.ParseIP(ipStr)
|
|
||||||
if ip == nil {
|
|
||||||
return nil, fmt.Errorf("%s is not a valid IP", ipStr)
|
|
||||||
}
|
|
||||||
tree.Insert(domain, ip)
|
|
||||||
}
|
|
||||||
dnsCfg.Hosts = tree
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.EnhancedMode == dns.FAKEIP {
|
if cfg.EnhancedMode == dns.FAKEIP {
|
||||||
_, ipnet, err := net.ParseCIDR(cfg.FakeIPRange)
|
_, ipnet, err := net.ParseCIDR(cfg.FakeIPRange)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,8 +9,74 @@ var (
|
||||||
errIPNotFound = errors.New("cannot found ip")
|
errIPNotFound = errors.New("cannot found ip")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ResolveIPv4 with a host, return ipv4
|
||||||
|
func ResolveIPv4(host string) (net.IP, error) {
|
||||||
|
if node := DefaultHosts.Search(host); node != nil {
|
||||||
|
if ip := node.Data.(net.IP).To4(); ip != nil {
|
||||||
|
return ip, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ip := net.ParseIP(host)
|
||||||
|
if ip4 := ip.To4(); ip4 != nil {
|
||||||
|
return ip4, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if DefaultResolver != nil {
|
||||||
|
return DefaultResolver.ResolveIPv4(host)
|
||||||
|
}
|
||||||
|
|
||||||
|
ipAddrs, err := net.LookupIP(host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ip := range ipAddrs {
|
||||||
|
if ip4 := ip.To4(); ip4 != nil {
|
||||||
|
return ip4, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errIPNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolveIPv6 with a host, return ipv6
|
||||||
|
func ResolveIPv6(host string) (net.IP, error) {
|
||||||
|
if node := DefaultHosts.Search(host); node != nil {
|
||||||
|
if ip := node.Data.(net.IP).To16(); ip != nil {
|
||||||
|
return ip, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ip := net.ParseIP(host)
|
||||||
|
if ip6 := ip.To16(); ip6 != nil {
|
||||||
|
return ip6, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if DefaultResolver != nil {
|
||||||
|
return DefaultResolver.ResolveIPv6(host)
|
||||||
|
}
|
||||||
|
|
||||||
|
ipAddrs, err := net.LookupIP(host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ip := range ipAddrs {
|
||||||
|
if ip6 := ip.To16(); ip6 != nil {
|
||||||
|
return ip6, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errIPNotFound
|
||||||
|
}
|
||||||
|
|
||||||
// ResolveIP with a host, return ip
|
// ResolveIP with a host, return ip
|
||||||
func ResolveIP(host string) (net.IP, error) {
|
func ResolveIP(host string) (net.IP, error) {
|
||||||
|
if node := DefaultHosts.Search(host); node != nil {
|
||||||
|
return node.Data.(net.IP), nil
|
||||||
|
}
|
||||||
|
|
||||||
if DefaultResolver != nil {
|
if DefaultResolver != nil {
|
||||||
if DefaultResolver.ipv6 {
|
if DefaultResolver.ipv6 {
|
||||||
return DefaultResolver.ResolveIP(host)
|
return DefaultResolver.ResolveIP(host)
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/component/fakeip"
|
"github.com/Dreamacro/clash/component/fakeip"
|
||||||
|
@ -12,15 +10,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type handler func(w D.ResponseWriter, r *D.Msg)
|
type handler func(w D.ResponseWriter, r *D.Msg)
|
||||||
|
type middleware func(next handler) handler
|
||||||
|
|
||||||
func withFakeIP(pool *fakeip.Pool) handler {
|
func withFakeIP(fakePool *fakeip.Pool) middleware {
|
||||||
|
return func(next handler) handler {
|
||||||
return func(w D.ResponseWriter, r *D.Msg) {
|
return func(w D.ResponseWriter, r *D.Msg) {
|
||||||
q := r.Question[0]
|
q := r.Question[0]
|
||||||
|
if q.Qtype != D.TypeA && q.Qtype != D.TypeAAAA {
|
||||||
|
next(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
host := strings.TrimRight(q.Name, ".")
|
host := strings.TrimRight(q.Name, ".")
|
||||||
|
|
||||||
rr := &D.A{}
|
rr := &D.A{}
|
||||||
rr.Hdr = D.RR_Header{Name: q.Name, Rrtype: D.TypeA, Class: D.ClassINET, Ttl: dnsDefaultTTL}
|
rr.Hdr = D.RR_Header{Name: q.Name, Rrtype: D.TypeA, Class: D.ClassINET, Ttl: dnsDefaultTTL}
|
||||||
ip := pool.Lookup(host)
|
ip := fakePool.Lookup(host)
|
||||||
rr.A = ip
|
rr.A = ip
|
||||||
msg := r.Copy()
|
msg := r.Copy()
|
||||||
msg.Answer = []D.RR{rr}
|
msg.Answer = []D.RR{rr}
|
||||||
|
@ -31,15 +36,14 @@ func withFakeIP(pool *fakeip.Pool) handler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func withResolver(resolver *Resolver) handler {
|
func withResolver(resolver *Resolver) handler {
|
||||||
return func(w D.ResponseWriter, r *D.Msg) {
|
return func(w D.ResponseWriter, r *D.Msg) {
|
||||||
msg, err := resolver.Exchange(r)
|
msg, err := resolver.Exchange(r)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
q := r.Question[0]
|
q := r.Question[0]
|
||||||
qString := fmt.Sprintf("%s %s %s", q.Name, D.Class(q.Qclass).String(), D.Type(q.Qtype).String())
|
log.Debugln("[DNS Server] Exchange %s failed: %v", q.String(), err)
|
||||||
log.Debugln("[DNS Server] Exchange %s failed: %v", qString, err)
|
|
||||||
D.HandleFailed(w, r)
|
D.HandleFailed(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -49,64 +53,23 @@ func withResolver(resolver *Resolver) handler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withHost(resolver *Resolver, next handler) handler {
|
func compose(middlewares []middleware, endpoint handler) handler {
|
||||||
hosts := resolver.hosts
|
length := len(middlewares)
|
||||||
if hosts == nil {
|
h := endpoint
|
||||||
panic("dns/withHost: hosts should not be nil")
|
for i := length - 1; i >= 0; i-- {
|
||||||
|
middleware := middlewares[i]
|
||||||
|
h = middleware(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(w D.ResponseWriter, r *D.Msg) {
|
return h
|
||||||
q := r.Question[0]
|
|
||||||
if q.Qtype != D.TypeA && q.Qtype != D.TypeAAAA {
|
|
||||||
next(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
domain := strings.TrimRight(q.Name, ".")
|
|
||||||
host := hosts.Search(domain)
|
|
||||||
if host == nil {
|
|
||||||
next(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ip := host.Data.(net.IP)
|
|
||||||
if q.Qtype == D.TypeAAAA && ip.To16() == nil {
|
|
||||||
next(w, r)
|
|
||||||
return
|
|
||||||
} else if q.Qtype == D.TypeA && ip.To4() == nil {
|
|
||||||
next(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var rr D.RR
|
|
||||||
if q.Qtype == D.TypeAAAA {
|
|
||||||
record := &D.AAAA{}
|
|
||||||
record.Hdr = D.RR_Header{Name: q.Name, Rrtype: D.TypeAAAA, Class: D.ClassINET, Ttl: dnsDefaultTTL}
|
|
||||||
record.AAAA = ip
|
|
||||||
rr = record
|
|
||||||
} else {
|
|
||||||
record := &D.A{}
|
|
||||||
record.Hdr = D.RR_Header{Name: q.Name, Rrtype: D.TypeA, Class: D.ClassINET, Ttl: dnsDefaultTTL}
|
|
||||||
record.A = ip
|
|
||||||
rr = record
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := r.Copy()
|
|
||||||
msg.Answer = []D.RR{rr}
|
|
||||||
msg.SetReply(r)
|
|
||||||
w.WriteMsg(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newHandler(resolver *Resolver) handler {
|
func newHandler(resolver *Resolver) handler {
|
||||||
|
middlewares := []middleware{}
|
||||||
|
|
||||||
if resolver.IsFakeIP() {
|
if resolver.IsFakeIP() {
|
||||||
return withFakeIP(resolver.pool)
|
middlewares = append(middlewares, withFakeIP(resolver.pool))
|
||||||
}
|
}
|
||||||
|
|
||||||
if resolver.hosts != nil {
|
return compose(middlewares, withResolver(resolver))
|
||||||
return withHost(resolver, withResolver(resolver))
|
|
||||||
}
|
|
||||||
|
|
||||||
return withResolver(resolver)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// DefaultResolver aim to resolve ip with host
|
// DefaultResolver aim to resolve ip
|
||||||
DefaultResolver *Resolver
|
DefaultResolver *Resolver
|
||||||
|
|
||||||
|
// DefaultHosts aim to resolve hosts
|
||||||
|
DefaultHosts = trie.New()
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -46,7 +49,6 @@ type Resolver struct {
|
||||||
ipv6 bool
|
ipv6 bool
|
||||||
mapping bool
|
mapping bool
|
||||||
fakeip bool
|
fakeip bool
|
||||||
hosts *trie.Trie
|
|
||||||
pool *fakeip.Pool
|
pool *fakeip.Pool
|
||||||
fallback []resolver
|
fallback []resolver
|
||||||
main []resolver
|
main []resolver
|
||||||
|
@ -56,11 +58,6 @@ type Resolver struct {
|
||||||
|
|
||||||
// ResolveIP request with TypeA and TypeAAAA, priority return TypeAAAA
|
// ResolveIP request with TypeA and TypeAAAA, priority return TypeAAAA
|
||||||
func (r *Resolver) ResolveIP(host string) (ip net.IP, err error) {
|
func (r *Resolver) ResolveIP(host string) (ip net.IP, err error) {
|
||||||
ip = net.ParseIP(host)
|
|
||||||
if ip != nil {
|
|
||||||
return ip, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ch := make(chan net.IP)
|
ch := make(chan net.IP)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(ch)
|
defer close(ch)
|
||||||
|
@ -89,26 +86,12 @@ func (r *Resolver) ResolveIP(host string) (ip net.IP, err error) {
|
||||||
|
|
||||||
// ResolveIPv4 request with TypeA
|
// ResolveIPv4 request with TypeA
|
||||||
func (r *Resolver) ResolveIPv4(host string) (ip net.IP, err error) {
|
func (r *Resolver) ResolveIPv4(host string) (ip net.IP, err error) {
|
||||||
ip = net.ParseIP(host)
|
return r.resolveIP(host, D.TypeA)
|
||||||
if ip != nil {
|
|
||||||
return ip, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
query := &D.Msg{}
|
// ResolveIPv6 request with TypeAAAA
|
||||||
query.SetQuestion(D.Fqdn(host), D.TypeA)
|
func (r *Resolver) ResolveIPv6(host string) (ip net.IP, err error) {
|
||||||
|
return r.resolveIP(host, D.TypeAAAA)
|
||||||
msg, err := r.Exchange(query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ips := r.msgToIP(msg)
|
|
||||||
if len(ips) == 0 {
|
|
||||||
return nil, errIPNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
ip = ips[0]
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exchange a batch of dns request, and it use cache
|
// Exchange a batch of dns request, and it use cache
|
||||||
|
@ -232,6 +215,17 @@ func (r *Resolver) fallbackExchange(m *D.Msg) (msg *D.Msg, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) resolveIP(host string, dnsType uint16) (ip net.IP, err error) {
|
func (r *Resolver) resolveIP(host string, dnsType uint16) (ip net.IP, err error) {
|
||||||
|
ip = net.ParseIP(host)
|
||||||
|
if dnsType == D.TypeAAAA {
|
||||||
|
if ip6 := ip.To16(); ip6 != nil {
|
||||||
|
return ip6, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ip4 := ip.To4(); ip4 != nil {
|
||||||
|
return ip4, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
query := &D.Msg{}
|
query := &D.Msg{}
|
||||||
query.SetQuestion(D.Fqdn(host), dnsType)
|
query.SetQuestion(D.Fqdn(host), dnsType)
|
||||||
|
|
||||||
|
@ -282,7 +276,6 @@ type Config struct {
|
||||||
Main, Fallback []NameServer
|
Main, Fallback []NameServer
|
||||||
IPv6 bool
|
IPv6 bool
|
||||||
EnhancedMode EnhancedMode
|
EnhancedMode EnhancedMode
|
||||||
Hosts *trie.Trie
|
|
||||||
Pool *fakeip.Pool
|
Pool *fakeip.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +290,6 @@ func New(config Config) *Resolver {
|
||||||
cache: cache.New(time.Second * 60),
|
cache: cache.New(time.Second * 60),
|
||||||
mapping: config.EnhancedMode == MAPPING,
|
mapping: config.EnhancedMode == MAPPING,
|
||||||
fakeip: config.EnhancedMode == FAKEIP,
|
fakeip: config.EnhancedMode == FAKEIP,
|
||||||
hosts: config.Hosts,
|
|
||||||
pool: config.Pool,
|
pool: config.Pool,
|
||||||
}
|
}
|
||||||
if len(config.Fallback) != 0 {
|
if len(config.Fallback) != 0 {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Dreamacro/clash/component/auth"
|
"github.com/Dreamacro/clash/component/auth"
|
||||||
|
trie "github.com/Dreamacro/clash/component/domain-trie"
|
||||||
"github.com/Dreamacro/clash/config"
|
"github.com/Dreamacro/clash/config"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/dns"
|
"github.com/Dreamacro/clash/dns"
|
||||||
|
@ -30,6 +31,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
|
||||||
updateProxies(cfg.Proxies)
|
updateProxies(cfg.Proxies)
|
||||||
updateRules(cfg.Rules)
|
updateRules(cfg.Rules)
|
||||||
updateDNS(cfg.DNS)
|
updateDNS(cfg.DNS)
|
||||||
|
updateHosts(cfg.Hosts)
|
||||||
updateExperimental(cfg.Experimental)
|
updateExperimental(cfg.Experimental)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +70,6 @@ func updateDNS(c *config.DNS) {
|
||||||
Main: c.NameServer,
|
Main: c.NameServer,
|
||||||
Fallback: c.Fallback,
|
Fallback: c.Fallback,
|
||||||
IPv6: c.IPv6,
|
IPv6: c.IPv6,
|
||||||
Hosts: c.Hosts,
|
|
||||||
EnhancedMode: c.EnhancedMode,
|
EnhancedMode: c.EnhancedMode,
|
||||||
Pool: c.FakeIPRange,
|
Pool: c.FakeIPRange,
|
||||||
})
|
})
|
||||||
|
@ -83,6 +84,10 @@ func updateDNS(c *config.DNS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateHosts(tree *trie.Trie) {
|
||||||
|
dns.DefaultHosts = tree
|
||||||
|
}
|
||||||
|
|
||||||
func updateProxies(proxies map[string]C.Proxy) {
|
func updateProxies(proxies map[string]C.Proxy) {
|
||||||
tunnel := T.Instance()
|
tunnel := T.Instance()
|
||||||
oldProxies := tunnel.Proxies()
|
oldProxies := tunnel.Proxies()
|
||||||
|
|
|
@ -213,6 +213,13 @@ func (t *Tunnel) match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
|
||||||
defer t.configMux.RUnlock()
|
defer t.configMux.RUnlock()
|
||||||
|
|
||||||
var resolved bool
|
var resolved bool
|
||||||
|
|
||||||
|
if node := dns.DefaultHosts.Search(metadata.Host); node != nil {
|
||||||
|
ip := node.Data.(net.IP)
|
||||||
|
metadata.DstIP = &ip
|
||||||
|
resolved = true
|
||||||
|
}
|
||||||
|
|
||||||
for _, rule := range t.rules {
|
for _, rule := range t.rules {
|
||||||
if !resolved && t.shouldResolveIP(rule, metadata) {
|
if !resolved && t.shouldResolveIP(rule, metadata) {
|
||||||
ip, err := t.resolveIP(metadata.Host)
|
ip, err := t.resolveIP(metadata.Host)
|
||||||
|
|
Loading…
Reference in a new issue