From: JINMEI Tatuya Date: Fri, 26 Apr 2013 23:26:32 +0000 (-0700) Subject: [2911] add request_ixfr zone option to finer policy control on use of IXFR. X-Git-Tag: bind10-1.2.0beta1-release~418^2~9^2~1^2~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e532e4f5648f23bec3bc01d01bec47abd966e07f;p=thirdparty%2Fkea.git [2911] add request_ixfr zone option to finer policy control on use of IXFR. currently just recognize the option. no behavior change due to it yet. --- diff --git a/src/bin/xfrin/tests/xfrin_test.py b/src/bin/xfrin/tests/xfrin_test.py index 09ac80d141..d38371e9f8 100644 --- a/src/bin/xfrin/tests/xfrin_test.py +++ b/src/bin/xfrin/tests/xfrin_test.py @@ -2748,6 +2748,19 @@ class TestXfrin(unittest.TestCase): else: # if not set, should default to False self.assertFalse(zone_info.use_ixfr) + if ('request_ixfr' in zone_config and + zone_config.get('request_ixfr')): + cfg_val = zone_config.get('request_ixfr') + val = zone_info.request_ixfr + if cfg_val == 'yes': + self.assertEqual(ZoneInfo.REQUEST_IXFR_FIRST, val) + elif cfg_val == 'no': + self.assertEqual(ZoneInfo.REQUEST_IXFR_DISABLED, val) + elif cfg_val == 'only': + self.assertEqual(ZoneInfo.REQUEST_IXFR_ONLY, val) + else: # check the default + self.assertEqual(ZoneInfo.REQUEST_IXFR_FIRST, + zone_info.request_ixfr) def test_config_handler_zones(self): # This test passes a number of good and bad configs, and checks whether @@ -2759,7 +2772,7 @@ class TestXfrin(unittest.TestCase): { 'name': 'test.example.', 'master_addr': '192.0.2.1', 'master_port': 53, - 'use_ixfr': False + 'request_ixfr': 'yes' } ]} self.assertEqual(self.xfr.config_handler(config1)['result'][0], 0) @@ -2771,12 +2784,24 @@ class TestXfrin(unittest.TestCase): 'master_addr': '192.0.2.2', 'master_port': 53, 'tsig_key': "example.com:SFuWd/q99SzF8Yzd1QbB9g==", - 'use_ixfr': True + 'request_ixfr': 'no' } ]} self.assertEqual(self.xfr.config_handler(config2)['result'][0], 0) self._check_zones_config(config2) + config3 = {'transfers_in': 4, + 'zones': [ + { 'name': 'test.example.', + 'master_addr': '192.0.2.2', + 'master_port': 53, + 'tsig_key': "example.com:SFuWd/q99SzF8Yzd1QbB9g==", + 'request_ixfr': 'only' + } + ]} + self.assertEqual(self.xfr.config_handler(config3)['result'][0], 0) + self._check_zones_config(config3) + # test that configuring the zone multiple times fails zones = { 'transfers_in': 5, 'zones': [ @@ -2791,7 +2816,7 @@ class TestXfrin(unittest.TestCase): ]} self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) # since this has failed, we should still have the previous config - self._check_zones_config(config2) + self._check_zones_config(config3) zones = { 'zones': [ { 'name': 'test.example.', @@ -2801,7 +2826,7 @@ class TestXfrin(unittest.TestCase): } ]} self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) - self._check_zones_config(config2) + self._check_zones_config(config3) zones = { 'zones': [ { 'master_addr': '192.0.2.4', @@ -2810,7 +2835,7 @@ class TestXfrin(unittest.TestCase): ]} self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) # since this has failed, we should still have the previous config - self._check_zones_config(config2) + self._check_zones_config(config3) zones = { 'zones': [ { 'name': 'bad..zone.', @@ -2820,7 +2845,7 @@ class TestXfrin(unittest.TestCase): ]} self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) # since this has failed, we should still have the previous config - self._check_zones_config(config2) + self._check_zones_config(config3) zones = { 'zones': [ { 'name': '', @@ -2830,7 +2855,7 @@ class TestXfrin(unittest.TestCase): ]} self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) # since this has failed, we should still have the previous config - self._check_zones_config(config2) + self._check_zones_config(config3) zones = { 'zones': [ { 'name': 'test.example', @@ -2840,7 +2865,7 @@ class TestXfrin(unittest.TestCase): ]} self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) # since this has failed, we should still have the previous config - self._check_zones_config(config2) + self._check_zones_config(config3) zones = { 'zones': [ { 'name': 'test.example', @@ -2850,7 +2875,7 @@ class TestXfrin(unittest.TestCase): ]} self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) # since this has failed, we should still have the previous config - self._check_zones_config(config2) + self._check_zones_config(config3) zones = { 'zones': [ { 'name': 'test.example', @@ -2862,7 +2887,7 @@ class TestXfrin(unittest.TestCase): ]} self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) # since this has failed, we should still have the previous config - self._check_zones_config(config2) + self._check_zones_config(config3) # let's also add a zone that is correct too, and make sure # that the new config is not partially taken @@ -2879,7 +2904,18 @@ class TestXfrin(unittest.TestCase): ]} self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) # since this has failed, we should still have the previous config - self._check_zones_config(config2) + self._check_zones_config(config3) + + # invalid request_ixfr value + zones = { 'zones': [ + { 'name': 'test.example', + 'master_addr': '192.0.2.7', + 'request_ixfr': 'bad value' + } + ]} + self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1) + # since this has failed, we should still have the previous config + self._check_zones_config(config3) def test_config_handler_zones_default(self): # Checking it some default config values apply. Using a separate diff --git a/src/bin/xfrin/xfrin.py.in b/src/bin/xfrin/xfrin.py.in index cef72ee366..d4a0f496ba 100755 --- a/src/bin/xfrin/xfrin.py.in +++ b/src/bin/xfrin/xfrin.py.in @@ -1238,6 +1238,11 @@ class XfrinRecorder: return ret class ZoneInfo: + # Internal values corresponding to request_ixfr + REQUEST_IXFR_FIRST = 0 # request_ixfr=yes, use IXFR 1st then AXFR + REQUEST_IXFR_ONLY = 1 # request_ixfr=only, use IXFR only + REQUEST_IXFR_DISABLED = 2 # request_ixfr=no, AXFR-only + def __init__(self, config_data, module_cc): """Creates a zone_info with the config data element as specified by the 'zones' list in xfrin.spec. Module_cc is @@ -1250,6 +1255,17 @@ class ZoneInfo: self.set_zone_class(config_data.get('class')) self.set_tsig_key_name(config_data.get('tsig_key')) self.set_use_ixfr(config_data.get('use_ixfr')) + self.set_request_ixfr(config_data.get('request_ixfr')) + + @property + def request_ixfr(self): + """Policy on the use of IXFR. + + Possible values are REQUEST_IXFR_xxx, internally stored in + __request_ixfr, read-only outside of the class. + + """ + return self.__request_ixfr def set_name(self, name_str): """Set the name for this zone given a name string. @@ -1338,15 +1354,25 @@ class ZoneInfo: def set_use_ixfr(self, use_ixfr): """Set use_ixfr. If set to True, it will use - IXFR for incoming transfers. If set to False, it will use AXFR. - At this moment there is no automatic fallback""" - # TODO: http://bind10.isc.org/ticket/1279 + IXFR for incoming transfers. If set to False, it will use AXFR.""" if use_ixfr is None: self.use_ixfr = \ self._module_cc.get_default_value("zones/use_ixfr") else: self.use_ixfr = use_ixfr + def set_request_ixfr(self, request_ixfr): + if request_ixfr is None: + request_ixfr = 'yes' # if unspecified, use the default + cfg_to_val = { 'yes': self.REQUEST_IXFR_FIRST, + 'only': self.REQUEST_IXFR_ONLY, + 'no': self.REQUEST_IXFR_DISABLED } + try: + self.__request_ixfr = cfg_to_val[request_ixfr] + except KeyError: + raise XfrinZoneInfoException('invalid value for request_ixfr: ' + + request_ixfr) + def get_master_addr_info(self): return (self.master_addr.family, socket.SOCK_STREAM, (str(self.master_addr), self.master_port)) diff --git a/src/bin/xfrin/xfrin.spec b/src/bin/xfrin/xfrin.spec index dc993f7fdc..42dd8745df 100644 --- a/src/bin/xfrin/xfrin.spec +++ b/src/bin/xfrin/xfrin.spec @@ -48,6 +48,11 @@ "item_type": "boolean", "item_optional": false, "item_default": false + }, + { "item_name": "request_ixfr", + "item_type": "string", + "item_optional": false, + "item_default": "yes" } ] }