github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/net/dnsconfig_unix.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build darwin dragonfly freebsd linux netbsd openbsd solaris !nacl 6 7 // Read system DNS config from /etc/resolv.conf 8 9 package net 10 11 type dnsConfig struct { 12 servers []string // servers to use 13 search []string // suffixes to append to local name 14 ndots int // number of dots in name to trigger absolute lookup 15 timeout int // seconds before giving up on packet 16 attempts int // lost packets before giving up on server 17 rotate bool // round robin among servers 18 } 19 20 // See resolv.conf(5) on a Linux machine. 21 // TODO(rsc): Supposed to call uname() and chop the beginning 22 // of the host name to get the default search domain. 23 func dnsReadConfig(filename string) (*dnsConfig, error) { 24 file, err := open(filename) 25 if err != nil { 26 return nil, &DNSConfigError{err} 27 } 28 defer file.close() 29 conf := &dnsConfig{ 30 ndots: 1, 31 timeout: 5, 32 attempts: 2, 33 } 34 for line, ok := file.readLine(); ok; line, ok = file.readLine() { 35 f := getFields(line) 36 if len(f) < 1 { 37 continue 38 } 39 switch f[0] { 40 case "nameserver": // add one name server 41 if len(f) > 1 && len(conf.servers) < 3 { // small, but the standard limit 42 // One more check: make sure server name is 43 // just an IP address. Otherwise we need DNS 44 // to look it up. 45 if parseIPv4(f[1]) != nil { 46 conf.servers = append(conf.servers, f[1]) 47 } else if ip, _ := parseIPv6(f[1], true); ip != nil { 48 conf.servers = append(conf.servers, f[1]) 49 } 50 } 51 52 case "domain": // set search path to just this domain 53 if len(f) > 1 { 54 conf.search = []string{f[1]} 55 } 56 57 case "search": // set search path to given servers 58 conf.search = make([]string, len(f)-1) 59 for i := 0; i < len(conf.search); i++ { 60 conf.search[i] = f[i+1] 61 } 62 63 case "options": // magic options 64 for i := 1; i < len(f); i++ { 65 s := f[i] 66 switch { 67 case hasPrefix(s, "ndots:"): 68 n, _, _ := dtoi(s, 6) 69 if n < 1 { 70 n = 1 71 } 72 conf.ndots = n 73 case hasPrefix(s, "timeout:"): 74 n, _, _ := dtoi(s, 8) 75 if n < 1 { 76 n = 1 77 } 78 conf.timeout = n 79 case hasPrefix(s, "attempts:"): 80 n, _, _ := dtoi(s, 9) 81 if n < 1 { 82 n = 1 83 } 84 conf.attempts = n 85 case s == "rotate": 86 conf.rotate = true 87 } 88 } 89 } 90 } 91 return conf, nil 92 } 93 94 func hasPrefix(s, prefix string) bool { 95 return len(s) >= len(prefix) && s[:len(prefix)] == prefix 96 }