src/pkg/net/dnsconfig.go - The Go Programming Language

Golang

Source file src/pkg/net/dnsconfig.go

     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 freebsd linux netbsd openbsd
     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	// We assume it's in resolv.conf anyway.
    24	func dnsReadConfig() (*dnsConfig, error) {
    25		file, err := open("/etc/resolv.conf")
    26		if err != nil {
    27			return nil, &DNSConfigError{err}
    28		}
    29		conf := new(dnsConfig)
    30		conf.servers = make([]string, 3)[0:0] // small, but the standard limit
    31		conf.search = make([]string, 0)
    32		conf.ndots = 1
    33		conf.timeout = 5
    34		conf.attempts = 2
    35		conf.rotate = false
    36		for line, ok := file.readLine(); ok; line, ok = file.readLine() {
    37			f := getFields(line)
    38			if len(f) < 1 {
    39				continue
    40			}
    41			switch f[0] {
    42			case "nameserver": // add one name server
    43				a := conf.servers
    44				n := len(a)
    45				if len(f) > 1 && n < cap(a) {
    46					// One more check: make sure server name is
    47					// just an IP address.  Otherwise we need DNS
    48					// to look it up.
    49					name := f[1]
    50					switch len(ParseIP(name)) {
    51					case 16:
    52						name = "[" + name + "]"
    53						fallthrough
    54					case 4:
    55						a = a[0 : n+1]
    56						a[n] = name
    57						conf.servers = a
    58					}
    59				}
    60	
    61			case "domain": // set search path to just this domain
    62				if len(f) > 1 {
    63					conf.search = make([]string, 1)
    64					conf.search[0] = f[1]
    65				} else {
    66					conf.search = make([]string, 0)
    67				}
    68	
    69			case "search": // set search path to given servers
    70				conf.search = make([]string, len(f)-1)
    71				for i := 0; i < len(conf.search); i++ {
    72					conf.search[i] = f[i+1]
    73				}
    74	
    75			case "options": // magic options
    76				for i := 1; i < len(f); i++ {
    77					s := f[i]
    78					switch {
    79					case len(s) >= 6 && s[0:6] == "ndots:":
    80						n, _, _ := dtoi(s, 6)
    81						if n < 1 {
    82							n = 1
    83						}
    84						conf.ndots = n
    85					case len(s) >= 8 && s[0:8] == "timeout:":
    86						n, _, _ := dtoi(s, 8)
    87						if n < 1 {
    88							n = 1
    89						}
    90						conf.timeout = n
    91					case len(s) >= 8 && s[0:9] == "attempts:":
    92						n, _, _ := dtoi(s, 9)
    93						if n < 1 {
    94							n = 1
    95						}
    96						conf.attempts = n
    97					case s == "rotate":
    98						conf.rotate = true
    99					}
   100				}
   101			}
   102		}
   103		file.close()
   104	
   105		return conf, nil
   106	}