BIND 10 trac1514, updated. db1b2905e965e85882dc7c36903839b0ffbec3f0 [1514] This ticket implements serial number incrementally update in DDNS module. This ticket is based on the snapshot of trac1457

BIND 10 source code commits bind10-changes at lists.isc.org
Thu May 31 12:36:19 UTC 2012


The branch, trac1514 has been updated
       via  db1b2905e965e85882dc7c36903839b0ffbec3f0 (commit)
      from  0cdd1593225256d36486590cfca23ab35ae15879 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit db1b2905e965e85882dc7c36903839b0ffbec3f0
Author: haikuo zhang <zhanghaikuo at cnnic.cn>
Date:   Thu May 31 20:28:17 2012 +0800

    [1514] This ticket implements serial number incrementally update in DDNS module.
    This ticket is based on the snapshot of trac1457

-----------------------------------------------------------------------

Summary of changes:
 src/lib/python/isc/ddns/session.py             |   47 ++++++++++++++-
 src/lib/python/isc/ddns/tests/session_tests.py |   75 +++++++++++++++++++++++-
 2 files changed, 117 insertions(+), 5 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/python/isc/ddns/session.py b/src/lib/python/isc/ddns/session.py
index 4af8540..e0a93e8 100644
--- a/src/lib/python/isc/ddns/session.py
+++ b/src/lib/python/isc/ddns/session.py
@@ -112,6 +112,45 @@ def convert_rrset_class(rrset, rrclass):
         new_rrset.add_rdata(isc.dns.Rdata(rrset.get_type(), rrclass, wire))
     return new_rrset
 
+class DDNSSOA:
+    '''Class to handle the SOA in the DNS update '''
+
+    def __get_serial_internal(self, origin_soa):
+        '''get serial number from soa'''
+        return Serial(int(origin_soa.get_rdata()[0].to_text().split()[2]))
+
+    def __write_soa_internal(self, origin_soa, soa_num):
+        '''write serial number to soa'''
+        new_soa = RRset(origin_soa.get_name(), origin_soa.get_class(),
+                        RRType.SOA(), origin_soa.get_ttl())
+        new_content = ""
+        index = 0
+        for i in origin_soa.get_rdata()[0].to_text().split():
+            if(index == 2):
+                # the second item is serial number
+                new_content = "%s %d"%(new_content, soa_num.get_value())
+            else:
+                new_content = "%s %s"%(new_content, i)
+            index += 1
+        new_soa.add_rdata(Rdata(origin_soa.get_type(), origin_soa.get_class(),
+                                new_content))
+        return new_soa
+
+    def soa_update_check(self, origin_soa, new_soa):
+        old_serial = self.__get_serial_internal(origin_soa)
+        new_serial = self.__get_serial_internal(new_soa)
+        if(new_serial >= old_serial):
+            return True
+        else:
+            return False
+
+    def update_soa(self, origin_soa, inc_number = 1):
+        soa_num = self.__get_serial_internal(origin_soa)
+        soa_num = soa_num + inc_number
+        if soa_num.get_value() == 0:
+            soa_num = soa_num + 1
+        return self.__write_soa_internal(origin_soa, soa_num)
+
 class UpdateSession:
     '''Protocol handling for a single dynamic update request.
 
@@ -677,13 +716,17 @@ class UpdateSession:
         result, old_soa, _ = self.__finder.find(self.__zname, RRType.SOA(),
                                                 ZoneFinder.NO_WILDCARD |
                                                 ZoneFinder.FIND_GLUE_OK)
-
+        serial_operation = DDNSSOA()
         if self.__added_soa is not None:
-            new_soa = self.__added_soa
             # serial check goes here
+            if serial_operation.soa_update_check(old_soa, self.__added_soa):
+                new_soa = self.__added_soa
+            else:
+                pass
         else:
             new_soa = old_soa
             # increment goes here
+            new_soa = serial_operation.update_soa(new_soa)
 
         diff.delete_data(old_soa)
         diff.add_data(new_soa)
diff --git a/src/lib/python/isc/ddns/tests/session_tests.py b/src/lib/python/isc/ddns/tests/session_tests.py
index 63f7885..30c6148 100644
--- a/src/lib/python/isc/ddns/tests/session_tests.py
+++ b/src/lib/python/isc/ddns/tests/session_tests.py
@@ -89,6 +89,66 @@ def add_rdata(rrset, rdata):
                                   rrset.get_class(),
                                   rdata))
 
+class TestDDNSSOA(unittest.TestCase):
+    '''unittest for the DDNSSOA'''
+    def test_update_soa(self):
+        '''unittest for update_soa function'''
+        soa_update = DDNSSOA()
+        soa_rr = create_rrset("example.org", TEST_RRCLASS,
+                              RRType.SOA(), 3600, ["ns1.example.org. " +
+                              "admin.example.org. " +
+                              "1233 3600 1800 2419200 7200"])
+        expected_soa_rr = create_rrset("example.org", TEST_RRCLASS,
+                                       RRType.SOA(), 3600, ["ns1.example.org. "
+                                       + "admin.example.org. " +
+                                       "1234 3600 1800 2419200 7200"])
+        self.assertEqual(soa_update.update_soa(soa_rr).get_rdata()[0].to_text(),
+                         expected_soa_rr.get_rdata()[0].to_text())
+        max_serial = 2 ** 32 - 1
+        soa_rdata = "%d %s"%(max_serial,"3600 1800 2419200 7200")
+        soa_rr = create_rrset("example.org", TEST_RRCLASS, RRType.SOA(), 3600,
+                              ["ns1.example.org. " + "admin.example.org. " +
+                              soa_rdata])
+        expected_soa_rr = create_rrset("example.org", TEST_RRCLASS,
+                                       RRType.SOA(), 3600, ["ns1.example.org. "
+                                       + "admin.example.org. " +
+                                       "1 3600 1800 2419200 7200"])
+        self.assertEqual(soa_update.update_soa(soa_rr).get_rdata()[0].to_text(),
+                         expected_soa_rr.get_rdata()[0].to_text())
+
+    def test_soa_update_check(self):
+        '''unittest for soa_update_check function'''
+        small_soa_rr = create_rrset("example.org", TEST_RRCLASS, RRType.SOA(),
+                                    3600, ["ns1.example.org. " +
+                                    "admin.example.org. " +
+                                    "1233 3600 1800 2419200 7200"])
+        large_soa_rr = create_rrset("example.org", TEST_RRCLASS, RRType.SOA(),
+                                    3600, ["ns1.example.org. " +
+                                    "admin.example.org. " +
+                                    "1234 3600 1800 2419200 7200"])
+        soa_update = DDNSSOA()
+        # The case of (i1 < i2 and i2 - i1 < 2^(SERIAL_BITS - 1)) in rfc 1982
+        self.assertTrue(soa_update.soa_update_check(small_soa_rr,
+                                                    large_soa_rr))
+        self.assertFalse(soa_update.soa_update_check(large_soa_rr,
+                                                     small_soa_rr))
+        small_serial = 1235 + 2 ** 31
+        soa_rdata = "%d %s"%(small_serial,"3600 1800 2419200 7200")
+        small_soa_rr = create_rrset("example.org", TEST_RRCLASS, RRType.SOA(),
+                                    3600, ["ns1.example.org. " +
+                                           "admin.example.org. " +
+                                           soa_rdata])
+        large_soa_rr = create_rrset("example.org", TEST_RRCLASS, RRType.SOA(),
+                                    3600, ["ns1.example.org. " +
+                                    "admin.example.org. " +
+                                    "1234 3600 1800 2419200 7200"])
+        # The case of (i1 > i2 and i1 - i2 > 2^(SERIAL_BITS - 1)) in rfc 1982
+        self.assertTrue(soa_update.soa_update_check(small_soa_rr,
+                                                    large_soa_rr))
+        self.assertFalse(soa_update.soa_update_check(large_soa_rr,
+                                                     small_soa_rr))
+
+
 class SessionTest(unittest.TestCase):
     '''Session tests'''
     def setUp(self):
@@ -946,6 +1006,15 @@ class SessionTest(unittest.TestCase):
                                       [ "ns1.example.org. " +
                                         "admin.example.org. " +
                                         "1234 3600 1800 2419200 7200" ])
+        # At some point, the SOA SERIAL will be auto-incremented
+        incremented_soa_rrset_01 = create_rrset("example.org", TEST_RRCLASS,
+                RRType.SOA(), 3600, ["ns1.example.org. " +
+                                     "admin.example.org. " +
+                                     "1235 3600 1800 2419200 7200" ])
+        incremented_soa_rrset_02 = create_rrset("example.org", TEST_RRCLASS,
+                RRType.SOA(), 3600, ["ns1.example.org. " +
+                                     "admin.example.org. " +
+                                     "1236 3600 1800 2419200 7200" ])
 
         # We will delete some of the NS records
         orig_ns_rrset = create_rrset("example.org", TEST_RRCLASS,
@@ -978,16 +1047,16 @@ class SessionTest(unittest.TestCase):
         self.check_inzone_data(isc.datasrc.ZoneFinder.SUCCESS,
                                isc.dns.Name("example.org"),
                                RRType.SOA(),
-                               orig_soa_rrset)
+                               incremented_soa_rrset_01)
 
         # If we delete everything at the apex, the SOA and NS rrsets should be
-        # untouched
+        # untouched (but serial will be incremented)
         self.check_full_handle_result(Rcode.NOERROR(),
                                       [ self.rrset_update_del_name_apex ])
         self.check_inzone_data(isc.datasrc.ZoneFinder.SUCCESS,
                                isc.dns.Name("example.org"),
                                RRType.SOA(),
-                               orig_soa_rrset)
+                               incremented_soa_rrset_02)
         self.check_inzone_data(isc.datasrc.ZoneFinder.SUCCESS,
                                isc.dns.Name("example.org"),
                                RRType.NS(),



More information about the bind10-changes mailing list