|
@@ -26,6 +26,7 @@ from isc.datasrc import sqlite3_ds
|
|
from socketserver import *
|
|
from socketserver import *
|
|
import os
|
|
import os
|
|
from isc.config.ccsession import *
|
|
from isc.config.ccsession import *
|
|
|
|
+from isc.log.log import *
|
|
from isc.cc import SessionError
|
|
from isc.cc import SessionError
|
|
import socket
|
|
import socket
|
|
import select
|
|
import select
|
|
@@ -53,21 +54,20 @@ else:
|
|
SPECFILE_LOCATION = SPECFILE_PATH + "/xfrout.spec"
|
|
SPECFILE_LOCATION = SPECFILE_PATH + "/xfrout.spec"
|
|
AUTH_SPECFILE_LOCATION = AUTH_SPECFILE_PATH + os.sep + "auth.spec"
|
|
AUTH_SPECFILE_LOCATION = AUTH_SPECFILE_PATH + os.sep + "auth.spec"
|
|
MAX_TRANSFERS_OUT = 10
|
|
MAX_TRANSFERS_OUT = 10
|
|
-verbose_mode = False
|
|
+VERBOSE_MODE = False
|
|
-
|
|
|
|
-
|
|
|
|
-class XfroutException(Exception): pass
|
|
|
|
-
|
|
|
|
|
|
|
|
class XfroutSession(BaseRequestHandler):
|
|
class XfroutSession(BaseRequestHandler):
|
|
|
|
+ def __init__(self, request, client_address, server, log):
|
|
|
|
+ BaseRequestHandler.__init__(self, request, client_address, server)
|
|
|
|
+ self._log = log
|
|
|
|
+
|
|
def handle(self):
|
|
def handle(self):
|
|
fd = recv_fd(self.request.fileno())
|
|
fd = recv_fd(self.request.fileno())
|
|
if fd < 0:
|
|
if fd < 0:
|
|
# This may happen when one xfrout process try to connect to
|
|
# This may happen when one xfrout process try to connect to
|
|
# xfrout unix socket server, to check whether there is another
|
|
# xfrout unix socket server, to check whether there is another
|
|
# xfrout running.
|
|
# xfrout running.
|
|
- print("[b10-xfrout] Failed to receive the FD for XFR connection, "
|
|
+ self._log.log_message("error", "Failed to receive the file descriptor for XFR connection")
|
|
- "maybe because another xfrout process was started.")
|
|
|
|
return
|
|
return
|
|
|
|
|
|
data_len = self.request.recv(2)
|
|
data_len = self.request.recv(2)
|
|
@@ -77,8 +77,7 @@ class XfroutSession(BaseRequestHandler):
|
|
try:
|
|
try:
|
|
self.dns_xfrout_start(sock, msgdata)
|
|
self.dns_xfrout_start(sock, msgdata)
|
|
except Exception as e:
|
|
except Exception as e:
|
|
- if verbose_mode:
|
|
+ self._log.log_message("error", str(e))
|
|
- self.log_msg(str(e))
|
|
|
|
|
|
|
|
sock.close()
|
|
sock.close()
|
|
|
|
|
|
@@ -89,8 +88,7 @@ class XfroutSession(BaseRequestHandler):
|
|
msg = message(message_mode.PARSE)
|
|
msg = message(message_mode.PARSE)
|
|
msg.from_wire(input_buffer(mdata))
|
|
msg.from_wire(input_buffer(mdata))
|
|
except Exception as err:
|
|
except Exception as err:
|
|
- if verbose_mode:
|
|
+ self._log.log_message("error", str(err))
|
|
- self.log_msg(str(err))
|
|
|
|
return rcode.FORMERR(), None
|
|
return rcode.FORMERR(), None
|
|
|
|
|
|
return rcode.NOERROR(), msg
|
|
return rcode.NOERROR(), msg
|
|
@@ -179,16 +177,11 @@ class XfroutSession(BaseRequestHandler):
|
|
return self. _reply_query_with_error_rcode(msg, sock, rcode_)
|
|
return self. _reply_query_with_error_rcode(msg, sock, rcode_)
|
|
|
|
|
|
try:
|
|
try:
|
|
- if verbose_mode:
|
|
+ self._log.log_message("info", "transfer of '%s/IN': AXFR started" % zone_name)
|
|
- self.log_msg("transfer of '%s/IN': AXFR started" % zone_name)
|
|
|
|
-
|
|
|
|
self._reply_xfrout_query(msg, sock, zone_name)
|
|
self._reply_xfrout_query(msg, sock, zone_name)
|
|
-
|
|
+ self._log.log_message("info", "transfer of '%s/IN': AXFR end" % zone_name)
|
|
- if verbose_mode:
|
|
|
|
- self.log_msg("transfer of '%s/IN': AXFR end" % zone_name)
|
|
|
|
except Exception as err:
|
|
except Exception as err:
|
|
- if verbose_mode:
|
|
+ self._log.log_message("error", str(err))
|
|
- sys.stderr.write("[b10-xfrout] %s\n" % str(err))
|
|
|
|
|
|
|
|
self.server.decrease_transfers_counter()
|
|
self.server.decrease_transfers_counter()
|
|
return
|
|
return
|
|
@@ -262,7 +255,7 @@ class XfroutSession(BaseRequestHandler):
|
|
# the message length to know if the rrset has been added sucessfully.
|
|
# the message length to know if the rrset has been added sucessfully.
|
|
for rr_data in sqlite3_ds.get_zone_datas(zone_name, self.server.get_db_file()):
|
|
for rr_data in sqlite3_ds.get_zone_datas(zone_name, self.server.get_db_file()):
|
|
if self.server._shutdown_event.is_set(): # Check if xfrout is shutdown
|
|
if self.server._shutdown_event.is_set(): # Check if xfrout is shutdown
|
|
- raise XfroutException("shutdown!")
|
|
+ self._log.log_message("error", "shutdown!")
|
|
|
|
|
|
if rr_type(rr_data[5]) == rr_type.SOA(): #ignore soa record
|
|
if rr_type(rr_data[5]) == rr_type.SOA(): #ignore soa record
|
|
continue
|
|
continue
|
|
@@ -281,22 +274,23 @@ class XfroutSession(BaseRequestHandler):
|
|
|
|
|
|
self._send_message_with_last_soa(msg, sock, rrset_soa)
|
|
self._send_message_with_last_soa(msg, sock, rrset_soa)
|
|
|
|
|
|
- def log_msg(self, msg):
|
|
|
|
- print('[b10-xfrout] ', msg)
|
|
|
|
-
|
|
|
|
|
|
|
|
class UnixSockServer(ThreadingUnixStreamServer):
|
|
class UnixSockServer(ThreadingUnixStreamServer):
|
|
'''The unix domain socket server which accept xfr query sent from auth server.'''
|
|
'''The unix domain socket server which accept xfr query sent from auth server.'''
|
|
|
|
|
|
- def __init__(self, sock_file, handle_class, shutdown_event, config_data, cc):
|
|
+ def __init__(self, sock_file, handle_class, shutdown_event, config_data, cc, log):
|
|
self._remove_unused_sock_file(sock_file)
|
|
self._remove_unused_sock_file(sock_file)
|
|
self._sock_file = sock_file
|
|
self._sock_file = sock_file
|
|
ThreadingUnixStreamServer.__init__(self, sock_file, handle_class)
|
|
ThreadingUnixStreamServer.__init__(self, sock_file, handle_class)
|
|
self._lock = threading.Lock()
|
|
self._lock = threading.Lock()
|
|
self._transfers_counter = 0
|
|
self._transfers_counter = 0
|
|
self._shutdown_event = shutdown_event
|
|
self._shutdown_event = shutdown_event
|
|
|
|
+ self._log = log
|
|
self.update_config_data(config_data)
|
|
self.update_config_data(config_data)
|
|
self._cc = cc
|
|
self._cc = cc
|
|
|
|
+ def finish_request(self, request, client_address):
|
|
|
|
+ '''Finish one request by instantiating RequestHandlerClass.'''
|
|
|
|
+ self.RequestHandlerClass(request, client_address, self, self._log)
|
|
|
|
|
|
def _remove_unused_sock_file(self, sock_file):
|
|
def _remove_unused_sock_file(self, sock_file):
|
|
'''Try to remove the socket file. If the file is being used
|
|
'''Try to remove the socket file. If the file is being used
|
|
@@ -333,14 +327,17 @@ class UnixSockServer(ThreadingUnixStreamServer):
|
|
ThreadingUnixStreamServer.shutdown(self)
|
|
ThreadingUnixStreamServer.shutdown(self)
|
|
try:
|
|
try:
|
|
os.unlink(self._sock_file)
|
|
os.unlink(self._sock_file)
|
|
- except:
|
|
+ except Exception as e:
|
|
- pass
|
|
+ self._log.log_message("error", str(e))
|
|
|
|
|
|
def update_config_data(self, new_config):
|
|
def update_config_data(self, new_config):
|
|
'''Apply the new config setting of xfrout module. '''
|
|
'''Apply the new config setting of xfrout module. '''
|
|
|
|
+ self._log.log_message('info', 'update config data start.')
|
|
self._lock.acquire()
|
|
self._lock.acquire()
|
|
self._max_transfers_out = new_config.get('transfers_out')
|
|
self._max_transfers_out = new_config.get('transfers_out')
|
|
|
|
+ self._log.log_message('info', 'max transfer out : %d', self._max_transfers_out)
|
|
self._lock.release()
|
|
self._lock.release()
|
|
|
|
+ self._log.log_message('info', 'update config data complete.')
|
|
|
|
|
|
def get_db_file(self):
|
|
def get_db_file(self):
|
|
file, is_default = self._cc.get_remote_config_value("Auth", "database_file")
|
|
file, is_default = self._cc.get_remote_config_value("Auth", "database_file")
|
|
@@ -391,19 +388,24 @@ def listen_on_xfr_query(unix_socket_server):
|
|
class XfroutServer:
|
|
class XfroutServer:
|
|
def __init__(self):
|
|
def __init__(self):
|
|
self._unix_socket_server = None
|
|
self._unix_socket_server = None
|
|
|
|
+ self._log = None
|
|
self._listen_sock_file = UNIX_SOCKET_FILE
|
|
self._listen_sock_file = UNIX_SOCKET_FILE
|
|
self._shutdown_event = threading.Event()
|
|
self._shutdown_event = threading.Event()
|
|
self._cc = isc.config.ModuleCCSession(SPECFILE_LOCATION, self.config_handler, self.command_handler)
|
|
self._cc = isc.config.ModuleCCSession(SPECFILE_LOCATION, self.config_handler, self.command_handler)
|
|
self._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
|
|
self._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
|
|
self._config_data = self._cc.get_full_config()
|
|
self._config_data = self._cc.get_full_config()
|
|
self._cc.start()
|
|
self._cc.start()
|
|
|
|
+ self._log = isc.log.NSLogger(self._config_data.get('log_name'), self._config_data.get('log_file'),
|
|
|
|
+ self._config_data.get('log_severity'), self._config_data.get('log_versions'),
|
|
|
|
+ self._config_data.get('log_max_bytes'), True)
|
|
self._start_xfr_query_listener()
|
|
self._start_xfr_query_listener()
|
|
|
|
|
|
def _start_xfr_query_listener(self):
|
|
def _start_xfr_query_listener(self):
|
|
'''Start a new thread to accept xfr query. '''
|
|
'''Start a new thread to accept xfr query. '''
|
|
|
|
|
|
self._unix_socket_server = UnixSockServer(self._listen_sock_file, XfroutSession,
|
|
self._unix_socket_server = UnixSockServer(self._listen_sock_file, XfroutSession,
|
|
- self._shutdown_event, self._config_data, self._cc);
|
|
+ self._shutdown_event, self._config_data,
|
|
|
|
+ self._cc, self._log);
|
|
listener = threading.Thread(target = listen_on_xfr_query, args = (self._unix_socket_server,))
|
|
listener = threading.Thread(target = listen_on_xfr_query, args = (self._unix_socket_server,))
|
|
listener.start()
|
|
listener.start()
|
|
|
|
|
|
@@ -417,6 +419,9 @@ class XfroutServer:
|
|
continue
|
|
continue
|
|
self._config_data[key] = new_config[key]
|
|
self._config_data[key] = new_config[key]
|
|
|
|
|
|
|
|
+ if self._log:
|
|
|
|
+ self._log.update_config(new_config)
|
|
|
|
+
|
|
if self._unix_socket_server:
|
|
if self._unix_socket_server:
|
|
self._unix_socket_server.update_config_data(self._config_data)
|
|
self._unix_socket_server.update_config_data(self._config_data)
|
|
|
|
|
|
@@ -442,8 +447,7 @@ class XfroutServer:
|
|
|
|
|
|
def command_handler(self, cmd, args):
|
|
def command_handler(self, cmd, args):
|
|
if cmd == "shutdown":
|
|
if cmd == "shutdown":
|
|
- if verbose_mode:
|
|
+ self._log.log_message("info", "Received shutdown command.")
|
|
- print("[b10-xfrout] Received shutdown command")
|
|
|
|
self.shutdown()
|
|
self.shutdown()
|
|
answer = create_answer(0)
|
|
answer = create_answer(0)
|
|
else:
|
|
else:
|
|
@@ -478,18 +482,18 @@ if '__main__' == __name__:
|
|
parser = OptionParser()
|
|
parser = OptionParser()
|
|
set_cmd_options(parser)
|
|
set_cmd_options(parser)
|
|
(options, args) = parser.parse_args()
|
|
(options, args) = parser.parse_args()
|
|
- verbose_mode = options.verbose
|
|
+ VERBOSE_MODE = options.verbose
|
|
|
|
|
|
set_signal_handler()
|
|
set_signal_handler()
|
|
xfrout_server = XfroutServer()
|
|
xfrout_server = XfroutServer()
|
|
xfrout_server.run()
|
|
xfrout_server.run()
|
|
except KeyboardInterrupt:
|
|
except KeyboardInterrupt:
|
|
- print("[b10-xfrout] exit xfrout process")
|
|
+ sys.stderr.write("[b10-xfrout] exit xfrout process")
|
|
except SessionError as e:
|
|
except SessionError as e:
|
|
- print('[b10-xfrout] Error creating xfrout, '
|
|
+ sys.stderr.write("[b10-xfrout] Error creating xfrout,"
|
|
- 'is the command channel daemon running?' )
|
|
+ "is the command channel daemon running?")
|
|
except ModuleCCSessionError as e:
|
|
except ModuleCCSessionError as e:
|
|
- print('[b10-xfrout] exit xfrout process:', e)
|
|
+ sys.stderr.write("info", '[b10-xfrout] exit xfrout process:', e)
|
|
|
|
|
|
if xfrout_server:
|
|
if xfrout_server:
|
|
xfrout_server.shutdown()
|
|
xfrout_server.shutdown()
|