Serial number 0

Joseph S D Yao jsdy at cospo.osis.gov
Mon Nov 13 22:53:49 UTC 2000


On Mon, Nov 13, 2000 at 10:05:36PM +0000, Barry Margolin wrote:
> We run slave DNS for many of our customers.  Occasionally they mess up
> their serial number sequencing, usually by inserting an extra digit and
> later trying to fix it by removing the digit; that doesn't work properly,
> because the slave server complains that the new serial number is less than
> what it has.
> 
> The DNS & BIND book, on p.137, says that if the slave servers are running
> BIND 4.9 or higher, you can resynchronize by setting the serial number on
> the primary server to 0; it says that serial number 0 is treated specially,
> and forces a zone transfer every time the slave checks.
> 
> Usually this works, but occasionally we see the following message in our
> log:
> 
> named-xfer[26376]: serial from [<primary addr>], zone <domain>: 0 lower than current: 2000111900
> 
> Is this trick really supposed to work?  I looked in the BIND source, and it
> looks like it triggers named to fire off named-xfer, but named-xfer doesn't
> have any special processing of serial 0 from the master.  I suspect that
> this only worked in cases where the serial number that they were trying to
> reset from was > 2^31, so that 0 was higher than it in serial number
> arithmetic.
> 
> So is this trick supposed to work, or are we going to have to labor through
> teaching our customers how to perform real serial number arithmetic to
> start their serial number sequences over?

4.9.* and 8.1* have the following code:

	if (SEQ_GT(zp_start.z_serial, serial_no) || !serial_no) {

where

#define SEQ_GT(a,b)   ((int32_t)((a)-(b)) > 0)

In other words, if (new_serial_number - old_serial_number) > 0, then it
will accept the change.  In rot(2^32 signed), of course.

The "!serial_no" is a BAD idiom from C.  It means if serial_no == 0,
then it will also accept the change.

D&B 3rdE does not include any changes in BIND 8.2*.  In BIND 8.2*, the
code changes to:

	if (SEQ_GT(zp_start.z_serial, serial_no) || !check_serial) {

Here, check_serial is merely a boolean value - usually false (0), but
TRUE if a serial number has been passed in via "-s".  I do not find any
trace of it being set TRUE if zp_start.z_serial is valid.  I suspect
that a bug could be found here.  BUT, this also eliminates the "set
serial number to 0" trick.  You will have to use the other trick - that
of adding 2^31-1 to the old serial number, using the min of that and
2^32-1 as the new serial number, waiting for it to propagate, and then
setting it more "correctly".

-- 
Joe Yao				jsdy at cospo.osis.gov - Joseph S. D. Yao
COSPO/OSIS Computer Support					EMT-B
-----------------------------------------------------------------------
This message is not an official statement of COSPO policies.



More information about the bind-users mailing list