// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org)
// Parts of this are derived from lib/dns/xfrin.c from BIND 9; its copyright
// notice follows.

/*
 * Copyright (C) 1999-2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package org.xbill.DNS;

import java.io.*;
import java.net.*;
import java.util.*;

/**
 * An incoming DNS Zone Transfer.  To use this class, first initialize an
 * object, then call the run() method.  If run() doesn't throw an exception
 * the result will either be an IXFR-style response, an AXFR-style response,
 * or an indication that the zone is up to date.
 *
 * @author Brian Wellington
 */

public class ZoneTransferIn {

private static final int INITIALSOA	= 0;
private static final int FIRSTDATA	= 1;
private static final int IXFR_DELSOA	= 2;
private static final int IXFR_DEL	= 3;
private static final int IXFR_ADDSOA	= 4;
private static final int IXFR_ADD	= 5;
private static final int AXFR		= 6;
private static final int END		= 7;

private Name zname;
private int qtype;
private int dclass;
private long ixfr_serial;
private boolean want_fallback;
private ZoneTransferHandler handler;

private SocketAddress localAddress;
private SocketAddress address;
private TCPClient client;
private TSIG tsig;
private TSIG.StreamVerifier verifier;
private long timeout = 900 * 1000;

private int state;
private long end_serial;
private long current_serial;
private Record initialsoa;

private int rtype;

public static class Delta {
	/**
	 * All changes between two versions of a zone in an IXFR response.
	 */

	/** The starting serial number of this delta. */
	public long start;

	/** The ending serial number of this delta. */
	public long end;

	/** A list of records added between the start and end versions */
	public List adds;

	/** A list of records deleted between the start and end versions */
	public List deletes;

	private
	Delta() {
		adds = new ArrayList();
		deletes = new ArrayList();
	}
}

public static interface ZoneTransferHandler {
	/**
	 * Handles a Zone Transfer.
	 */

	/**
	 * Called when an AXFR transfer begins.
	 */
	public void startAXFR() throws ZoneTransferException;

	/**
	 * Called when an IXFR transfer begins.
	 */
	public void startIXFR() throws ZoneTransferException;

	/**
	 * Called when a series of IXFR deletions begins.
	 * @param soa The starting SOA.
	 */
	public void startIXFRDeletes(Record soa) throws ZoneTransferException;

	/**
	 * Called when a series of IXFR adds begins.
	 * @param soa The starting SOA.
	 */
	public void startIXFRAdds(Record soa) throws ZoneTransferException;

	/**
	 * Called for each content record in an AXFR.
	 * @param r The DNS record.
	 */
	public void handleRecord(Record r) throws ZoneTransferException;
};

private static class BasicHandler implements ZoneTransferHandler {
	private List axfr;
	private List ixfr;

	public void startAXFR() {
		axfr = new ArrayList();
	}

	public void startIXFR() {
		ixfr = new ArrayList();
	}

	public void startIXFRDeletes(Record soa) {
		Delta delta = new Delta();
		delta.deletes.add(soa);
		delta.start = getSOASerial(soa);
		ixfr.add(delta);
	}

	public void startIXFRAdds(Record soa) {
		Delta delta = (Delta) ixfr.get(ixfr.size() - 1);
		delta.adds.add(soa);
		delta.end = getSOASerial(soa);
	}

	public void handleRecord(Record r) {
		List list;
		if (ixfr != null) {
			Delta delta = (Delta) ixfr.get(ixfr.size() - 1);
			if (delta.adds.size() > 0)
				list = delta.adds;
			else
				list = delta.deletes;
		} else
			list = axfr;
		list.add(r);
	}
};

private
ZoneTransferIn() {}

private
ZoneTransferIn(Name zone, int xfrtype, long serial, boolean fallback,
	       SocketAddress address, TSIG key)
{
	this.address = address;
	this.tsig = key;
	if (zone.isAbsolute())
		zname = zone;
	else {
		try {
			zname = Name.concatenate(zone, Name.root);
		}
		catch (NameTooLongException e) {
			throw new IllegalArgumentException("ZoneTransferIn: " +
							   "name too long");
		}
	}
	qtype = xfrtype;
	dclass = DClass.IN;
	ixfr_serial = serial;
	want_fallback = fallback;
	state = INITIALSOA;
}

/**
 * Instantiates a ZoneTransferIn object to do an AXFR (full zone transfer).
 * @param zone The zone to transfer.
 * @param address The host/port from which to transfer the zone.
 * @param key The TSIG key used to authenticate the transfer, or null.
 * @return The ZoneTransferIn object.
 * @throws UnknownHostException The host does not exist.
 */
public static ZoneTransferIn
newAXFR(Name zone, SocketAddress address, TSIG key) {
	return new ZoneTransferIn(zone, Type.AXFR, 0, false, address, key);
}

/**
 * Instantiates a ZoneTransferIn object to do an AXFR (full zone transfer).
 * @param zone The zone to transfer.
 * @param host The host from which to transfer the zone.
 * @param port The port to connect to on the server, or 0 for the default.
 * @param key The TSIG key used to authenticate the transfer, or null.
 * @return The ZoneTransferIn object.
 * @throws UnknownHostException The host does not exist.
 */
public static ZoneTransferIn
newAXFR(Name zone, String host, int port, TSIG key)
throws UnknownHostException
{
	if (port == 0)
		port = SimpleResolver.DEFAULT_PORT;
	return newAXFR(zone, new InetSocketAddress(host, port), key);
}

/**
 * Instantiates a ZoneTransferIn object to do an AXFR (full zone transfer).
 * @param zone The zone to transfer.
 * @param host The host from which to transfer the zone.
 * @param key The TSIG key used to authenticate the transfer, or null.
 * @return The ZoneTransferIn object.
 * @throws UnknownHostException The host does not exist.
 */
public static ZoneTransferIn
newAXFR(Name zone, String host, TSIG key)
throws UnknownHostException
{
	return newAXFR(zone, host, 0, key);
}

/**
 * Instantiates a ZoneTransferIn object to do an IXFR (incremental zone
 * transfer).
 * @param zone The zone to transfer.
 * @param serial The existing serial number.
 * @param fallback If true, fall back to AXFR if IXFR is not supported.
 * @param address The host/port from which to transfer the zone.
 * @param key The TSIG key used to authenticate the transfer, or null.
 * @return The ZoneTransferIn object.
 * @throws UnknownHostException The host does not exist.
 */
public static ZoneTransferIn
newIXFR(Name zone, long serial, boolean fallback, SocketAddress address,
	TSIG key)
{
	return new ZoneTransferIn(zone, Type.IXFR, serial, fallback, address,
				  key);
}

/**
 * Instantiates a ZoneTransferIn object to do an IXFR (incremental zone
 * transfer).
 * @param zone The zone to transfer.
 * @param serial The existing serial number.
 * @param fallback If true, fall back to AXFR if IXFR is not supported.
 * @param host The host from which to transfer the zone.
 * @param port The port to connect to on the server, or 0 for the default.
 * @param key The TSIG key used to authenticate the transfer, or null.
 * @return The ZoneTransferIn object.
 * @throws UnknownHostException The host does not exist.
 */
public static ZoneTransferIn
newIXFR(Name zone, long serial, boolean fallback, String host, int port,
	TSIG key)
throws UnknownHostException
{
	if (port == 0)
		port = SimpleResolver.DEFAULT_PORT;
	return newIXFR(zone, serial, fallback,
		       new InetSocketAddress(host, port), key);
}

/**
 * Instantiates a ZoneTransferIn object to do an IXFR (incremental zone
 * transfer).
 * @param zone The zone to transfer.
 * @param serial The existing serial number.
 * @param fallback If true, fall back to AXFR if IXFR is not supported.
 * @param host The host from which to transfer the zone.
 * @param key The TSIG key used to authenticate the transfer, or null.
 * @return The ZoneTransferIn object.
 * @throws UnknownHostException The host does not exist.
 */
public static ZoneTransferIn
newIXFR(Name zone, long serial, boolean fallback, String host, TSIG key)
throws UnknownHostException
{
	return newIXFR(zone, serial, fallback, host, 0, key);
}

/**
 * Gets the name of the zone being transferred.
 */
public Name
getName() {
	return zname;
}

/**
 * Gets the type of zone transfer (either AXFR or IXFR).
 */
public int
getType() {
	return qtype;
}

/**
 * Sets a timeout on this zone transfer.  The default is 900 seconds (15
 * minutes).
 * @param secs The maximum amount of time that this zone transfer can take.
 */
public void
setTimeout(int secs) {
	if (secs < 0)
		throw new IllegalArgumentException("timeout cannot be " +
						   "negative");
	timeout = 1000L * secs;
}

/**
 * Sets an alternate DNS class for this zone transfer.
 * @param dclass The class to use instead of class IN.
 */
public void
setDClass(int dclass) {
	DClass.check(dclass);
	this.dclass = dclass;
}

/**
 * Sets the local address to bind to when sending messages.
 * @param addr The local address to send messages from.
 */
public void
setLocalAddress(SocketAddress addr) {
	this.localAddress = addr;
}

private void
openConnection() throws IOException {
	long endTime = System.currentTimeMillis() + timeout;
	client = new TCPClient(endTime);
	if (localAddress != null)
		client.bind(localAddress);
	client.connect(address);
}

private void
sendQuery() throws IOException {
	Record question = Record.newRecord(zname, qtype, dclass);

	Message query = new Message();
	query.getHeader().setOpcode(Opcode.QUERY);
	query.addRecord(question, Section.QUESTION);
	if (qtype == Type.IXFR) {
		Record soa = new SOARecord(zname, dclass, 0, Name.root,
					   Name.root, ixfr_serial,
					   0, 0, 0, 0);
		query.addRecord(soa, Section.AUTHORITY);
	}
	if (tsig != null) {
		tsig.apply(query, null);
		verifier = new TSIG.StreamVerifier(tsig, query.getTSIG());
	}
	byte [] out = query.toWire(Message.MAXLENGTH);
	client.send(out);
}

private static long
getSOASerial(Record rec) {
	SOARecord soa = (SOARecord) rec;
	return soa.getSerial();
}

private void
logxfr(String s) {
	if (Options.check("verbose"))
		System.out.println(zname + ": " + s);
}

private void
fail(String s) throws ZoneTransferException {
	throw new ZoneTransferException(s);
}

private void
fallback() throws ZoneTransferException {
	if (!want_fallback)
		fail("server doesn't support IXFR");

	logxfr("falling back to AXFR");
	qtype = Type.AXFR;
	state = INITIALSOA;
}

private void
parseRR(Record rec) throws ZoneTransferException {
	int type = rec.getType();
	Delta delta;

	switch (state) {
	case INITIALSOA:
		if (type != Type.SOA)
			fail("missing initial SOA");
		initialsoa = rec;
		// Remember the serial number in the initial SOA; we need it
		// to recognize the end of an IXFR.
		end_serial = getSOASerial(rec);
		if (qtype == Type.IXFR &&
		    Serial.compare(end_serial, ixfr_serial) <= 0)
		{
			logxfr("up to date");
			state = END;
			break;
		}
		state = FIRSTDATA;
		break;

	case FIRSTDATA:
		// If the transfer begins with 1 SOA, it's an AXFR.
		// If it begins with 2 SOAs, it's an IXFR.
		if (qtype == Type.IXFR && type == Type.SOA &&
		    getSOASerial(rec) == ixfr_serial)
		{
			rtype = Type.IXFR;
			handler.startIXFR();
			logxfr("got incremental response");
			state = IXFR_DELSOA;
		} else {
			rtype = Type.AXFR;
			handler.startAXFR();
			handler.handleRecord(initialsoa);
			logxfr("got nonincremental response");
			state = AXFR;
		}
		parseRR(rec); // Restart...
		return;

	case IXFR_DELSOA:
		handler.startIXFRDeletes(rec);
		state = IXFR_DEL;
		break;

	case IXFR_DEL:
		if (type == Type.SOA) {
			current_serial = getSOASerial(rec);
			state = IXFR_ADDSOA;
			parseRR(rec); // Restart...
			return;
		}
		handler.handleRecord(rec);
		break;

	case IXFR_ADDSOA:
		handler.startIXFRAdds(rec);
		state = IXFR_ADD;
		break;

	case IXFR_ADD:
		if (type == Type.SOA) {
			long soa_serial = getSOASerial(rec);
			if (soa_serial == end_serial) {
				state = END;
				break;
			} else if (soa_serial != current_serial) {
				fail("IXFR out of sync: expected serial " +
				     current_serial + " , got " + soa_serial);
			} else {
				state = IXFR_DELSOA;
				parseRR(rec); // Restart...
				return;
			}
		}
		handler.handleRecord(rec);
		break;

	case AXFR:
		// Old BINDs sent cross class A records for non IN classes.
		if (type == Type.A && rec.getDClass() != dclass)
			break;
		handler.handleRecord(rec);
		if (type == Type.SOA) {
			state = END;
		}
		break;

	case END:
		fail("extra data");
		break;

	default:
		fail("invalid state");
		break;
	}
}

private void
closeConnection() {
	try {
		if (client != null)
			client.cleanup();
	}
	catch (IOException e) {
	}
}

private Message
parseMessage(byte [] b) throws WireParseException {
	try {
		return new Message(b);
	}
	catch (IOException e) {
		if (e instanceof WireParseException)
			throw (WireParseException) e;
		throw new WireParseException("Error parsing message");
	}
}

private void
doxfr() throws IOException, ZoneTransferException {
	sendQuery();
	while (state != END) {
		byte [] in = client.recv();
		Message response =  parseMessage(in);
		if (response.getHeader().getRcode() == Rcode.NOERROR &&
		    verifier != null)
		{
			TSIGRecord tsigrec = response.getTSIG();

			int error = verifier.verify(response, in);
			if (error != Rcode.NOERROR)
				fail("TSIG failure");
		}

		Record [] answers = response.getSectionArray(Section.ANSWER);

		if (state == INITIALSOA) {
			int rcode = response.getRcode();
			if (rcode != Rcode.NOERROR) {
				if (qtype == Type.IXFR &&
				    rcode == Rcode.NOTIMP)
				{
					fallback();
					doxfr();
					return;
				}
				fail(Rcode.string(rcode));
			}

			Record question = response.getQuestion();
			if (question != null && question.getType() != qtype) {
				fail("invalid question section");
			}

			if (answers.length == 0 && qtype == Type.IXFR) {
				fallback();
				doxfr();
				return;
			}
		}

		for (int i = 0; i < answers.length; i++) {
			parseRR(answers[i]);
		}

		if (state == END && verifier != null &&
		    !response.isVerified())
			fail("last message must be signed");
	}
}

/**
 * Does the zone transfer.
 * @param handler The callback object that handles the zone transfer data.
 * @throws IOException The zone transfer failed to due an IO problem.
 * @throws ZoneTransferException The zone transfer failed to due a problem
 * with the zone transfer itself.
 */
public void
run(ZoneTransferHandler handler) throws IOException, ZoneTransferException {
	this.handler = handler;
	try {
		openConnection();
		doxfr();
	}
	finally {
		closeConnection();
	}
}

/**
 * Does the zone transfer.
 * @return A list, which is either an AXFR-style response (List of Records),
 * and IXFR-style response (List of Deltas), or null, which indicates that
 * an IXFR was performed and the zone is up to date.
 * @throws IOException The zone transfer failed to due an IO problem.
 * @throws ZoneTransferException The zone transfer failed to due a problem
 * with the zone transfer itself.
 */
public List
run() throws IOException, ZoneTransferException {
	BasicHandler handler = new BasicHandler();
	run(handler);
	if (handler.axfr != null)
		return handler.axfr;
	return handler.ixfr;
}

private BasicHandler
getBasicHandler() throws IllegalArgumentException {
	if (handler instanceof BasicHandler)
		return (BasicHandler) handler;
	throw new IllegalArgumentException("ZoneTransferIn used callback " +
					   "interface");
}

/**
 * Returns true if the response is an AXFR-style response (List of Records).
 * This will be true if either an IXFR was performed, an IXFR was performed
 * and the server provided a full zone transfer, or an IXFR failed and
 * fallback to AXFR occurred.
 */
public boolean
isAXFR() {
	return (rtype == Type.AXFR);
}

/**
 * Gets the AXFR-style response.
 * @throws IllegalArgumentException The transfer used the callback interface,
 * so the response was not stored.
 */
public List
getAXFR() {
	BasicHandler handler = getBasicHandler();
	return handler.axfr;
}

/**
 * Returns true if the response is an IXFR-style response (List of Deltas).
 * This will be true only if an IXFR was performed and the server provided
 * an incremental zone transfer.
 */
public boolean
isIXFR() {
	return (rtype == Type.IXFR);
}

/**
 * Gets the IXFR-style response.
 * @throws IllegalArgumentException The transfer used the callback interface,
 * so the response was not stored.
 */
public List
getIXFR() {
	BasicHandler handler = getBasicHandler();
	return handler.ixfr;
}

/**
 * Returns true if the response indicates that the zone is up to date.
 * This will be true only if an IXFR was performed.
 * @throws IllegalArgumentException The transfer used the callback interface,
 * so the response was not stored.
 */
public boolean
isCurrent() {
	BasicHandler handler = getBasicHandler();
	return (handler.axfr == null && handler.ixfr == null);
}

}
