|
@@ -31,7 +31,7 @@ import socket
|
|
|
from optparse import OptionParser, OptionValueError
|
|
|
try:
|
|
|
from bind10_xfr import *
|
|
|
- from bind10_dns import *
|
|
|
+ from libdns_python import *
|
|
|
except ImportError as e:
|
|
|
# C++ loadable module may not be installed; even so the xfrout process
|
|
|
# must keep running, so we warn about it and move forward.
|
|
@@ -39,12 +39,13 @@ except ImportError as e:
|
|
|
|
|
|
if "B10_FROM_SOURCE" in os.environ:
|
|
|
SPECFILE_PATH = os.environ["B10_FROM_SOURCE"] + "/src/bin/xfrout"
|
|
|
+ UNIX_SOCKET_FILE = os.environ["B10_FROM_SOURCE"] + "/auth_xfrout_conn"
|
|
|
else:
|
|
|
PREFIX = "@prefix@"
|
|
|
DATAROOTDIR = "@datarootdir@"
|
|
|
SPECFILE_PATH = "@datadir@/@PACKAGE@".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
|
|
|
+ UNIX_SOCKET_FILE = "@localstatedir@".replace("${prefix}", PREFIX) + "/auth_xfrout_conn"
|
|
|
SPECFILE_LOCATION = SPECFILE_PATH + "/xfrout.spec"
|
|
|
-UNIX_SOCKET_FILE = "@localstatedir@".replace("${prefix}", PREFIX) + "/auth_xfrout_conn"
|
|
|
|
|
|
MAX_TRANSFERS_OUT = 10
|
|
|
verbose_mode = False
|
|
@@ -52,10 +53,10 @@ verbose_mode = False
|
|
|
|
|
|
class XfroutException(Exception): pass
|
|
|
|
|
|
-
|
|
|
class XfroutSession(BaseRequestHandler):
|
|
|
def handle(self):
|
|
|
fd = recv_fd(self.request.fileno())
|
|
|
+
|
|
|
if fd < 0:
|
|
|
raise XfroutException("failed to receive the FD for XFR connection")
|
|
|
data_len = self.request.recv(2)
|
|
@@ -68,24 +69,26 @@ class XfroutSession(BaseRequestHandler):
|
|
|
if verbose_mode:
|
|
|
self.log_msg(str(e))
|
|
|
|
|
|
+ sock.shutdown(socket.SHUT_RDWR)
|
|
|
sock.close()
|
|
|
+ os.close(fd)
|
|
|
+ pass
|
|
|
|
|
|
def _parse_query_message(self, mdata):
|
|
|
''' parse query message to [socket,message]'''
|
|
|
#TODO, need to add parseHeader() in case the message header is invalid
|
|
|
try:
|
|
|
- msg = message(message_mode.PARSE)
|
|
|
- msg.from_wire(input_buffer(mdata))
|
|
|
+ msg = Message(PARSE)
|
|
|
+ msg.from_wire(mdata)
|
|
|
except Exception as err:
|
|
|
if verbose_mode:
|
|
|
self.log_msg(str(err))
|
|
|
- return rcode.FORMERR(), None
|
|
|
+ return Rcode.FORMERR(), None
|
|
|
|
|
|
- return rcode.NOERROR(), msg
|
|
|
+ return Rcode.NOERROR(), msg
|
|
|
|
|
|
def _get_query_zone_name(self, msg):
|
|
|
- q_iter = question_iter(msg)
|
|
|
- question = q_iter.get_question()
|
|
|
+ question = msg.get_question()[0]
|
|
|
return question.get_name().to_text()
|
|
|
|
|
|
|
|
@@ -98,12 +101,14 @@ class XfroutSession(BaseRequestHandler):
|
|
|
|
|
|
|
|
|
def _send_message(self, sock, msg):
|
|
|
- obuf = output_buffer(0)
|
|
|
- render = message_render(obuf)
|
|
|
+ #obuf = output_buffer(0)
|
|
|
+ #render = message_render(obuf)
|
|
|
+ render = MessageRenderer()
|
|
|
+ render.set_length_limit(65535)
|
|
|
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(sock, header_len)
|
|
|
- self._send_data(sock, obuf.get_data())
|
|
|
+ self._send_data(sock, render.get_data())
|
|
|
|
|
|
|
|
|
def _reply_query_with_error_rcode(self, msg, sock, rcode_):
|
|
@@ -118,7 +123,7 @@ class XfroutSession(BaseRequestHandler):
|
|
|
return # query message is invalid. send nothing back.
|
|
|
|
|
|
msg.make_response()
|
|
|
- msg.set_rcode(rcode.FORMERR())
|
|
|
+ msg.set_rcode(Rcode.FORMERR())
|
|
|
self._send_message(sock, msg)
|
|
|
|
|
|
|
|
@@ -143,27 +148,27 @@ class XfroutSession(BaseRequestHandler):
|
|
|
eg. check allow_transfer setting,
|
|
|
'''
|
|
|
if not self._zone_exist(zone_name):
|
|
|
- return rcode.NOTAUTH()
|
|
|
+ return Rcode.NOTAUTH()
|
|
|
|
|
|
if self._zone_is_empty(zone_name):
|
|
|
- return rcode.SERVFAIL()
|
|
|
+ return Rcode.SERVFAIL()
|
|
|
|
|
|
#TODO, check allow_transfer
|
|
|
if not self.server.increase_transfers_counter():
|
|
|
- return rcode.REFUSED()
|
|
|
+ return Rcode.REFUSED()
|
|
|
|
|
|
- return rcode.NOERROR()
|
|
|
+ return Rcode.NOERROR()
|
|
|
|
|
|
|
|
|
def dns_xfrout_start(self, sock, msg_query):
|
|
|
rcode_, msg = self._parse_query_message(msg_query)
|
|
|
#TODO. create query message and parse header
|
|
|
- if rcode_ != rcode.NOERROR():
|
|
|
+ if rcode_ != Rcode.NOERROR():
|
|
|
return self._reply_query_with_format_error(msg, sock)
|
|
|
|
|
|
zone_name = self._get_query_zone_name(msg)
|
|
|
rcode_ = self._check_xfrout_available(zone_name)
|
|
|
- if rcode_ != rcode.NOERROR():
|
|
|
+ if rcode_ != Rcode.NOERROR():
|
|
|
return self. _reply_query_with_error_rcode(msg, sock, rcode_)
|
|
|
|
|
|
try:
|
|
@@ -187,21 +192,21 @@ class XfroutSession(BaseRequestHandler):
|
|
|
opcode = msg.get_opcode()
|
|
|
rcode = msg.get_rcode()
|
|
|
|
|
|
- msg.clear(message_mode.RENDER)
|
|
|
+ msg.clear(RENDER)
|
|
|
msg.set_qid(qid)
|
|
|
msg.set_opcode(opcode)
|
|
|
msg.set_rcode(rcode)
|
|
|
- msg.set_header_flag(message_flag.AA())
|
|
|
- msg.set_header_flag(message_flag.QR())
|
|
|
+ msg.set_header_flag(MessageFlag.AA())
|
|
|
+ msg.set_header_flag(MessageFlag.QR())
|
|
|
return msg
|
|
|
|
|
|
def _create_rrset_from_db_record(self, record):
|
|
|
'''Create one rrset from one record of datasource, if the schema of record is changed,
|
|
|
This function should be updated first.
|
|
|
'''
|
|
|
- rrtype_ = rr_type(record[5])
|
|
|
- rdata_ = create_rdata(rrtype_, rr_class.IN(), " ".join(record[7:]))
|
|
|
- rrset_ = rrset(name(record[2]), rr_class.IN(), rrtype_, rr_ttl( int(record[4])))
|
|
|
+ rrtype_ = RRType(record[5])
|
|
|
+ rdata_ = Rdata(rrtype_, RRClass("IN"), " ".join(record[7:]))
|
|
|
+ rrset_ = RRset(Name(record[2]), RRClass("IN"), rrtype_, RRTTL( int(record[4])))
|
|
|
rrset_.add_rdata(rdata_)
|
|
|
return rrset_
|
|
|
|
|
@@ -210,20 +215,19 @@ class XfroutSession(BaseRequestHandler):
|
|
|
added, a new message should be created to send out the last soa .
|
|
|
'''
|
|
|
|
|
|
- obuf = output_buffer(0)
|
|
|
- render = message_render(obuf)
|
|
|
+ render = MessageRenderer()
|
|
|
msg.to_wire(render)
|
|
|
- old_message_len = obuf.get_length()
|
|
|
- msg.add_rrset(section.ANSWER(), rrset_soa)
|
|
|
+ old_message_len = render.get_length()
|
|
|
+ msg.add_rrset(Section.ANSWER(), rrset_soa)
|
|
|
|
|
|
msg.to_wire(render)
|
|
|
- message_len = obuf.get_length()
|
|
|
+ message_len = render.get_length()
|
|
|
|
|
|
if message_len != old_message_len:
|
|
|
self._send_message(sock, msg)
|
|
|
else:
|
|
|
msg = self._clear_message(msg)
|
|
|
- msg.add_rrset(section.ANSWER(), rrset_soa)
|
|
|
+ msg.add_rrset(Section.ANSWER(), rrset_soa)
|
|
|
self._send_message(sock, msg)
|
|
|
|
|
|
def _get_message_len(self, msg):
|
|
@@ -231,19 +235,18 @@ class XfroutSession(BaseRequestHandler):
|
|
|
a better way, I need check with jinmei later.
|
|
|
'''
|
|
|
|
|
|
- obuf = output_buffer(0)
|
|
|
- render = message_render(obuf)
|
|
|
+ render = MessageRenderer()
|
|
|
msg.to_wire(render)
|
|
|
- return obuf.get_length()
|
|
|
+ return render.get_length()
|
|
|
|
|
|
|
|
|
def _reply_xfrout_query(self, msg, sock, zone_name):
|
|
|
#TODO, there should be a better way to insert rrset.
|
|
|
msg.make_response()
|
|
|
- msg.set_header_flag(message_flag.AA())
|
|
|
+ msg.set_header_flag(MessageFlag.AA())
|
|
|
soa_record = sqlite3_ds.get_zone_soa(zone_name, self.server.get_db_file())
|
|
|
rrset_soa = self._create_rrset_from_db_record(soa_record)
|
|
|
- msg.add_rrset(section.ANSWER(), rrset_soa)
|
|
|
+ msg.add_rrset(Section.ANSWER(), rrset_soa)
|
|
|
|
|
|
old_message_len = 0
|
|
|
# TODO, Since add_rrset() return nothing when rrset can't be added, so I have to compare
|
|
@@ -252,11 +255,12 @@ class XfroutSession(BaseRequestHandler):
|
|
|
if self.server._shutdown_event.is_set(): # Check if xfrout is shutdown
|
|
|
raise XfroutException("shutdown!")
|
|
|
|
|
|
- if rr_type(rr_data[5]) == rr_type.SOA(): #ignore soa record
|
|
|
+ # TODO: RRType.SOA() ?
|
|
|
+ if RRType(rr_data[5]) == RRType("SOA"): #ignore soa record
|
|
|
continue
|
|
|
|
|
|
rrset_ = self._create_rrset_from_db_record(rr_data)
|
|
|
- msg.add_rrset(section.ANSWER(), rrset_)
|
|
|
+ msg.add_rrset(Section.ANSWER(), rrset_)
|
|
|
message_len = self._get_message_len(msg)
|
|
|
if message_len != old_message_len:
|
|
|
old_message_len = message_len
|
|
@@ -264,7 +268,7 @@ class XfroutSession(BaseRequestHandler):
|
|
|
|
|
|
self._send_message(sock, msg)
|
|
|
msg = self._clear_message(msg)
|
|
|
- msg.add_rrset(section.ANSWER(), rrset_) # Add the rrset to the new message
|
|
|
+ msg.add_rrset(Section.ANSWER(), rrset_) # Add the rrset to the new message
|
|
|
old_message_len = 0
|
|
|
|
|
|
self._send_message_with_last_soa(msg, sock, rrset_soa)
|