[Pdns-dev] [PATCH] Implement "Serial Number Arithmetic" (RFC 1982)

Sven Wegener swegener at gentoo.org
Tue Feb 5 23:19:42 CET 2008

Hi all,

"Serial Number Arithmetic" (also known as "sequence space arithmetic") is 
the magic that makes the SOA serial 536870912 higher/newer than 
3113851289. It is the magic that helps you to reset your serial, if you 
have screwed it up and a slave is not going to perform a zone transfer, 
because its local copy of the zone has a serial larger than yours.

A serial by itself does not have any meaning. It can only be compared to 
another serial. Starting from your current serial, the next 2^31-1 
(2147483647) serials (wrapping around after 4294967295 to 0) are 
considered higher. The 2^31-1 serial coming before your serial (wrapping 
around after 0 to 4294967295) are considered lower. There are some cases 
that are undefined. Taking the serials 536870912 and 2684354560, you would 
clearly say that the latter is higher than the former. But in sequence 
space arithmetic neither is higher or lower than the other.

We need to mark our zones for which we have not done a zone transfer. Even 
0 does not have any special meaning in sequence space arithmetic. But the 
RFC recommends not to use 0 as a serial, because implementations have 
incorrectly associated the serial 0 with something special. The patch 
treats 0 as outdated and will perform a zone transfer regardless of the 
other serial. I'm not quite happy with that, but it's probably the easiest 
method to reach the goal.

There are only two occurences of serial number comparison, that's why I 
kept them open-coded, without moving the comparison into its own function. 
Maybe worth doing it, but I do not know in which file the function fits.


Sven Wegener
Gentoo Developer
-------------- next part --------------
Index: pdns/communicator.cc
--- pdns/communicator.cc	(revision 1132)
+++ pdns/communicator.cc	(working copy)
@@ -261,16 +261,16 @@
       try {
 	resolver.getSoaSerial(*iter, i->zone, &theirserial);
-	if(theirserial<i->serial) {
+	if(ourserial!=0 && (theirserial<ourserial && ourserial-theirserial<2147483648 || theirserial>ourserial && theirserial-ourserial>2147483648)) {
 	  L<<Logger::Error<<"Domain "<<i->zone<<" more recent than master, our serial "<<ourserial<<" > their serial "<<theirserial<<endl;
-	else if(theirserial==i->serial) {
+	else if(theirserial==ourserial) {
 	  L<<Logger::Warning<<"Domain "<<i->zone<<" is fresh"<<endl;
 	else {
-	  L<<Logger::Warning<<"Domain "<<i->zone<<" is stale, master serial "<<theirserial<<", our serial "<<i->serial<<endl;
+	  L<<Logger::Warning<<"Domain "<<i->zone<<" is stale, master serial "<<theirserial<<", our serial "<<ourserial<<endl;
 	  addSuckRequest(i->zone, *iter);
Index: pdns/packethandler.cc
--- pdns/packethandler.cc	(revision 1132)
+++ pdns/packethandler.cc	(working copy)
@@ -524,7 +524,7 @@
     return RCode::ServFail;
-  if(theirserial<=di.serial) {
+  if(theirserial==di.serial || (di.serial!=0 && (theirserial<di.serial && di.serial-theirserial<2147483648 || theirserial>di.serial && theirserial-di.serial>2147483648))) {
     L<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from "<< authServer <<", we are up to date: "<<
     return RCode::NoError;

More information about the Pdns-dev mailing list