// 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.

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

// TODO(rsc):
//	Check periodically whether /etc/resolv.conf has changed.
//	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.
//	More substantial error reporting.

package net

import (
	"once";
	"os";
	"strings";
)

// DNSError represents a DNS lookup error.
type DNSError struct {
	Error string;	// description of the error
	Name string;	// name looked for
	Server string;	// server used
}

func (e *DNSError) String() string {
	s := "lookup " + e.Name;
	if e.Server != "" {
		s += " on " + e.Server;
	}
	s += ": " + e.Error;
	return s;
}

const noSuchHost = "no such host"

// Send a request on the connection and hope for a reply.
// Up to cfg.attempts attempts.
func _Exchange(cfg *_DNS_Config, c Conn, name string) (m *_DNS_Msg, err os.Error) {
	if len(name) >= 256 {
		return nil, &DNSError{"name too long", name, ""}
	}
	out := new(_DNS_Msg);
	out.id = 0x1234;
	out.question = []_DNS_Question{
		_DNS_Question{ name, _DNS_TypeA, _DNS_ClassINET }
	};
	out.recursion_desired = true;
	msg, ok := out.Pack();
	if !ok {
		return nil, &DNSError{"internal error - cannot pack message", name, ""}
	}

	for attempt := 0; attempt < cfg.attempts; attempt++ {
		n, err := c.Write(msg);
		if err != nil {
			return nil, err
		}

		c.SetReadTimeout(1e9);	// nanoseconds

		buf := make([]byte, 2000);	// More than enough.
		n, err = c.Read(buf);
		if isEAGAIN(err)  {
			err = nil;
			continue;
		}
		if err != nil {
			return nil, err;
		}
		buf = buf[0:n];
		in := new(_DNS_Msg);
		if !in.Unpack(buf) || in.id != out.id {
			continue
		}
		return in, nil
	}
	return nil, &DNSError{"no answer from server", name, c.RemoteAddr()}
}


// Find answer for name in dns message.
// On return, if err == nil, addrs != nil.
func answer(name, server string, dns *_DNS_Msg) (addrs []string, err *DNSError) {
	addrs = make([]string, 0, len(dns.answer));

	if dns.rcode == _DNS_RcodeNameError && dns.recursion_available {
		return nil, &DNSError{noSuchHost, name, ""}
	}
	if dns.rcode != _DNS_RcodeSuccess {
		// None of the error codes make sense
		// for the query we sent.  If we didn't get
		// a name error and we didn't get success,
		// the server is behaving incorrectly.
		return nil, &DNSError{"server misbehaving", name, server}
	}

	// Look for the name.
	// Presotto says it's okay to assume that servers listed in
	// /etc/resolv.conf are recursive resolvers.
	// We asked for recursion, so it should have included
	// all the answers we need in this one packet.
Cname:
	for cnameloop := 0; cnameloop < 10; cnameloop++ {
		addrs = addrs[0:0];
		for i := 0; i < len(dns.answer); i++ {
			rr := dns.answer[i];
			h := rr.Header();
			if h.Class == _DNS_ClassINET && h.Name == name {
				switch h.Rrtype {
				case _DNS_TypeA:
					n := len(addrs);
					a := rr.(*_DNS_RR_A).A;
					addrs = addrs[0:n+1];
					addrs[n] = IPv4(byte(a>>24), byte(a>>16), byte(a>>8), byte(a)).String();
				case _DNS_TypeCNAME:
					// redirect to cname
					name = rr.(*_DNS_RR_CNAME).Cname;
					continue Cname
				}
			}
		}
		if len(addrs) == 0 {
			return nil, &DNSError{noSuchHost, name, server}
		}
		return addrs, nil
	}

	return nil, &DNSError{"too many redirects", name, server}
}

// Do a lookup for a single name, which must be rooted
// (otherwise answer will not find the answers).
func tryOneName(cfg *_DNS_Config, name string) (addrs []string, err os.Error) {
	if len(cfg.servers) == 0 {
		return nil, &DNSError{"no DNS servers", name, ""}
	}
	for i := 0; i < len(cfg.servers); i++ {
		// 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.
		server := cfg.servers[i] + ":53";
		c, cerr := Dial("udp", "", server);
		if cerr != nil {
			err = cerr;
			continue;
		}
		msg, merr := _Exchange(cfg, c, name);
		c.Close();
		if merr != nil {
			err = merr;
			continue;
		}
		var dnserr *DNSError;
		addrs, dnserr = answer(name, server, msg);
		if dnserr != nil {
			err = dnserr;
		} else {
			err = nil;	// nil os.Error, not nil *DNSError
		}
		if dnserr == nil || dnserr.Error == noSuchHost {
			break;
		}
	}
	return;
}

var cfg *_DNS_Config
var dnserr os.Error

func loadConfig() {
	cfg, dnserr = _DNS_ReadConfig();
}

func isDomainName(s string) bool {
	// Requirements on DNS name:
	//	* must not be empty.
	//	* must be alphanumeric plus - and .
	//	* each of the dot-separated elements must begin
	//	  and end with a letter or digit.
	//	  RFC 1035 required the element to begin with a letter,
	//	  but RFC 3696 says this has been relaxed to allow digits too.
	//	  still, there must be a letter somewhere in the entire name.
	if len(s) == 0 {
		return false;
	}
	if s[len(s)-1] != '.' {	// simplify checking loop: make name end in dot
		s += ".";
	}

	last := byte('.');
	ok := false;	// ok once we've seen a letter
	for i := 0; i < len(s); i++ {
		c := s[i];
		switch {
		default:
			return false;
		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
			ok = true;
		case '0' <= c && c <= '9':
			// fine
		case c == '-':
			// byte before dash cannot be dot
			if last == '.' {
				return false;
			}
		case c == '.':
			// byte before dot cannot be dot, dash
			if last == '.' || last == '-' {
				return false;
			}
		}
		last = c;
	}

	return ok;
}

// LookupHost looks up the host name using the local DNS resolver.
// It returns the canonical name for the host and an array of that
// host's addresses.
func LookupHost(name string) (cname string, addrs []string, err os.Error) {
	if !isDomainName(name) {
		return name, nil, &DNSError{"invalid domain name", name, ""};
	}
	once.Do(loadConfig);
	if dnserr != nil || cfg == nil {
		err = 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 || strings.Count(name, ".") >= cfg.ndots {
		rname := name;
		if !rooted {
			rname += ".";
		}
		// Can try as ordinary name.
		addrs, err = tryOneName(cfg, rname);
		if err == nil {
			cname = rname;
			return;
		}
	}
	if rooted {
		return
	}

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