|
@@ -59,7 +59,7 @@ XFRIN_FIRST_IXFR = 3
|
|
|
|
|
|
def log_error(msg):
|
|
|
sys.stderr.write("[b10-xfrin] ")
|
|
|
- sys.stderr.write(msg)
|
|
|
+ sys.stderr.write(str(msg))
|
|
|
sys.stderr.write('\n')
|
|
|
|
|
|
|
|
@@ -85,7 +85,8 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
self._zone_name = zone_name
|
|
|
self._db_file = db_file
|
|
|
- self._records = []
|
|
|
+ self._axfrin_db = isc.auth.sqlite3_ds.AXFRInDB(self._db_file, self._zone_name)
|
|
|
+ self._soa_rr_count = 0
|
|
|
self._idle_timeout = idle_timeout
|
|
|
self.setblocking(1)
|
|
|
self.connect((master_addr, port))
|
|
@@ -168,10 +169,10 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
|
|
|
self.log_msg('transfer of \'%s\': AXFR started' % self._zone_name)
|
|
|
if ret == XFRIN_OK:
|
|
|
+ self._axfrin_db.prepare_axfrin()
|
|
|
self._send_query(rr_type.AXFR())
|
|
|
ret = self._handle_xfrin_response()
|
|
|
|
|
|
- self._insert_record_to_sqlite3(self._records)
|
|
|
self.log_msg('transfer of \'%s\' AXFR ended' % self._zone_name)
|
|
|
except XfrinException as e:
|
|
|
self.log_msg(e)
|
|
@@ -179,6 +180,8 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
#TODO, recover data source.
|
|
|
finally:
|
|
|
self.close()
|
|
|
+ if ret == XFRIN_OK:
|
|
|
+ self._axfrin_db.finish_axfrin()
|
|
|
|
|
|
return ret
|
|
|
|
|
@@ -201,7 +204,6 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
|
|
|
|
|
|
def _handle_answer_section(self, rrset_iter):
|
|
|
- soa_count = 0
|
|
|
while not rrset_iter.is_last():
|
|
|
rrset = rrset_iter.get_rrset()
|
|
|
rrset_iter.next()
|
|
@@ -215,19 +217,18 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
while not rdata_iter.is_last():
|
|
|
# Count the soa record count
|
|
|
if rrset.get_type() == rr_type.SOA():
|
|
|
- soa_count += 1
|
|
|
+ self._soa_rr_count += 1
|
|
|
+ if (self._soa_rr_count == 2):
|
|
|
+ # Avoid inserting soa record twice
|
|
|
+ return
|
|
|
|
|
|
rdata_text = rdata_iter.get_current().to_text()
|
|
|
rr_data = (rrset_name, rrset_ttl, rrset_class, rrset_type, rdata_text)
|
|
|
- self._records.append(rr_data)
|
|
|
- #self._insert_record_to_sqlite3(rr_data)
|
|
|
+ self._axfrin_db.insert_axfr_record([rr_data])
|
|
|
rdata_iter.next()
|
|
|
-
|
|
|
- return soa_count
|
|
|
|
|
|
|
|
|
def _handle_xfrin_response(self):
|
|
|
- soa_count = 0
|
|
|
while True:
|
|
|
data_len = self._get_request_response(2)
|
|
|
msg_len = socket.htons(struct.unpack('H', data_len)[0])
|
|
@@ -237,8 +238,8 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
self._check_response_status(msg)
|
|
|
|
|
|
rrset_iter = section_iter(msg, section.ANSWER())
|
|
|
- soa_count += self._handle_answer_section(rrset_iter)
|
|
|
- if soa_count == 2:
|
|
|
+ self._handle_answer_section(rrset_iter)
|
|
|
+ if self._soa_rr_count == 2:
|
|
|
return XFRIN_OK
|
|
|
|
|
|
if self._shutdown_event.is_set():
|
|
@@ -248,24 +249,19 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
|
|
|
return XFRIN_OK
|
|
|
|
|
|
- def _insert_record_to_sqlite3(self, rrs):
|
|
|
- ''' The interface provided by sqlite3_ds only support insert all the records
|
|
|
- at the end of AXFR'''
|
|
|
- isc.auth.sqlite3_ds.load(self._db_file, self._zone_name, rrs)
|
|
|
-
|
|
|
|
|
|
def writable(self):
|
|
|
'''Ignore the writable socket. '''
|
|
|
return False
|
|
|
|
|
|
|
|
|
- def log_info(self, msg):
|
|
|
+ def log_info(self, msg, type='info'):
|
|
|
# Overwrite the log function, log nothing
|
|
|
pass
|
|
|
|
|
|
def log_msg(self, msg):
|
|
|
sys.stdout.write('[b10-xfrin] ')
|
|
|
- sys.stdout.write(msg)
|
|
|
+ sys.stdout.write(str(msg))
|
|
|
sys.stdout.write('\n')
|
|
|
|
|
|
|