[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