169 lines
4.4 KiB
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();
|