diff --git a/resolver.go b/resolver.go index ca283c9..25cb39b 100644 --- a/resolver.go +++ b/resolver.go @@ -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 }