BIND 10 master, updated. fb2001dc826b485c3d86ab3eff689c3f13c5b710 Merge branch 'master' into trac1514 [1514] merge master to trac1514 Conflicts: src/lib/python/isc/ddns/session.py src/lib/python/isc/ddns/tests/session_tests.py

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Jun 11 05:43:08 UTC 2012


The branch, master has been updated
       via  fb2001dc826b485c3d86ab3eff689c3f13c5b710 (commit)
       via  5f5ebca253e112f149d67b171ce1c86cbd3d4a1a (commit)
       via  0ed47de0a1900e15b7c70bfd67fc907ce85ff2cb (commit)
       via  4d25eba05071e631333c26580ae495c50c6ae895 (commit)
       via  e63d7f5a896e05c9a5ee143dbca5fbc7ce9b8950 (commit)
       via  db1b2905e965e85882dc7c36903839b0ffbec3f0 (commit)
      from  9b2f2c4d4f87cf7672a3aa8efc25fb73400dce3a (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 fb2001dc826b485c3d86ab3eff689c3f13c5b710
Merge: 5f5ebca 9b2f2c4
Author: haikuo zhang <zhanghaikuo at cnnic.cn>
Date:   Mon Jun 11 13:40:59 2012 +0800

    Merge branch 'master' into trac1514
    [1514] merge master to trac1514
    Conflicts:
    	src/lib/python/isc/ddns/session.py
    	src/lib/python/isc/ddns/tests/session_tests.py

commit 5f5ebca253e112f149d67b171ce1c86cbd3d4a1a
Author: haikuo zhang <zhanghaikuo at cnnic.cn>
Date:   Fri Jun 8 11:49:29 2012 +0800

    [1514] polished codes, added execption operation for DDNS_SOA

commit 0ed47de0a1900e15b7c70bfd67fc907ce85ff2cb
Author: haikuo zhang <zhanghaikuo at cnnic.cn>
Date:   Thu Jun 7 10:13:57 2012 +0800

    [1514] If the new serial number is greater or equal to the old one, the SOA in
    zone should be replaced by the new one. If not, the serial number in SOA will be
    increased automatically

commit 4d25eba05071e631333c26580ae495c50c6ae895
Author: haikuo zhang <zhanghaikuo at cnnic.cn>
Date:   Fri Jun 1 14:45:26 2012 +0800

    [1514] modified the comments. Appended the prerequisite comments for update_soa
    function in DDNS_SOA class

commit e63d7f5a896e05c9a5ee143dbca5fbc7ce9b8950
Author: haikuo zhang <zhanghaikuo at cnnic.cn>
Date:   Fri Jun 1 13:57:20 2012 +0800

    [1514] appended some comments for DDNS_SOA and simplify __write_soa_internal
    function

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             |   71 ++++++++++++++++--
 src/lib/python/isc/ddns/tests/session_tests.py |   94 ++++++++++++++++++++----
 2 files changed, 146 insertions(+), 19 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/python/isc/ddns/session.py b/src/lib/python/isc/ddns/session.py
index 6cb2c98..d36f6fd 100644
--- a/src/lib/python/isc/ddns/session.py
+++ b/src/lib/python/isc/ddns/session.py
@@ -125,6 +125,58 @@ def collect_rrsets(collection, rrset):
     if not found:
         collection.append(rrset)
 
+class DDNS_SOA:
+    '''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 back serial number to soa'''
+        new_soa = RRset(origin_soa.get_name(), origin_soa.get_class(),
+                        RRType.SOA(), origin_soa.get_ttl())
+        soa_rdata_parts = origin_soa.get_rdata()[0].to_text().split()
+        soa_rdata_parts[2] = str(soa_num.get_value())
+        new_soa.add_rdata(Rdata(origin_soa.get_type(), origin_soa.get_class(),
+                                " ".join(soa_rdata_parts)))
+        return new_soa
+
+    def soa_update_check(self, origin_soa, new_soa):
+        '''Check whether the new soa is valid. If the serial number is bigger
+        than the old one, it is valid, then return True, otherwise, return
+        False. Make sure the origin_soa and new_soa parameters are not none
+        before invoke soa_update_check.
+        Parameters:
+            origin_soa, old SOA resource record.
+            new_soa, new SOA resource record.
+        Output:
+            if the serial number of new soa is bigger than the old one, return
+            True, otherwise return False.
+        '''
+        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):
+        ''' Update the soa number incrementally as RFC 2136. Please make sure
+        that the origin_soa exists and not none before invoke this function.
+        Parameters:
+            origin_soa, the soa resource record which will be updated.
+            inc_number, the number which will be added into the serial number of
+            origin_soa, the default value is one.
+        Output:
+            The new origin soa whoes serial number has been updated.
+        '''
+        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.
 
@@ -740,14 +792,21 @@ class UpdateSession:
         # serial magic and add the newly created one
 
         # get it from DS and to increment and stuff
-        result, old_soa, _ = self.__diff.find(self.__zname, RRType.SOA())
-
-        if self.__added_soa is not None:
-            new_soa = self.__added_soa
-            # serial check goes here
+        result, old_soa, _ = self.__finder.find(self.__zname, RRType.SOA(),
+                                                ZoneFinder.NO_WILDCARD |
+                                                ZoneFinder.FIND_GLUE_OK)
+        # We may implement recovering from missing SOA data at some point, but
+        # for now servfail on such a broken state
+        if result != ZoneFinder.SUCCESS:
+            raise UpdateError("Error finding SOA record in datasource.",
+                    self.__zname, self.__zclass, Rcode.SERVFAIL())
+        serial_operation = DDNS_SOA()
+        if self.__added_soa is not None and\
+        serial_operation.soa_update_check(old_soa, self.__added_soa):
+                new_soa = self.__added_soa
         else:
-            new_soa = old_soa
             # increment goes here
+            new_soa = serial_operation.update_soa(old_soa)
 
         self.__diff.delete_data(old_soa)
         self.__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 53f1982..f191995 100644
--- a/src/lib/python/isc/ddns/tests/session_tests.py
+++ b/src/lib/python/isc/ddns/tests/session_tests.py
@@ -224,6 +224,65 @@ class SessionTestBase(unittest.TestCase):
         self.assertEqual(0, msg.get_rr_count(SECTION_UPDATE))
         self.assertEqual(0, msg.get_rr_count(Message.SECTION_ADDITIONAL))
 
+class TestDDNSSOA(unittest.TestCase):
+    '''unittest for the DDNS_SOA'''
+    def test_update_soa(self):
+        '''unittest for update_soa function'''
+        soa_update = DDNS_SOA()
+        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 = DDNS_SOA()
+        # 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(SessionTestBase):
     '''Basic session tests'''
 
@@ -1181,6 +1240,15 @@ class SessionTest(SessionTestBase):
                                       [ "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,
@@ -1205,23 +1273,23 @@ class SessionTest(SessionTestBase):
         self.check_full_handle_result(Rcode.NOERROR(),
                                       [ self.rrset_update_del_soa_apex,
                                         self.rrset_update_soa_del ])
-        self.__check_inzone_data(isc.datasrc.ZoneFinder.SUCCESS,
-                                 isc.dns.Name("example.org"),
-                                 RRType.SOA(),
-                                 orig_soa_rrset)
+        self.check_inzone_data(isc.datasrc.ZoneFinder.SUCCESS,
+                               isc.dns.Name("example.org"),
+                               RRType.SOA(),
+                               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)
-        self.__check_inzone_data(isc.datasrc.ZoneFinder.SUCCESS,
-                                 isc.dns.Name("example.org"),
-                                 RRType.NS(),
-                                 orig_ns_rrset)
+        self.check_inzone_data(isc.datasrc.ZoneFinder.SUCCESS,
+                               isc.dns.Name("example.org"),
+                               RRType.SOA(),
+                               incremented_soa_rrset_02)
+        self.check_inzone_data(isc.datasrc.ZoneFinder.SUCCESS,
+                               isc.dns.Name("example.org"),
+                               RRType.NS(),
+                               orig_ns_rrset)
         # but the MX should be gone
         self.__check_inzone_data(isc.datasrc.ZoneFinder.NXRRSET,
                                  isc.dns.Name("example.org"),



More information about the bind10-changes mailing list