slp_misc/java/dnsjava-ixfr.diff

169 lines
4.4 KiB
Diff

diff -aur dnsjava-1.2.3/org/xbill/DNS/Zone.java dnsjava-devel/org/xbill/DNS/Zone.java
--- dnsjava-1.2.3/org/xbill/DNS/Zone.java Wed Mar 14 20:49:55 2001
+++ dnsjava-devel/org/xbill/DNS/Zone.java Mon Feb 11 23:31:13 2002
@@ -15,6 +15,14 @@
public class Zone extends NameSet {
+ private static final int FIRSTSOA = 0;
+ private static final int SECONDSOA = 1;
+ private static final int ADD = 2;
+ private static final int DEL = 3;
+ private static final int LASTSOA = 4;
+ private static final int DONE = 5;
+ private static final int AXFR = 6;
+
class AXFREnumeration implements Enumeration {
private Enumeration znames;
private Name currentName;
@@ -173,6 +181,11 @@
Record rec = Record.newRecord(zone, Type.AXFR, dclass);
Message query = Message.newQuery(rec);
Message response = res.send(query);
+
+ if (response.getHeader().getRcode() != Rcode.NOERROR) {
+ // XXX uh, oh. we fux0red up. return an error!
+ }
+
Record [] recs = response.getSectionArray(Section.ANSWER);
for (int i = 0; i < recs.length; i++) {
if (!recs[i].getName().subdomain(origin)) {
@@ -191,6 +204,114 @@
validate();
}
+ /** Perform an IXFR (if possible) to update the zone.
+ @return false if unsuccessful, true if updated.
+ non-success may be because unsupported! */
+ public boolean updateZone(String remote, Cache cache)
+ throws IOException
+ {
+ Resolver res = new SimpleResolver(remote);
+ Record rec = Record.newRecord(origin, Type.IXFR, dclass);
+ Message query = Message.newQuery(rec);
+ query.addRecord(getSOA(), Section.AUTHORITY);
+ Message response = res.send(query);
+
+ if (response.getHeader().getRcode() == Rcode.NOTIMPL) {
+ // IXFR not supported. try again as an AXFR.
+ rec = Record.newRecord(origin, Type.AXFR, dclass);
+ query = Message.newQuery(rec);
+ response = res.send(query);
+ }
+
+ if (response.getHeader().getRcode() != Rcode.NOERROR)
+ return false; // uh, oh. we fux0red up. return an error!
+
+ // XXX what about other errors? permission, etc?
+
+ Record [] recs = response.getSectionArray(Section.ANSWER);
+
+ // check for UDP overflow.
+ if ((response.getHeader().getFlag(Flags.TC) == true) ||
+ ((recs.length == 1) && (recs[0].getType() == Type.SOA))) {
+ SOARecord r = (SOARecord) recs[0];
+ return (r.getSerial() <= getSOA().getSerial());
+ // if >, then it needs updating. otherwise we're okay.
+ }
+
+ SOARecord oldSOA = getSOA();
+ SOARecord newSOA = null;
+
+ int state = FIRSTSOA;
+
+ // we're getting a successful IXFR!
+ for (int i = 0; i < recs.length; i++) {
+ if (!recs[i].getName().subdomain(origin)) {
+ if (Options.check("verbose"))
+ System.err.println(recs[i].getName() +
+ "is not in zone " + origin);
+ continue;
+ }
+
+ // now for the state machine.
+ switch(state) {
+ case FIRSTSOA: {
+ newSOA = (SOARecord) recs[i];
+ state = SECONDSOA;
+ break;
+ }
+ case SECONDSOA: {
+ Record r = recs[i];
+ if (! (r instanceof SOARecord)) {
+ clear();
+ addRecord(r);
+ state = AXFR;
+ } else {
+ state = DEL;
+ deleteRecord(r);
+ }
+ }
+ case DEL: {
+ Record r = recs[i];
+ if (r instanceof SOARecord) {
+ state = ADD;
+ addRecord(r);
+ } else {
+ deleteRecord(r);
+ }
+ }
+ case ADD: {
+ Record r = recs[i];
+ if (r instanceof SOARecord) {
+ SOARecord x = (SOARecord) r;
+ if (x.getSerial() == newSOA.getSerial()) {
+ addRecord(r);
+ state = DONE;
+ } else {
+ state = DEL;
+ deleteRecord(r);
+ }
+ } else {
+ addRecord(r);
+ }
+ }
+ case AXFR: {
+ Record r = recs[i];
+ addRecord(r);
+ }
+ case DONE: {
+ // XXX wtF? nothing should get here.
+ }
+ } // end switch
+ }
+ if (cache != null) {
+ recs = response.getSectionArray(Section.ADDITIONAL);
+ for (int i = 0; i < recs.length; i++)
+ cache.addRecord(recs[i], Credibility.ZONE_GLUE, recs);
+ }
+ validate();
+ return true;
+}
+
/** Returns the Zone's origin */
public Name
getOrigin() {
@@ -326,6 +447,22 @@
rrset.addRR(r);
}
+/**
+ * Deletes a record from the Zone
+ * @param r The record to be deleted
+ * @see Record
+ */
+public void
+deleteRecord(Record r) {
+ Name name = r.getName();
+ short type = r.getRRsetType();
+ RRset rrset = (RRset) findExactSet (name, type);
+ if (rrset == null)
+ return;
+ else
+ rrset.deleteRR(r);
+}
+
public Enumeration
AXFR() {
return new AXFREnumeration();