|
@@ -29,7 +29,7 @@ import random
|
|
|
from optparse import OptionParser, OptionValueError
|
|
|
from isc.config.ccsession import *
|
|
|
try:
|
|
|
- from bind10_dns import *
|
|
|
+ from libdns_python import *
|
|
|
except ImportError as e:
|
|
|
# C++ loadable module may not be installed; even so the xfrin process
|
|
|
# must keep running, so we warn about it and move forward.
|
|
@@ -95,14 +95,17 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
def _create_query(self, query_type):
|
|
|
'''Create dns query message. '''
|
|
|
|
|
|
- msg = message(message_mode.RENDER)
|
|
|
+ msg = Message(RENDER)
|
|
|
query_id = random.randint(1, 0xFFFF)
|
|
|
self._query_id = query_id
|
|
|
msg.set_qid(query_id)
|
|
|
- msg.set_opcode(op_code.QUERY())
|
|
|
- msg.set_rcode(rcode.NOERROR())
|
|
|
- query_question = question(name(self._zone_name), rr_class.IN(), query_type)
|
|
|
- msg.add_question(query_question)
|
|
|
+ msg.set_opcode(Opcode.QUERY())
|
|
|
+ msg.set_rcode(Rcode.NOERROR())
|
|
|
+ query_question = Question(Name(self._zone_name), RRClass("IN"), query_type)
|
|
|
+ try:
|
|
|
+ msg.add_question(query_question)
|
|
|
+ except Exception as err:
|
|
|
+ raise err
|
|
|
return msg
|
|
|
|
|
|
def _send_data(self, data):
|
|
@@ -116,13 +119,12 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
'''Send query message over TCP. '''
|
|
|
|
|
|
msg = self._create_query(query_type)
|
|
|
- obuf = output_buffer(0)
|
|
|
- render = message_render(obuf)
|
|
|
+ render = MessageRenderer()
|
|
|
msg.to_wire(render)
|
|
|
- header_len = struct.pack('H', socket.htons(obuf.get_length()))
|
|
|
+ header_len = struct.pack('H', socket.htons(render.get_length()))
|
|
|
|
|
|
self._send_data(header_len)
|
|
|
- self._send_data(obuf.get_data())
|
|
|
+ self._send_data(render.get_data())
|
|
|
|
|
|
def _get_request_response(self, size):
|
|
|
recv_size = 0
|
|
@@ -146,7 +148,7 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
True: soa serial in master is bigger
|
|
|
'''
|
|
|
|
|
|
- self._send_query(rr_type.SOA())
|
|
|
+ self._send_query(RRType("SOA"))
|
|
|
data_size = self._get_request_response(2)
|
|
|
soa_reply = self._get_request_response(int(data_size))
|
|
|
#TODO, need select soa record from data source then compare the two
|
|
@@ -160,11 +162,12 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
ret = XFRIN_OK
|
|
|
if check_soa:
|
|
|
ret = self._check_soa_serial()
|
|
|
-
|
|
|
+
|
|
|
logstr = 'transfer of \'%s\': AXFR ' % self._zone_name
|
|
|
- if ret == XFRIN_OK:
|
|
|
+ if ret == XFRIN_OK:
|
|
|
self.log_msg(logstr + 'started')
|
|
|
- self._send_query(rr_type.AXFR())
|
|
|
+ # TODO: .AXFR() RRType.AXFR()
|
|
|
+ self._send_query(RRType(252))
|
|
|
isc.datasrc.sqlite3_ds.load(self._db_file, self._zone_name,
|
|
|
self._handle_xfrin_response)
|
|
|
|
|
@@ -187,37 +190,33 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
|
|
|
#TODO, check more?
|
|
|
msg_rcode = msg.get_rcode()
|
|
|
- if msg_rcode != rcode.NOERROR():
|
|
|
+ if msg_rcode != Rcode.NOERROR():
|
|
|
raise XfrinException('error response: %s' % msg_rcode.to_text())
|
|
|
|
|
|
- if not msg.get_header_flag(message_flag.QR()):
|
|
|
+ if not msg.get_header_flag(MessageFlag.QR()):
|
|
|
raise XfrinException('response is not a response ')
|
|
|
|
|
|
if msg.get_qid() != self._query_id:
|
|
|
raise XfrinException('bad query id')
|
|
|
|
|
|
- if msg.get_rr_count(section.ANSWER()) == 0:
|
|
|
+ if msg.get_rr_count(Section.ANSWER()) == 0:
|
|
|
raise XfrinException('answer section is empty')
|
|
|
|
|
|
- if msg.get_rr_count(section.QUESTION()) > 1:
|
|
|
+ if msg.get_rr_count(Section.QUESTION()) > 1:
|
|
|
raise XfrinException('query section count greater than 1')
|
|
|
|
|
|
- def _handle_answer_section(self, rrset_iter):
|
|
|
+ def _handle_answer_section(self, answer_section):
|
|
|
'''Return a generator for the reponse in one tcp package to a zone transfer.'''
|
|
|
|
|
|
- while not rrset_iter.is_last():
|
|
|
- rrset = rrset_iter.get_rrset()
|
|
|
- rrset_iter.next()
|
|
|
+ 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()
|
|
|
|
|
|
- rdata_iter = rrset.get_rdata_iterator()
|
|
|
- rdata_iter.first()
|
|
|
- while not rdata_iter.is_last():
|
|
|
+ for rdata in rrset.get_rdata():
|
|
|
# Count the soa record count
|
|
|
- if rrset.get_type() == rr_type.SOA():
|
|
|
+ if rrset.get_type() == RRType("SOA"):
|
|
|
self._soa_rr_count += 1
|
|
|
|
|
|
# XXX: the current DNS message parser can't preserve the
|
|
@@ -229,24 +228,22 @@ class XfrinConnection(asyncore.dispatcher):
|
|
|
# Avoid inserting soa record twice
|
|
|
break
|
|
|
|
|
|
- rdata_text = rdata_iter.get_current().to_text()
|
|
|
+ rdata_text = rdata.to_text()
|
|
|
yield (rrset_name, rrset_ttl, rrset_class, rrset_type,
|
|
|
rdata_text)
|
|
|
- rdata_iter.next()
|
|
|
|
|
|
def _handle_xfrin_response(self):
|
|
|
'''Return a generator for the response to a zone transfer. '''
|
|
|
-
|
|
|
while True:
|
|
|
data_len = self._get_request_response(2)
|
|
|
msg_len = socket.htons(struct.unpack('H', data_len)[0])
|
|
|
recvdata = self._get_request_response(msg_len)
|
|
|
- msg = message(message_mode.PARSE)
|
|
|
- msg.from_wire(input_buffer(recvdata))
|
|
|
+ msg = Message(PARSE)
|
|
|
+ msg.from_wire(recvdata)
|
|
|
self._check_response_status(msg)
|
|
|
-
|
|
|
- rrset_iter = section_iter(msg, section.ANSWER())
|
|
|
- for rr in self._handle_answer_section(rrset_iter):
|
|
|
+
|
|
|
+ answer_section = msg.get_section(Section.ANSWER())
|
|
|
+ for rr in self._handle_answer_section(answer_section):
|
|
|
yield rr
|
|
|
|
|
|
if self._soa_rr_count == 2:
|
|
@@ -398,8 +395,8 @@ class Xfrin():
|
|
|
def xfrin_start(self, zone_name, db_file, master_addr,
|
|
|
port = 53,
|
|
|
check_soa = True):
|
|
|
- if "bind10_dns" not in sys.modules:
|
|
|
- return (1, "xfrin failed, can't load dns message python library: 'bind10_dns'")
|
|
|
+ if "libdns_python" not in sys.modules:
|
|
|
+ return (1, "xfrin failed, can't load dns message python library: 'libdns_python'")
|
|
|
|
|
|
# check max_transfer_in, else return quota error
|
|
|
if self.recorder.count() >= self._max_transfers_in:
|