Add bolt provider, rewrite hosts, start of api, start of update via nsupdate
This commit is contained in:
		@ -1,5 +1,6 @@
 | 
			
		||||
package resolver
 | 
			
		||||
 | 
			
		||||
type Nameserver struct {
 | 
			
		||||
	net string
 | 
			
		||||
	address string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"meow.tf/joker/godns/log"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"meow.tf/joker/godns/utils"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
@ -19,24 +19,29 @@ import (
 | 
			
		||||
 | 
			
		||||
type ResolvError struct {
 | 
			
		||||
	qname, net  string
 | 
			
		||||
	nameservers []string
 | 
			
		||||
	nameservers []*Nameserver
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ResolvError) Error() string {
 | 
			
		||||
	errmsg := fmt.Sprintf("%s resolv failed on %s (%s)", e.qname, strings.Join(e.nameservers, "; "), e.net)
 | 
			
		||||
	return errmsg
 | 
			
		||||
	nameservers := make([]string, len(e.nameservers))
 | 
			
		||||
 | 
			
		||||
	for i, nameserver := range e.nameservers {
 | 
			
		||||
		nameservers[i] = nameserver.address
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fmt.Sprintf("%s resolv failed on %s (%s)", e.qname, strings.Join(nameservers, "; "), e.net)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RResp struct {
 | 
			
		||||
	msg        *dns.Msg
 | 
			
		||||
	nameserver string
 | 
			
		||||
	nameserver *Nameserver
 | 
			
		||||
	rtt        time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Resolver struct {
 | 
			
		||||
	servers       []string
 | 
			
		||||
	domain_server *suffixTreeNode
 | 
			
		||||
	config        *Settings
 | 
			
		||||
	servers      []*Nameserver
 | 
			
		||||
	domainServer *suffixTreeNode
 | 
			
		||||
	config       *Settings
 | 
			
		||||
 | 
			
		||||
	clients map[string]*dns.Client
 | 
			
		||||
	clientLock sync.RWMutex
 | 
			
		||||
@ -44,9 +49,9 @@ type Resolver struct {
 | 
			
		||||
 | 
			
		||||
func NewResolver(c Settings) *Resolver {
 | 
			
		||||
	r := &Resolver{
 | 
			
		||||
		servers:       []string{},
 | 
			
		||||
		domain_server: newSuffixTreeRoot(),
 | 
			
		||||
		config:        &c,
 | 
			
		||||
		servers:      make([]*Nameserver, 0),
 | 
			
		||||
		domainServer: newSuffixTreeRoot(),
 | 
			
		||||
		config:       &c,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.ServerListFile) > 0 {
 | 
			
		||||
@ -63,7 +68,7 @@ func NewResolver(c Settings) *Resolver {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, server := range clientConfig.Servers {
 | 
			
		||||
			r.servers = append(r.servers, net.JoinHostPort(server, clientConfig.Port))
 | 
			
		||||
			r.servers = append(r.servers, &Nameserver{net: "udp", address: net.JoinHostPort(server, clientConfig.Port)})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -92,7 +97,7 @@ func (r *Resolver) parseServerListFile(buf *os.File) {
 | 
			
		||||
		line = strings.TrimSpace(line[idx+1:])
 | 
			
		||||
 | 
			
		||||
		if strings.HasPrefix(line, "https://") {
 | 
			
		||||
			r.servers = append(r.servers, line)
 | 
			
		||||
			r.servers = append(r.servers, &Nameserver{net: "https", address: line})
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -106,7 +111,7 @@ func (r *Resolver) parseServerListFile(buf *os.File) {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			r.domain_server.sinsert(strings.Split(domain, "."), ip)
 | 
			
		||||
			r.domainServer.sinsert(strings.Split(domain, "."), ip)
 | 
			
		||||
		case 1:
 | 
			
		||||
			srvPort := strings.Split(line, "#")
 | 
			
		||||
 | 
			
		||||
@ -130,7 +135,7 @@ func (r *Resolver) parseServerListFile(buf *os.File) {
 | 
			
		||||
				port = srvPort[1]
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			r.servers = append(r.servers, net.JoinHostPort(ip, port))
 | 
			
		||||
			r.servers = append(r.servers, &Nameserver{address: net.JoinHostPort(ip, port)})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -159,7 +164,7 @@ func (r *Resolver) Lookup(net string, req *dns.Msg) (message *dns.Msg, err error
 | 
			
		||||
 | 
			
		||||
	res := make(chan *RResp, 1)
 | 
			
		||||
	var wg sync.WaitGroup
 | 
			
		||||
	L := func(resolver *Resolver, nameserver string) {
 | 
			
		||||
	L := func(resolver *Resolver, nameserver *Nameserver) {
 | 
			
		||||
		defer wg.Done()
 | 
			
		||||
 | 
			
		||||
		c, err := resolver.resolverFor(net, nameserver)
 | 
			
		||||
@ -169,7 +174,7 @@ func (r *Resolver) Lookup(net string, req *dns.Msg) (message *dns.Msg, err error
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		r, rtt, err := c.Exchange(req, nameserver)
 | 
			
		||||
		r, rtt, err := c.Exchange(req, nameserver.address)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Warn("%s socket error on %s", qname, nameserver)
 | 
			
		||||
@ -213,18 +218,21 @@ func (r *Resolver) Lookup(net string, req *dns.Msg) (message *dns.Msg, err error
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
	select {
 | 
			
		||||
	case re := <-res:
 | 
			
		||||
		log.Debug("%s resolv on %s rtt: %v", utils.UnFqdn(qname), re.nameserver, re.rtt)
 | 
			
		||||
		log.Debug("%s resolv on %s rtt: %v", utils.UnFqdn(qname), re.nameserver.address, re.rtt)
 | 
			
		||||
		return re.msg, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, ResolvError{qname, net, nameservers}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Resolver) resolverFor(net, nameserver string) (*dns.Client, error) {
 | 
			
		||||
	key := net
 | 
			
		||||
func (r *Resolver) resolverFor(network string, n *Nameserver) (*dns.Client, error) {
 | 
			
		||||
	key := network
 | 
			
		||||
 | 
			
		||||
	if net == "tcp-tls" {
 | 
			
		||||
		key = net + ":" + nameserver
 | 
			
		||||
	// Use HTTPS if network is https, or TLS to force secure connections
 | 
			
		||||
	if n.net == "https" {
 | 
			
		||||
		key = n.net
 | 
			
		||||
	} else if n.net == "tcp-tls" {
 | 
			
		||||
		key = n.net + ":" + n.address
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r.clientLock.RLock()
 | 
			
		||||
@ -235,21 +243,27 @@ func (r *Resolver) resolverFor(net, nameserver string) (*dns.Client, error) {
 | 
			
		||||
		return client, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if net != "tcp" && net != "tcp-tls" && net != "https" && net != "udp" {
 | 
			
		||||
	if n.net != "tcp" && n.net != "tcp-tls" && n.net != "https" && n.net != "udp" {
 | 
			
		||||
		return nil, errors.New("unknown network type")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	timeout := r.Timeout()
 | 
			
		||||
 | 
			
		||||
	client = &dns.Client{
 | 
			
		||||
		Net: net,
 | 
			
		||||
		Net: n.net,
 | 
			
		||||
		ReadTimeout: timeout,
 | 
			
		||||
		WriteTimeout: timeout,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if strings.HasSuffix(nameserver, ":853") {
 | 
			
		||||
		client.TLSConfig = &tls.Config{
 | 
			
		||||
	if n.net == "tcp-tls" {
 | 
			
		||||
		host, _, err := net.SplitHostPort(n.address)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			host = n.address
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		client.TLSConfig = &tls.Config{
 | 
			
		||||
			ServerName: host,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -260,27 +274,23 @@ func (r *Resolver) resolverFor(net, nameserver string) (*dns.Client, error) {
 | 
			
		||||
	return client, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Namservers return the array of nameservers, with port number appended.
 | 
			
		||||
// Nameservers return the array of nameservers, with port number appended.
 | 
			
		||||
// '#' in the name is treated as port separator, as with dnsmasq.
 | 
			
		||||
 | 
			
		||||
func (r *Resolver) Nameservers(qname string) []string {
 | 
			
		||||
func (r *Resolver) Nameservers(qname string) []*Nameserver {
 | 
			
		||||
	queryKeys := strings.Split(qname, ".")
 | 
			
		||||
	queryKeys = queryKeys[:len(queryKeys)-1] // ignore last '.'
 | 
			
		||||
 | 
			
		||||
	ns := []string{}
 | 
			
		||||
	if v, found := r.domain_server.search(queryKeys); found {
 | 
			
		||||
	if v, found := r.domainServer.search(queryKeys); found {
 | 
			
		||||
		log.Debug("%s found in domain server list, upstream: %v", qname, v)
 | 
			
		||||
 | 
			
		||||
		ns = append(ns, net.JoinHostPort(v, "53"))
 | 
			
		||||
		//Ensure query the specific upstream nameserver in async Lookup() function.
 | 
			
		||||
		return ns
 | 
			
		||||
		return []*Nameserver{
 | 
			
		||||
			{net: "udp", address: net.JoinHostPort(v, "53")},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, nameserver := range r.servers {
 | 
			
		||||
		ns = append(ns, nameserver)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ns
 | 
			
		||||
	return r.servers
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Resolver) Timeout() time.Duration {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user