BIND 8.2.7 master ixfr to 9.2.2 slave
Mike Mitchell
Mike.Mitchell at sas.com
Wed May 4 17:59:02 UTC 2005
About once a day I have a BIND 9.2.2 slave truncate a zone after an IXFR
from a BIND 8 master. The packet trace shows the master sending an IXFR
response containing only two SOA records. The SOA records are =
identical,
with serial numbers one more than the IXFR request. I found this in RFC
1995:
4. Response Format
If incremental zone transfer is not available, the entire zone is
returned. The first and the last RR of the response is the SOA
record of the zone. I.e. the behavior is the same as an AXFR
response except the query type is IXFR.
I read this to indicate that two SOA records in a row would be an empty
zone, so it makes sense that BIND 9 is truncating the zone. This points
the finger back at BIND 8. I haven't found the root cause of the =
problem
in BIND 8, but I have developed a patch against BIND 8.4.6 that aborts
the query instead of sending a two-SOA response. Could someone look at
the patch and let me know if it's the right approach? I have it in
testing now but it takes some time before the two-SOA response is
triggered.=20
Here's a unified diff against BIND 8.4.6:
--- src/bin/named/ns_ixfr.c.orig 2003-11-23 18:43:35.000000000 -0500
+++ src/bin/named/ns_ixfr.c 2005-05-04 11:38:22.000000000 -0400
@@ -189,7 +189,7 @@
struct databuf *old_soadp;
ns_delta *dp;
ns_updrec *rp;
- int foundsoa;
+ int foundsoa, foundother;
=20
zp =3D &zones[qsp->xfr.zone];
soa_dp =3D (struct databuf *) findzonesoa(zp);
@@ -203,6 +203,8 @@
ns_panic(ns_log_update, 1, "sx_send_ixfr: out of memory");
memcpy(old_soadp, soa_dp, BIND_DATASIZE(soa_dp->d_size));
=20
+ foundother =3D 0;
+
again:
switch (qsp->xfr.state) {
case s_x_firstsoa:
@@ -260,10 +262,12 @@
/*
* Drop any SOA deletes
*/
- if (rp->r_dp->d_type !=3D T_SOA &&
- sx_addrr(qsp, rp->r_dname,
- rp->r_dp) < 0)
- goto cleanup;
+ if (rp->r_dp->d_type !=3D T_SOA) {
+ foundother =3D 1;
+ if (sx_addrr(qsp, rp->r_dname,
+ rp->r_dp) < 0)
+ goto cleanup;
+ }
db_detach(&rp->r_dp);
}
rp =3D NEXT(rp, r_link);
@@ -323,6 +327,7 @@
if (rp->r_opcode =3D=3D ADD &&
rp->r_dp !=3D NULL &&
rp->r_dp->d_type !=3D T_SOA) {
+ foundother =3D 1;
if (sx_addrr(qsp, rp->r_dname,
rp->r_dp) < 0)
goto cleanup;
@@ -360,9 +365,11 @@
break;
}
ns_debug(ns_log_default, 3, "IXFR: flushing %s", zp->z_origin);
- qsp->xfr.state =3D s_x_done;
- sx_flush(qsp);
- sq_writeh(qsp, sq_flushw);
+ if (foundother) {
+ qsp->xfr.state =3D s_x_done;
+ sx_flush(qsp);
+ sq_writeh(qsp, sq_flushw);
+ }
if (qsp->xfr.top.ixfr !=3D NULL) {
if(!EMPTY(*qsp->xfr.top.ixfr)) {
while ((dp =3D HEAD(*qsp->xfr.top.ixfr)) !=3D NULL) {
@@ -380,6 +387,11 @@
qsp->xfr.top.ixfr =3D NULL;
}
cleanup:
+ if (qsp->xfr.state !=3D s_x_done) {
+ ns_error(ns_log_xfer_out, "ns_ixfr: transfer aborted");
+ (void) shutdown(qsp->s_rfd, 2);
+ sq_remove(qsp);
+ }
memput(old_soadp, BIND_DATASIZE(old_soadp->d_size));
}
=20
More information about the bind-users
mailing list