// 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.
// 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.
//	Remove use of fmt?

package net

import (
	"fmt";
	"io";
	"net";
	"once";
	"os";
	"strings";
)

export var (
	DNS_InternalError = os.NewError("internal dns error");
	DNS_MissingConfig = os.NewError("no dns configuration");
	DNS_NoAnswer = os.NewError("dns got no answer");
	DNS_BadRequest = os.NewError("malformed dns request");
	DNS_BadReply = os.NewError("malformed dns reply");
	DNS_ServerFailure = os.NewError("dns server failure");
	DNS_NoServers = os.NewError("no dns servers");
	DNS_NameTooLong = os.NewError("dns name too long");
	DNS_RedirectLoop = os.NewError("dns redirect loop");
	DNS_NameNotFound = os.NewError("dns name not found");
);

// 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, DNS_NameTooLong
	}
	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, DNS_InternalError
	}

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

		// TODO(rsc): set up timeout or call ReadTimeout.
		// right now net does not support that.

		buf := new([]byte, 2000);	// More than enough.
		n, err = c.Read(buf);
		if err != nil {
			// TODO(rsc): only continue if timed out
			continue
		}
		buf = buf[0:n];
		in := new(DNS_Msg);
		if !in.Unpack(buf) || in.id != out.id {
			continue
		}
		return in, nil
	}
	return nil, DNS_NoAnswer
}

// Find answer for name in dns message.
// On return, if err == nil, addrs != nil.
// TODO(rsc): Maybe return *[]*[]byte (==*[]IPAddr) instead?
func Answer(name string, dns *DNS_Msg) (addrs *[]string, err *os.Error) {
	addrs = new([]string, len(dns.answer))[0:0];

	if dns.rcode == DNS_RcodeNameError && dns.authoritative {
		return nil, DNS_NameNotFound	// authoritative "no such host"
	}
	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, DNS_ServerFailure
	}

	// 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] = fmt.sprintf("%d.%d.%d.%d", (a>>24), (a>>16)&0xFF, (a>>8)&0xFF, a&0xFF);
				case DNS_TypeCNAME:
					// redirect to cname
					name = rr.(*DNS_RR_CNAME).cname;
					continue Cname
				}
			}
		}
		if len(addrs) == 0 {
			return nil, DNS_NameNotFound
		}
		return addrs, nil
	}

	// Too many redirects
	return nil, DNS_RedirectLoop
}

// 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) {
	err = DNS_NoServers;
	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.
		c, cerr := Dial("udp", "", cfg.servers[i] + ":53");
		if cerr != nil {
			err = cerr;
			continue;
		}
		msg, merr := Exchange(cfg, c, name);
		c.Close();
		if merr != nil {
			err = merr;
			continue;
		}
		addrs, aerr := Answer(name, msg);
		if aerr != nil && aerr != DNS_NameNotFound {
			err = aerr;
			continue;
		}
		return addrs, aerr;
	}
	return;
}

var cfg *DNS_Config

func LoadConfig() {
	cfg = DNS_ReadConfig();
}

export func LookupHost(name string) (name1 string, addrs *[]string, err *os.Error) {
	// TODO(rsc): Pick out obvious non-DNS names to avoid
	// sending stupid requests to the server?

	once.Do(&LoadConfig);
	if cfg == nil {
		err = DNS_MissingConfig;
		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, aerr := TryOneName(cfg, rname);
		if aerr == nil {
			return rname, addrs, nil;
		}
		err = aerr;
	}
	if rooted {
		return
	}

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