// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin dragonfly freebsd linux netbsd openbsd solaris

// DNS client: see RFC 1035.
// Has to be linked into package net for Dial.

// TODO(rsc):
//	Could potentially handle many outstanding lookups faster.
//	Could have a small cache.
//	Random UDP source port (net.Dial should do that for us).
//	Random request IDs.

package net

import (
	"errors"
	"io"
	"math/rand"
	"os"
	"sync"
	"time"
)

// A dnsConn represents a DNS transport endpoint.
type dnsConn interface {
	Conn

	// readDNSResponse reads a DNS response message from the DNS
	// transport endpoint and returns the received DNS response
	// message.
	readDNSResponse() (*dnsMsg, error)

	// writeDNSQuery writes a DNS query message to the DNS
	// connection endpoint.
	writeDNSQuery(*dnsMsg) error
}

func (c *UDPConn) readDNSResponse() (*dnsMsg, error) {
	b := make([]byte, 512) // see RFC 1035
	n, err := c.Read(b)
	if err != nil {
		return nil, err
	}
	msg := &dnsMsg{}
	if !msg.Unpack(b[:n]) {
		return nil, errors.New("cannot unmarshal DNS message")
	}
	return msg, nil
}

func (c *UDPConn) writeDNSQuery(msg *dnsMsg) error {
	b, ok := msg.Pack()
	if !ok {
		return errors.New("cannot marshal DNS message")
	}
	if _, err := c.Write(b); err != nil {
		return err
	}
	return nil
}

func (c *TCPConn) readDNSResponse() (*dnsMsg, error) {
	b := make([]byte, 1280) // 1280 is a reasonable initial size for IP over Ethernet, see RFC 4035
	if _, err := io.ReadFull(c, b[:2]); err != nil {
		return nil, err
	}
	l := int(b[0])<<8 | int(b[1])
	if l > len(b) {
		b = make([]byte, l)
	}
	n, err := io.ReadFull(c, b[:l])
	if err != nil {
		return nil, err
	}
	msg := &dnsMsg{}
	if !msg.Unpack(b[:n]) {
		return nil, errors.New("cannot unmarshal DNS message")
	}
	return msg, nil
}

func (c *TCPConn) writeDNSQuery(msg *dnsMsg) error {
	b, ok := msg.Pack()
	if !ok {
		return errors.New("cannot marshal DNS message")
	}
	l := uint16(len(b))
	b = append([]byte{byte(l >> 8), byte(l)}, b...)
	if _, err := c.Write(b); err != nil {
		return err
	}
	return nil
}

func (d *Dialer) dialDNS(network, server string) (dnsConn, error) {
	switch network {
	case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
	default:
		return nil, UnknownNetworkError(network)
	}
	// Calling Dial here is scary -- we have to be sure not to
	// dial a name that will require a DNS lookup, or Dial will
	// call back here to translate it. The DNS config parser has
	// already checked that all the cfg.servers[i] are IP
	// addresses, which Dial will use without a DNS lookup.
	c, err := d.Dial(network, server)
	if err != nil {
		return nil, err
	}
	switch network {
	case "tcp", "tcp4", "tcp6":
		return c.(*TCPConn), nil
	case "udp", "udp4", "udp6":
		return c.(*UDPConn), nil
	}
	panic("unreachable")
}

// exchange sends a query on the connection and hopes for a response.
func exchange(server, name string, qtype uint16, timeout time.Duration) (*dnsMsg, error) {
	d := Dialer{Timeout: timeout}
	out := dnsMsg{
		dnsMsgHdr: dnsMsgHdr{
			recursion_desired: true,
		},
		question: []dnsQuestion{
			{name, qtype, dnsClassINET},
		},
	}
	for _, network := range []string{"udp", "tcp"} {
		c, err := d.dialDNS(network, server)
		if err != nil {
			return nil, err
		}
		defer c.Close()
		if timeout > 0 {
			c.SetDeadline(time.Now().Add(timeout))
		}
		out.id = uint16(rand.Int()) ^ uint16(time.Now().UnixNano())
		if err := c.writeDNSQuery(&out); err != nil {
			return nil, err
		}
		in, err := c.readDNSResponse()
		if err != nil {
			return nil, err
		}
		if in.id != out.id {
			return nil, errors.New("DNS message ID mismatch")
		}
		if in.truncated { // see RFC 5966
			continue
		}
		return in, nil
	}
	return nil, errors.New("no answer from DNS server")
}

// Do a lookup for a single name, which must be rooted
// (otherwise answer will not find the answers).
func tryOneName(cfg *dnsConfig, name string, qtype uint16) (string, []dnsRR, error) {
	if len(cfg.servers) == 0 {
		return "", nil, &DNSError{Err: "no DNS servers", Name: name}
	}
	if len(name) >= 256 {
		return "", nil, &DNSError{Err: "DNS name too long", Name: name}
	}
	timeout := time.Duration(cfg.timeout) * time.Second
	var lastErr error
	for i := 0; i < cfg.attempts; i++ {
		for _, server := range cfg.servers {
			server = JoinHostPort(server, "53")
			msg, err := exchange(server, name, qtype, timeout)
			if err != nil {
				lastErr = &DNSError{
					Err:    err.Error(),
					Name:   name,
					Server: server,
				}
				if nerr, ok := err.(Error); ok && nerr.Timeout() {
					lastErr.(*DNSError).IsTimeout = true
				}
				continue
			}
			cname, addrs, err := answer(name, server, msg, qtype)
			if err == nil || err.(*DNSError).Err == errNoSuchHost.Error() {
				return cname, addrs, err
			}
			lastErr = err
		}
	}
	return "", nil, lastErr
}

func convertRR_A(records []dnsRR) []IP {
	addrs := make([]IP, len(records))
	for i, rr := range records {
		a := rr.(*dnsRR_A).A
		addrs[i] = IPv4(byte(a>>24), byte(a>>16), byte(a>>8), byte(a))
	}
	return addrs
}

func convertRR_AAAA(records []dnsRR) []IP {
	addrs := make([]IP, len(records))
	for i, rr := range records {
		a := make(IP, IPv6len)
		copy(a, rr.(*dnsRR_AAAA).AAAA[:])
		addrs[i] = a
	}
	return addrs
}

var cfg struct {
	ch        chan struct{}
	mu        sync.RWMutex // protects dnsConfig and dnserr
	dnsConfig *dnsConfig
	dnserr    error
}
var onceLoadConfig sync.Once

// Assume dns config file is /etc/resolv.conf here
func loadDefaultConfig() {
	loadConfig("/etc/resolv.conf", 5*time.Second, nil)
}

func loadConfig(resolvConfPath string, reloadTime time.Duration, quit <-chan chan struct{}) {
	var mtime time.Time
	cfg.ch = make(chan struct{}, 1)
	if fi, err := os.Stat(resolvConfPath); err != nil {
		cfg.dnserr = err
	} else {
		mtime = fi.ModTime()
		cfg.dnsConfig, cfg.dnserr = dnsReadConfig(resolvConfPath)
	}
	go func() {
		for {
			time.Sleep(reloadTime)
			select {
			case qresp := <-quit:
				qresp <- struct{}{}
				return
			case <-cfg.ch:
			}

			// In case of error, we keep the previous config
			fi, err := os.Stat(resolvConfPath)
			if err != nil {
				continue
			}
			// If the resolv.conf mtime didn't change, do not reload
			m := fi.ModTime()
			if m.Equal(mtime) {
				continue
			}
			mtime = m
			// In case of error, we keep the previous config
			ncfg, err := dnsReadConfig(resolvConfPath)
			if err != nil || len(ncfg.servers) == 0 {
				continue
			}
			cfg.mu.Lock()
			cfg.dnsConfig = ncfg
			cfg.dnserr = nil
			cfg.mu.Unlock()
		}
	}()
}

func lookup(name string, qtype uint16) (cname string, rrs []dnsRR, err error) {
	if !isDomainName(name) {
		return name, nil, &DNSError{Err: "invalid domain name", Name: name}
	}
	onceLoadConfig.Do(loadDefaultConfig)

	select {
	case cfg.ch <- struct{}{}:
	default:
	}

	cfg.mu.RLock()
	defer cfg.mu.RUnlock()

	if cfg.dnserr != nil || cfg.dnsConfig == nil {
		err = cfg.dnserr
		return
	}
	// If name is rooted (trailing dot) or has enough dots,
	// try it by itself first.
	rooted := len(name) > 0 && name[len(name)-1] == '.'
	if rooted || count(name, '.') >= cfg.dnsConfig.ndots {
		rname := name
		if !rooted {
			rname += "."
		}
		// Can try as ordinary name.
		cname, rrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
		if rooted || err == nil {
			return
		}
	}

	// Otherwise, try suffixes.
	for i := 0; i < len(cfg.dnsConfig.search); i++ {
		rname := name + "." + cfg.dnsConfig.search[i]
		if rname[len(rname)-1] != '.' {
			rname += "."
		}
		cname, rrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
		if err == nil {
			return
		}
	}

	// Last ditch effort: try unsuffixed only if we haven't already,
	// that is, name is not rooted and has less than ndots dots.
	if count(name, '.') < cfg.dnsConfig.ndots {
		cname, rrs, err = tryOneName(cfg.dnsConfig, name+".", qtype)
		if err == nil {
			return
		}
	}

	if e, ok := err.(*DNSError); ok {
		// Show original name passed to lookup, not suffixed one.
		// In general we might have tried many suffixes; showing
		// just one is misleading. See also golang.org/issue/6324.
		e.Name = name
	}
	return
}

// goLookupHost is the native Go implementation of LookupHost.
// Used only if cgoLookupHost refuses to handle the request
// (that is, only if cgoLookupHost is the stub in cgo_stub.go).
// Normally we let cgo use the C library resolver instead of
// depending on our lookup code, so that Go and C get the same
// answers.
func goLookupHost(name string) (addrs []string, err error) {
	// Use entries from /etc/hosts if they match.
	addrs = lookupStaticHost(name)
	if len(addrs) > 0 {
		return
	}
	ips, err := goLookupIP(name)
	if err != nil {
		return
	}
	addrs = make([]string, 0, len(ips))
	for _, ip := range ips {
		addrs = append(addrs, ip.String())
	}
	return
}

// goLookupIP is the native Go implementation of LookupIP.
// Used only if cgoLookupIP refuses to handle the request
// (that is, only if cgoLookupIP is the stub in cgo_stub.go).
// Normally we let cgo use the C library resolver instead of
// depending on our lookup code, so that Go and C get the same
// answers.
func goLookupIP(name string) (addrs []IPAddr, err error) {
	// Use entries from /etc/hosts if possible.
	haddrs := lookupStaticHost(name)
	if len(haddrs) > 0 {
		for _, haddr := range haddrs {
			haddr, zone := splitHostZone(haddr)
			if ip := ParseIP(haddr); ip != nil {
				addr := IPAddr{IP: ip, Zone: zone}
				addrs = append(addrs, addr)
			}
		}
		if len(addrs) > 0 {
			return
		}
	}
	type racer struct {
		qtype uint16
		rrs   []dnsRR
		error
	}
	lane := make(chan racer, 1)
	qtypes := [...]uint16{dnsTypeA, dnsTypeAAAA}
	for _, qtype := range qtypes {
		go func(qtype uint16) {
			_, rrs, err := lookup(name, qtype)
			lane <- racer{qtype, rrs, err}
		}(qtype)
	}
	var lastErr error
	for range qtypes {
		racer := <-lane
		if racer.error != nil {
			lastErr = racer.error
			continue
		}
		switch racer.qtype {
		case dnsTypeA:
			for _, ip := range convertRR_A(racer.rrs) {
				addr := IPAddr{IP: ip}
				addrs = append(addrs, addr)
			}
		case dnsTypeAAAA:
			for _, ip := range convertRR_AAAA(racer.rrs) {
				addr := IPAddr{IP: ip}
				addrs = append(addrs, addr)
			}
		}
	}
	if len(addrs) == 0 && lastErr != nil {
		return nil, lastErr
	}
	return addrs, nil
}

// goLookupCNAME is the native Go implementation of LookupCNAME.
// Used only if cgoLookupCNAME refuses to handle the request
// (that is, only if cgoLookupCNAME is the stub in cgo_stub.go).
// Normally we let cgo use the C library resolver instead of
// depending on our lookup code, so that Go and C get the same
// answers.
func goLookupCNAME(name string) (cname string, err error) {
	_, rr, err := lookup(name, dnsTypeCNAME)
	if err != nil {
		return
	}
	cname = rr[0].(*dnsRR_CNAME).Cname
	return
}
