You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.2 KiB
99 lines
2.2 KiB
package dns |
|
|
|
import ( |
|
"bufio" |
|
"os" |
|
"strconv" |
|
"strings" |
|
) |
|
|
|
// ClientConfig wraps the contents of the /etc/resolv.conf file. |
|
type ClientConfig struct { |
|
Servers []string // servers to use |
|
Search []string // suffixes to append to local name |
|
Port string // what port to use |
|
Ndots int // number of dots in name to trigger absolute lookup |
|
Timeout int // seconds before giving up on packet |
|
Attempts int // lost packets before giving up on server, not used in the package dns |
|
} |
|
|
|
// ClientConfigFromFile parses a resolv.conf(5) like file and returns |
|
// a *ClientConfig. |
|
func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) { |
|
file, err := os.Open(resolvconf) |
|
if err != nil { |
|
return nil, err |
|
} |
|
defer file.Close() |
|
c := new(ClientConfig) |
|
scanner := bufio.NewScanner(file) |
|
c.Servers = make([]string, 0) |
|
c.Search = make([]string, 0) |
|
c.Port = "53" |
|
c.Ndots = 1 |
|
c.Timeout = 5 |
|
c.Attempts = 2 |
|
|
|
for scanner.Scan() { |
|
if err := scanner.Err(); err != nil { |
|
return nil, err |
|
} |
|
line := scanner.Text() |
|
f := strings.Fields(line) |
|
if len(f) < 1 { |
|
continue |
|
} |
|
switch f[0] { |
|
case "nameserver": // add one name server |
|
if len(f) > 1 { |
|
// One more check: make sure server name is |
|
// just an IP address. Otherwise we need DNS |
|
// to look it up. |
|
name := f[1] |
|
c.Servers = append(c.Servers, name) |
|
} |
|
|
|
case "domain": // set search path to just this domain |
|
if len(f) > 1 { |
|
c.Search = make([]string, 1) |
|
c.Search[0] = f[1] |
|
} else { |
|
c.Search = make([]string, 0) |
|
} |
|
|
|
case "search": // set search path to given servers |
|
c.Search = make([]string, len(f)-1) |
|
for i := 0; i < len(c.Search); i++ { |
|
c.Search[i] = f[i+1] |
|
} |
|
|
|
case "options": // magic options |
|
for i := 1; i < len(f); i++ { |
|
s := f[i] |
|
switch { |
|
case len(s) >= 6 && s[:6] == "ndots:": |
|
n, _ := strconv.Atoi(s[6:]) |
|
if n < 1 { |
|
n = 1 |
|
} |
|
c.Ndots = n |
|
case len(s) >= 8 && s[:8] == "timeout:": |
|
n, _ := strconv.Atoi(s[8:]) |
|
if n < 1 { |
|
n = 1 |
|
} |
|
c.Timeout = n |
|
case len(s) >= 8 && s[:9] == "attempts:": |
|
n, _ := strconv.Atoi(s[9:]) |
|
if n < 1 { |
|
n = 1 |
|
} |
|
c.Attempts = n |
|
case s == "rotate": |
|
/* not imp */ |
|
} |
|
} |
|
} |
|
} |
|
return c, nil |
|
}
|
|
|