[svn] commit: r3350 - in /branches/trac376/src/bin: bind10/run_bind10.sh.in xfrin/tests/Makefile.am xfrin/tests/xfrin_test.py xfrin/xfrin.py.in

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Oct 25 14:52:31 UTC 2010


Author: jelte
Date: Mon Oct 25 14:52:31 2010
New Revision: 3350

Log:
use writable API for AXFR in in xfrin.py(.in)

Modified:
    branches/trac376/src/bin/bind10/run_bind10.sh.in
    branches/trac376/src/bin/xfrin/tests/Makefile.am
    branches/trac376/src/bin/xfrin/tests/xfrin_test.py
    branches/trac376/src/bin/xfrin/xfrin.py.in

Modified: branches/trac376/src/bin/bind10/run_bind10.sh.in
==============================================================================
--- branches/trac376/src/bin/bind10/run_bind10.sh.in (original)
+++ branches/trac376/src/bin/bind10/run_bind10.sh.in Mon Oct 25 14:52:31 2010
@@ -23,7 +23,7 @@
 PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:$PATH
 export PATH
 
-PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/xfr/.libs
+PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/datasrc/python/.libs:@abs_top_builddir@/src/lib/xfr/.libs
 export PYTHONPATH
 
 # If necessary (rare cases), explicitly specify paths to dynamic libraries

Modified: branches/trac376/src/bin/xfrin/tests/Makefile.am
==============================================================================
--- branches/trac376/src/bin/xfrin/tests/Makefile.am (original)
+++ branches/trac376/src/bin/xfrin/tests/Makefile.am Mon Oct 25 14:52:31 2010
@@ -14,7 +14,7 @@
 check-local:
 	for pytest in $(PYTESTS) ; do \
 	echo Running test: $$pytest ; \
-	env PYTHONPATH=$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/bin/xfrin:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
+	env PYTHONPATH=$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/datasrc/python/.libs:$(abs_top_builddir)/src/bin/xfrin:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
 	$(LIBRARY_PATH_PLACEHOLDER) \
 	$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
 	done

Modified: branches/trac376/src/bin/xfrin/tests/xfrin_test.py
==============================================================================
--- branches/trac376/src/bin/xfrin/tests/xfrin_test.py (original)
+++ branches/trac376/src/bin/xfrin/tests/xfrin_test.py Mon Oct 25 14:52:31 2010
@@ -301,7 +301,7 @@
 
     def test_do_xfrin_empty_response(self):
         # skipping the creation of response data, so the transfer will fail.
-        self.assertEqual(self.conn.do_xfrin(False), XFRIN_FAIL)
+        self.assertRaises(XfrinTestException, self.conn.do_xfrin, False)
 
     def test_do_xfrin_bad_response(self):
         self.conn.response_generator = self._create_broken_response_data
@@ -319,10 +319,7 @@
 
     def test_do_soacheck_broken_response(self):
         self.conn.response_generator = self._create_broken_response_data
-        # XXX: TODO: this test failed here, should xfr not raise an
-        # exception but simply drop and return FAIL?
-        #self.assertEqual(self.conn.do_xfrin(True), XFRIN_FAIL)
-        self.assertRaises(MessageTooShort, self.conn.do_xfrin, True)
+        self.assertEqual(self.conn.do_xfrin(True), XFRIN_FAIL)
 
     def test_do_soacheck_badqid(self):
         # the QID mismatch would internally trigger a XfrinException exception,

Modified: branches/trac376/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac376/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac376/src/bin/xfrin/xfrin.py.in Mon Oct 25 14:52:31 2010
@@ -27,6 +27,8 @@
 import threading
 import socket
 import random
+import pydnspp
+import pydatasrc
 from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
 from isc.notify import notify_out
@@ -196,32 +198,42 @@
             logstr = 'transfer of \'%s\': AXFR ' % self._zone_name
             if ret == XFRIN_OK:
                 self.log_msg(logstr + 'started')
-                # TODO: .AXFR() RRType.AXFR()
-                self._send_query(RRType(252))
-                isc.datasrc.sqlite3_ds.load(self._db_file, self._zone_name,
-                                            self._handle_xfrin_response)
-
+                self._send_query(RRType.AXFR())
+                
+                ds = pydatasrc.DataSrc()
+                ds.init("{ \"database_file\": \"" + self._db_file +"\" }")
+                transaction = pydatasrc.DataSrcTransaction(ds, Name(self._zone_name), RRClass.IN())
+                result = ds.start_transaction(transaction, True)
+                if result != ds.SUCCESS:
+                    raise XfrinException('Failed to start transaction')
+                
+                result = ds.replace_zone(transaction, self._handle_xfrin_response)
+                if result != ds.SUCCESS:
+                    raise XfrinException('Failed to start transaction')
+                 
+                result = ds.commit_transaction(transaction)
+                if result != ds.SUCCESS:
+                    raise XfrinException('Failed to commit transaction')
+                
                 self.log_msg(logstr + 'succeeded')
 
+        except pydnspp.MessageTooShort as mts:
+            self.log_msg(mts)
+            self.log_msg(logstr + 'failed')
+            ret = XFRIN_FAIL
         except XfrinException as e:
             self.log_msg(e)
             self.log_msg(logstr + 'failed')
             ret = XFRIN_FAIL
             #TODO, recover data source.
+        except pydatasrc.DataSrcError as dse:
+            self.log_msg(dse)
+            self.log_msg(logstr + 'failed')
+            ret = XFRIN_FAIL
         except isc.datasrc.sqlite3_ds.Sqlite3DSError as e:
             self.log_msg(e)
             self.log_msg(logstr + 'failed')
             ret = XFRIN_FAIL
-        except UserWarning as e:
-            # XXX: this is an exception from our C++ library via the
-            # Boost.Python binding.  It would be better to have more more
-            # specific exceptions, but at this moment this is the finest
-            # granularity.
-            self.log_msg(e)
-            self.log_msg(logstr + 'failed')
-            ret = XFRIN_FAIL
-        finally:
-           self.close()
 
         return ret
 
@@ -257,36 +269,11 @@
         if msg.get_rr_count(Section.QUESTION()) > 1:
             raise XfrinException('query section count greater than 1')
 
-    def _handle_answer_section(self, answer_section):
-        '''Return a generator for the reponse in one tcp package to a zone transfer.'''
-
-        for rrset in answer_section:
-            rrset_name = rrset.get_name().to_text()
-            rrset_ttl = int(rrset.get_ttl().to_text())
-            rrset_class = rrset.get_class().to_text()
-            rrset_type = rrset.get_type().to_text()
-
-            for rdata in rrset.get_rdata():
-                # Count the soa record count
-                if rrset.get_type() == RRType("SOA"):
-                    self._soa_rr_count += 1
-
-                    # XXX: the current DNS message parser can't preserve the
-                    # RR order or separete the beginning and ending SOA RRs.
-                    # As a short term workaround, we simply ignore the second
-                    # SOA, and ignore the erroneous case where the transfer
-                    # session doesn't end with an SOA.
-                    if (self._soa_rr_count == 2):
-                        # Avoid inserting soa record twice
-                        break
-
-                rdata_text = rdata.to_text()
-                yield (rrset_name, rrset_ttl, rrset_class, rrset_type,
-                       rdata_text)
-
     def _handle_xfrin_response(self):
         '''Return a generator for the response to a zone transfer. '''
-        while True:
+        done = False
+        soa_seen = False
+        while not done:
             data_len = self._get_request_response(2)
             msg_len = socket.htons(struct.unpack('H', data_len)[0])
             recvdata = self._get_request_response(msg_len)
@@ -295,12 +282,24 @@
             self._check_response_status(msg)
             
             answer_section = msg.get_section(Section.ANSWER())
-            for rr in self._handle_answer_section(answer_section):
-                yield rr
-
-            if self._soa_rr_count == 2:
-                break
-            
+            for rrset in answer_section:
+                if rrset.get_type() == RRType.SOA():
+                    if soa_seen:
+                        # second one, we're done.
+                        done = True
+                        break
+                    elif rrset.get_rdata_count() == 2:
+                        # workaround for current problem where second
+                        # soa rr gets added to the first by the parser
+                        done = True
+                        new_soa = RRset(rrset.get_name(), rrset.get_class(),
+                                        rrset.get_type(), rrset.get_ttl())
+                        new_soa.add_rdata(rrset.get_rdata()[0])
+                        rrset = new_soa
+                    else:
+                        soa_seen = True
+                yield rrset
+
             if self._shutdown_event.is_set():
                 raise XfrinException('xfrin is forced to stop')
 




More information about the bind10-changes mailing list