// 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 (
	"io";
	"net";
	"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.
// TODO(rsc): Maybe return []IP instead?
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.
		var dnserr *DNSError;
		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 += "."
		}
		var dnserr *DNSError;
		addrs, err = tryOneName(cfg, rname);
		if err == nil {
			cname = rname;
			return;
		}
	}
	return
}
