resolver now can be compatible with /etc/resolv.conf

This commit is contained in:
ginuerzh 2018-11-12 20:20:41 +08:00
parent d9cce6332c
commit 1e24898e87

View File

@ -67,6 +67,7 @@ type resolver struct {
Timeout time.Duration
TTL time.Duration
period time.Duration
domain string
}
// NewResolver create a new Resolver with the given name servers and resolution timeout.
@ -99,6 +100,9 @@ func (r *resolver) Resolve(host string) (ips []net.IP, err error) {
return []net.IP{ip}, nil
}
if !strings.Contains(host, ".") && r.domain != "" {
host = host + "." + r.domain
}
ips = r.loadCache(host)
if len(ips) > 0 {
if Debug {
@ -198,62 +202,76 @@ func (r *resolver) storeCache(name string, ips []net.IP) {
func (r *resolver) Reload(rd io.Reader) error {
var nss []NameServer
scanner := bufio.NewScanner(rd)
for scanner.Scan() {
line := scanner.Text()
split := func(line string) []string {
if line == "" {
return nil
}
if n := strings.IndexByte(line, '#'); n >= 0 {
line = line[:n]
}
line = strings.Replace(line, "\t", " ", -1)
line = strings.TrimSpace(line)
if line == "" {
continue
}
var ss []string
for _, s := range strings.Split(line, " ") {
if s = strings.TrimSpace(s); s != "" {
ss = append(ss, s)
}
}
return ss
}
scanner := bufio.NewScanner(rd)
for scanner.Scan() {
line := scanner.Text()
ss := split(line)
if len(ss) == 0 {
continue
}
if len(ss) >= 2 {
// timeout option
if strings.ToLower(ss[0]) == "timeout" {
switch ss[0] {
case "timeout": // timeout option
if len(ss) > 1 {
r.Timeout, _ = time.ParseDuration(ss[1])
continue
}
// ttl option
if strings.ToLower(ss[0]) == "ttl" {
case "ttl": // ttl option
if len(ss) > 1 {
r.TTL, _ = time.ParseDuration(ss[1])
continue
}
// reload option
if strings.ToLower(ss[0]) == "reload" {
case "reload": // reload option
if len(ss) > 1 {
r.period, _ = time.ParseDuration(ss[1])
continue
}
}
var ns NameServer
switch len(ss) {
case 1:
ns.Addr = ss[0]
case 2:
ns.Addr = ss[0]
ns.Protocol = ss[1]
case "domain":
if len(ss) > 1 {
r.domain = ss[1]
}
case "search", "sortlist", "options": // we don't support these features in /etc/resolv.conf
case "nameserver": // nameserver option, compatible with /etc/resolv.conf
if len(ss) <= 1 {
break
}
ss = ss[1:]
fallthrough
default:
ns.Addr = ss[0]
ns.Protocol = ss[1]
ns.Hostname = ss[2]
var ns NameServer
switch len(ss) {
case 0:
break
case 1:
ns.Addr = ss[0]
case 2:
ns.Addr = ss[0]
ns.Protocol = ss[1]
default:
ns.Addr = ss[0]
ns.Protocol = ss[1]
ns.Hostname = ss[2]
}
nss = append(nss, ns)
}
nss = append(nss, ns)
}
if err := scanner.Err(); err != nil {
return err
}