diff --git a/dns/client.go b/dns/client.go index d43b3a0..1dd04ef 100644 --- a/dns/client.go +++ b/dns/client.go @@ -152,12 +152,13 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) ( // use tcp to connect upstream server default network = "tcp" - dialer := c.proxy.NextDialer(qname + ":53") + dialer := c.proxy.NextDialer(qname + ":0") - // if we are resolving the dialer's domain, then use Direct to avoid dependency loop + // if we are resolving a domain which uses a forwarder `REJECT`, then use `DIRECT` instead + // so we can resolve it correctly. // TODO: dialer.Addr() == "REJECT", tricky - if strings.Contains(dialer.Addr(), qname) || dialer.Addr() == "REJECT" { - dialer = proxy.Default + if dialer.Addr() == "REJECT" { + dialer = c.proxy.NextDialer("direct:0") } // If client uses udp and no forwarders specified, use udp diff --git a/proxy/direct.go b/proxy/direct.go index 245302e..3044ae7 100644 --- a/proxy/direct.go +++ b/proxy/direct.go @@ -16,9 +16,6 @@ type Direct struct { relayTimeout time.Duration } -// Default dialer. -var Default = &Direct{dialTimeout: time.Second * 3} - func init() { RegisterDialer("direct", NewDirectDialer) } @@ -47,7 +44,10 @@ func NewDirect(intface string, dialTimeout, relayTimeout time.Duration) (*Direct // NewDirectDialer returns a direct dialer. func NewDirectDialer(s string, d Dialer) (Dialer, error) { - return NewDirect("", time.Duration(3)*time.Second, time.Duration(3)*time.Second) + if d == nil { + return NewDirect("", time.Duration(3)*time.Second, time.Duration(3)*time.Second) + } + return d, nil } // Addr returns forwarder's address. diff --git a/rule/proxy.go b/rule/proxy.go index 83c71f3..586de45 100644 --- a/rule/proxy.go +++ b/rule/proxy.go @@ -40,9 +40,11 @@ func NewProxy(mainForwarders []string, mainStrategy *Strategy, rules []*Config) } } + direct := NewFwdrGroup("", nil, mainStrategy) + rd.domainMap.Store("direct", direct) + // if there's any forwarder defined in main config, make sure they will be accessed directly. if len(mainForwarders) > 0 { - direct := NewFwdrGroup("", nil, mainStrategy) for _, f := range rd.main.fwdrs { addr := strings.Split(f.addr, ",")[0] host, _, _ := net.SplitHostPort(addr)