[svn] commit: r2628 - in /branches/trac289/src/bin/xfrin: xfrin.py.in xfrin.spec.pre.in
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Aug 4 10:49:38 UTC 2010
Author: zhanglikun
Date: Wed Aug 4 10:49:38 2010
New Revision: 2628
Log:
Refactor the code of xfrin and add config item 'masters' to xfrin, make sure when xfrin get the notify command from zone manager, the zone transfer will be triggered.
Modified:
branches/trac289/src/bin/xfrin/xfrin.py.in
branches/trac289/src/bin/xfrin/xfrin.spec.pre.in
Modified: branches/trac289/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac289/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac289/src/bin/xfrin/xfrin.py.in Wed Aug 4 10:49:38 2010
@@ -362,18 +362,19 @@
class Xfrin:
def __init__(self, verbose = False):
+ self._max_transfers_in = 10
+ #TODO, this is the temp way to set the zone's master.
+ self._masters = {}
self._cc_setup()
- self._max_transfers_in = 10
self.recorder = XfrinRecorder()
self._shutdown_event = threading.Event()
self._verbose = verbose
def _cc_setup(self):
- '''
-This method is used only as part of initialization, but is implemented
-separately for convenience of unit tests; by letting the test code override
-this method we can test most of this class without requiring a command channel.
-'''
+ '''This method is used only as part of initialization, but is
+ implemented separately for convenience of unit tests; by letting
+ the test code override this method we can test most of this class
+ without requiring a command channel.'''
# Create one session for sending command to other modules, because the
# listening session will block the send operation.
self._send_cc_session = isc.cc.Session()
@@ -381,16 +382,32 @@
self.config_handler,
self.command_handler)
self._module_cc.start()
+ config_data = self._module_cc.get_full_config()
+ self._max_transfers_in = config_data.get("transfers_in")
+ self._masters = config_data.get('masters')
def _cc_check_command(self):
- '''
-This is a straightforward wrapper for cc.check_command, but provided as
-a separate method for the convenience of unit tests.
-'''
+ '''This is a straightforward wrapper for cc.check_command,
+ but provided as a separate method for the convenience
+ of unit tests.'''
self._module_cc.check_command()
def config_handler(self, new_config):
- # TODO, process new config data
+ self._max_transfers_in = new_config.get("transfers_in") or self._max_transfers_in
+ new_master = new_config.get('masters')
+ if new_master:
+ # Check if the new master is valid, there should be library for check it.
+ # and user should change the port and address together.
+ try:
+ new_master['address'] = new_master.get('address') or self._masters.get('address')
+ new_master['port'] = new_master.get('port') or self._masters.get('port')
+ check_addr_port(new_master.get('address'), new_master.get('port'))
+ self._masters = new_master
+ except:
+ errmsg = "bad format for zone's master: " + str(new_master)
+ log_error(errmsg)
+ return create_answer(1, errmsg)
+
return create_answer(0)
def shutdown(self):
@@ -404,66 +421,31 @@
continue
th.join()
-
def command_handler(self, command, args):
answer = create_answer(0)
try:
if command == 'shutdown':
self._shutdown_event.set()
- elif command == 'retransfer' or command == 'refresh':
- (zone_name, rrclass,
- master_addr, db_file) = self._parse_cmd_params(args)
- ret = self.xfrin_start(zone_name, rrclass, db_file,
- master_addr,
- False if command == 'retransfer' else True)
- answer = create_answer(ret[0], ret[1])
- elif command == 'notify':
- # This is the temporary implementation for notify.
- # actually the notfiy command should be sent to the
- # Zone Manager module. Being temporary, we separate this case
- # from refresh/retransfer while we could (and should otherwise)
- # share the code.
- (zone_name, rrclass,
- master_addr, db_file) = self._parse_cmd_params(args)
-
- # XXX: master_addr is the sender of the notify message.
- # It's very dangerous to naively trust it as the source of
- # subsequent zone transfer; any remote node can easily exploit
- # it to mount zone poisoning or DoS attacks. We should
- # locally identify the appropriate set of master servers.
- # For now, we disable the code below.
- master_is_valid = False
-
- if master_is_valid:
- ret = self.xfrin_start(zone_name, rrclass, db_file,
- master_addr, True)
- else:
- errmsg = 'Failed to validate the master address ('
- errmsg += args['master'] + '), ignoring notify'
- ret = [1, errmsg]
+ elif command == 'notify' or \
+ command == 'retransfer' or \
+ command == 'refresh':
+ # Xfrin maybe receives the refresh/notify command from zone manager, or
+ # the retransfer/refresh from cmdctl(sent by bindctl).
+ # If the command has specified master address, do transfer from the
+ # master address, or else do transfer from the configured masters.
+ # notify command maybe has the parameters which
+ # specify the notifyfrom address and port, according the RFC1996, zone
+ # transfer should starts first from the notifyfrom, but now, let 'TODO' it.
+ (zone_name, rrclass, master_addr, db_file) = self._parse_cmd_params(args)
+ ret = self.xfrin_start(zone_name, rrclass,
+ db_file, master_addr,
+ (False if command == 'retransfer' else True))
answer = create_answer(ret[0], ret[1])
else:
answer = create_answer(1, 'unknown command: ' + command)
-
except XfrinException as err:
answer = create_answer(1, str(err))
-
return answer
-
- def publish_xfrin_news(self, zone_name, xfr_result):
- '''Send command to xfrout/zone manager module.
- If xfrin has finished successfully for one zone, tell the good
- news(command: zone_new_data_ready) to zone manager and xfrout.
- if xfrin failed, just tell the bad news to zone manager, so that
- it can reset the refresh timer for that zone. '''
- param = {'zone_name': zone_name}
- if xfr_result == XFRIN_OK:
- msg = create_command(notify_out.ZONE_NEW_DATA_READY_CMD, param)
- self._send_cc_session.group_sendmsg(msg, XFROUT_MODULE_NAME)
- self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
- else:
- msg = create_command(ZONE_XFRIN_FAILED, param)
- self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
def _parse_cmd_params(self, args):
zone_name = args.get('zone_name')
@@ -472,9 +454,6 @@
rrclass = args.get('zone_class')
if not rrclass:
- # The default RR class is IN. We should fix this so that
- # the class is always passed in the command arg (where we specify
- # the default)
rrclass = RRClass.IN()
else:
try:
@@ -482,15 +461,19 @@
except InvalidRRClass as e:
raise XfrinException('invalid RRClass: ' + rrclass)
- master = args.get('master')
- if not master:
- raise XfrinException('master address should be provided')
-
port_str = args.get('port')
if not port_str:
port_str = DEFAULT_MASTER_PORT
+
+ master = args.get('master')
+ if not master:
+ if len(self._masters) > 0:
+ master = self._masters.get('address')
+ port_str = self._masters.get('port')
+ else:
+ raise XfrinException("zone's master should be provided")
+
master_addrinfo = check_addr_port(master, port_str)
-
db_file = args.get('db_file')
if not db_file:
#TODO, the db file path should be got in auth server's configuration
@@ -509,6 +492,21 @@
return (zone_name, rrclass, master_addrinfo, db_file)
+ def publish_xfrin_news(self, zone_name, xfr_result):
+ '''Send command to xfrout/zone manager module.
+ If xfrin has finished successfully for one zone, tell the good
+ news(command: zone_new_data_ready) to zone manager and xfrout.
+ if xfrin failed, just tell the bad news to zone manager, so that
+ it can reset the refresh timer for that zone. '''
+ param = {'zone_name': zone_name}
+ if xfr_result == XFRIN_OK:
+ msg = create_command(notify_out.ZONE_NEW_DATA_READY_CMD, param)
+ self._send_cc_session.group_sendmsg(msg, XFROUT_MODULE_NAME)
+ self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
+ else:
+ msg = create_command(ZONE_XFRIN_FAILED, param)
+ self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
+
def startup(self):
while not self._shutdown_event.is_set():
self._cc_check_command()
Modified: branches/trac289/src/bin/xfrin/xfrin.spec.pre.in
==============================================================================
--- branches/trac289/src/bin/xfrin/xfrin.spec.pre.in (original)
+++ branches/trac289/src/bin/xfrin/xfrin.spec.pre.in Wed Aug 4 10:49:38 2010
@@ -8,7 +8,25 @@
"item_type": "integer",
"item_optional": false,
"item_default": 10
- }
+ },
+ {
+ "item_name": "masters",
+ "item_type": "map",
+ "item_optional": true,
+ "item_default": {},
+ "map_item_spec": [
+ { "item_name": "address",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": ""
+ },
+ { "item_name": "port",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 53
+ }
+ ]
+ }
],
"commands": [
{
@@ -29,7 +47,7 @@
{
"item_name": "master",
"item_type": "string",
- "item_optional": false,
+ "item_optional": true,
"item_default": ""
},
{
More information about the bind10-changes
mailing list