Commit f7cec864 authored by Jelte Jansen's avatar Jelte Jansen

added manual python wrappers location to PYTHONPATH

made xfrout use the dns python wrappers instead of the boost.python one
(still needs boost.python for the wrappers for sending sockets around)

also fixed a few other problems in xfrout;
- UNIX_SOCKET_FILE (the socket that is used to send other socket descriptors over) only worked if installed, updated to use @abs_top_srcdir@/auth_sock_conn for the domain socket file (for now, where should we really put this?) Also updated bin/auth/main.cc to use this one if run from source tree
- That file descriptor that is passed wasn't closed, so after a while the system would run out of file descriptors. Added os.close(fd) for that to xfrout. We might want to think about adding this to our send_fd/recv_fd lib
- Other (temporary) workaround; When the AXFR response is rendered, it triggers truncation. So for now I used renderer.setLengthLimit(65535). But we might want to simply make multiple message packets within the stream.

(all three of these problems also occur in trunk/ btw, but since all of them might be temporary and i'm focusing on the main wrappers here, i committed them here for now)


git-svn-id: svn://bind10.isc.org/svn/bind10/experiments/python-binding@1828 e5f2f494-b856-4b98-b285-d166d9295462
parent 0845a483
......@@ -130,7 +130,16 @@ check_axfr_query(char *msg_data, uint16_t msg_len)
static void
dispatch_axfr_query(int tcp_sock, char axfr_query[], uint16_t query_len)
{
std::string path = string(UNIX_SOCKET_FILE);
std::string path;
if (getenv("B10_FROM_SOURCE")) {
path = string(getenv("B10_FROM_SOURCE")) +
"/auth_xfrout_conn";
} else {
path = string(UNIX_SOCKET_FILE);
}
(void)tcp_sock;
(void)axfr_query;
(void)query_len;
XfroutClient xfr_client(path);
try {
xfr_client.connect();
......
......@@ -23,7 +23,7 @@ BIND10_PATH=@abs_top_builddir@/src/bin/bind10
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/xfrin:@abs_top_builddir@/src/bin/xfrout:$PATH
export PATH
PYTHONPATH=@abs_top_builddir@/src/lib/python
PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs
export PYTHONPATH
B10_FROM_SOURCE=@abs_top_srcdir@
......
......@@ -19,7 +19,7 @@ PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
export PYTHON_EXEC
MYPATH_PATH=@abs_top_builddir@/src/bin/xfrout
PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/xfr/.libs
PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/xfr/.libs:@abs_top_builddir@/src/lib/dns/python/.libs
export PYTHONPATH
cd ${MYPATH_PATH}
......
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment