Commit ada1705c authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[master] Merge branch 'trac1294'

parents aadf8f9a fd39e4e8
......@@ -1271,6 +1271,7 @@ TODO
development release, however, it only tries AXFR by default,
and care should be taken to enable IXFR.
</para>
<!-- TODO: http://bind10.isc.org/ticket/1279 -->
<note><simpara>
In the current development release of BIND 10, incoming zone
......@@ -1278,13 +1279,19 @@ TODO
that is, they don't work for an in-memory data source.
</simpara></note>
<para>
To enable IXFR, you need to
configure <command>b10-xfrin</command> with an explicit zone
configuration for the zone.
For example, to enable IXFR for a zone named "example.com"
(whose master address is assumed to be 2001:db8::53 here),
run the following at the <command>bindctl</command> prompt:
<section>
<title>Configuration for Incoming Zone Transfers</title>
<para>
In practice, you need to specify a list of secondary zones to
enable incoming zone transfers for these zones (you can still
trigger a zone transfer manually, without a prior configuration
(see below)).
</para>
<para>
For example, to enable zone transfers for a zone named "example.com"
(whose master address is assumed to be 2001:db8::53 here),
run the following at the <command>bindctl</command> prompt:
<screen>&gt; <userinput>config add Xfrin/zones</userinput>
&gt; <userinput>config set Xfrin/zones[0]/name "<option>example.com</option>"</userinput>
......@@ -1292,16 +1299,23 @@ TODO
&gt; <userinput>config commit</userinput></screen>
(We assume there has been no zone configuration before).
Note that you do NOT have to explicitly enable IXFR in the zone
configuration; once it's defined, IXFR is enabled by default.
This also means if you specify a zone configuration for some
other reason but don't want to use IXFR for that zone, you need
to disable it explicitly:
</para>
</section>
<screen>&gt; <userinput>config set Xfrin/zones[0]/ixfr_disabled true</userinput></screen>
</para>
<section>
<title>Enabling IXFR</title>
<para>
As noted above, <command>b10-xfrin</command> uses AXFR for
zone transfers by default. To enable IXFR for zone transfers
for a particular zone, set the <userinput>use_ixfr</userinput>
configuration parameter to <userinput>true</userinput>.
In the above example of configuration sequence, you'll need
to add the following before performing <userinput>commit</userinput>:
<screen>&gt; <userinput>config set Xfrin/zones[0]/use_ixfr true</userinput></screen>
</para>
<para>
<!-- TODO: http://bind10.isc.org/ticket/1279 -->
<note><simpara>
One reason why IXFR is disabled by default in the current
release is because it does not support automatic fallback from IXFR to
AXFR when it encounters a primary server that doesn't support
......@@ -1315,7 +1329,8 @@ TODO
make this selection automatically.
These features will be implemented in a near future
version, at which point we will enable IXFR by default.
</para>
</simpara></note>
</section>
<!-- TODO:
......@@ -1328,13 +1343,18 @@ what if a NOTIFY is sent?
-->
<para>
To manually trigger a zone transfer to retrieve a remote zone,
you may use the <command>bindctl</command> utility.
For example, at the <command>bindctl</command> prompt run:
<section>
<title>Trigger an Incoming Zone Transfer Manually</title>
<para>
To manually trigger a zone transfer to retrieve a remote zone,
you may use the <command>bindctl</command> utility.
For example, at the <command>bindctl</command> prompt run:
<screen>&gt; <userinput>Xfrin retransfer zone_name="<option>foo.example.org</option>" master=<option>192.0.2.99</option></userinput></screen>
</para>
</section>
<screen>&gt; <userinput>Xfrin retransfer zone_name="<option>foo.example.org</option>" master=<option>192.0.2.99</option></userinput></screen>
</para>
<!-- TODO: can that retransfer be used to identify a new zone? -->
<!-- TODO: what if doesn't exist at that master IP? -->
......
......@@ -75,6 +75,7 @@ in separate zonemgr process.
and care should be taken to enable IXFR.
See the BIND 10 Guide for more details.
</para>
<!-- TODO: http://bind10.isc.org/ticket/1279 -->
<para>
This daemon communicates with BIND 10 over a
......@@ -110,7 +111,7 @@ in separate zonemgr process.
<varname>class</varname> (defaults to <quote>IN</quote>),
<varname>master_addr</varname> (the zone master to transfer from),
<varname>master_port</varname> (defaults to 53),
<varname>ixfr_disabled</varname> (defaults to false), and
<varname>use_ixfr</varname> (defaults to false), and
<varname>tsig_key</varname> (optional TSIG key to use).
The <varname>tsig_key</varname> is specified using a full string
colon-delimited name:key:algorithm representation (e.g.
......@@ -158,7 +159,7 @@ in separate zonemgr process.
according to the SOA's REFRESH time
to tell <command>b10-xfrin</command> that the zone needs to do
a zone refresh.
This is an internal command and not exposed to the administrator.
This is an internal command and not exposed to the administrator.
<!-- not defined in spec -->
</para>
......@@ -208,7 +209,7 @@ add a usage example of xfrin -->
</para></note>
<!-- TODO:
it can handle more than one XFR in now,
it can handle more than one XFR in now,
but the problem is If SQLITE3 datasource part support multiple write
operation
-->
......
......@@ -98,10 +98,15 @@ class XfrinTestTimeoutException(Exception):
class MockCC():
def get_default_value(self, identifier):
# The returned values should be identical to the spec file
# XXX: these should be retrieved from the spec file
# (see MyCCSession of xfrout_test.py.in)
if identifier == "zones/master_port":
return TEST_MASTER_PORT
if identifier == "zones/class":
return TEST_RRCLASS_STR
if identifier == "zones/use_ixfr":
return False
class MockDataSourceClient():
'''A simple mock data source client.
......@@ -1937,20 +1942,24 @@ class TestXfrin(unittest.TestCase):
self.assertEqual(zone_info.tsig_key.to_text(), TSIGKey(zone_config['tsig_key']).to_text())
else:
self.assertIsNone(zone_info.tsig_key)
if 'ixfr_disabled' in zone_config and\
zone_config.get('ixfr_disabled'):
self.assertTrue(zone_info.ixfr_disabled)
if 'use_ixfr' in zone_config and\
zone_config.get('use_ixfr'):
self.assertTrue(zone_info.use_ixfr)
else:
# if not set, should default to False
self.assertFalse(zone_info.ixfr_disabled)
self.assertFalse(zone_info.use_ixfr)
def test_command_handler_zones(self):
def test_config_handler_zones(self):
# This test passes a number of good and bad configs, and checks whether
# the values are reflected in the structure that will dictate the
# actual behaviour. It also checks if bad values are correctly
# handled
config1 = { 'transfers_in': 3,
'zones': [
{ 'name': 'test.example.',
'master_addr': '192.0.2.1',
'master_port': 53,
'ixfr_disabled': False
'use_ixfr': False
}
]}
self.assertEqual(self.xfr.config_handler(config1)['result'][0], 0)
......@@ -1962,7 +1971,7 @@ class TestXfrin(unittest.TestCase):
'master_addr': '192.0.2.2',
'master_port': 53,
'tsig_key': "example.com:SFuWd/q99SzF8Yzd1QbB9g==",
'ixfr_disabled': True
'use_ixfr': True
}
]}
self.assertEqual(self.xfr.config_handler(config2)['result'][0], 0)
......@@ -2072,37 +2081,49 @@ class TestXfrin(unittest.TestCase):
# since this has failed, we should still have the previous config
self._check_zones_config(config2)
def common_ixfr_setup(self, xfr_mode, ixfr_disabled):
def test_config_handler_zones_default(self):
# Checking it some default config values apply. Using a separate
# test case for a fresh xfr object.
config = { 'zones': [
{ 'name': 'test.example.',
'master_addr': '192.0.2.1',
'master_port': 53,
}
]}
self.assertEqual(self.xfr.config_handler(config)['result'][0], 0)
self._check_zones_config(config)
def common_ixfr_setup(self, xfr_mode, use_ixfr):
# This helper method explicitly sets up a zone configuration with
# ixfr_disabled, and invokes either retransfer or refresh.
# use_ixfr, and invokes either retransfer or refresh.
# Shared by some of the following test cases.
config = {'zones': [
{'name': 'example.com.',
'master_addr': '192.0.2.1',
'ixfr_disabled': ixfr_disabled}]}
'use_ixfr': use_ixfr}]}
self.assertEqual(self.xfr.config_handler(config)['result'][0], 0)
self.assertEqual(self.xfr.command_handler(xfr_mode,
self.args)['result'][0], 0)
def test_command_handler_retransfer_ixfr_enabled(self):
# If IXFR is explicitly enabled in config, IXFR will be used
self.common_ixfr_setup('retransfer', False)
self.common_ixfr_setup('retransfer', True)
self.assertEqual(RRType.IXFR(), self.xfr.xfrin_started_request_type)
def test_command_handler_refresh_ixfr_enabled(self):
# Same for refresh
self.common_ixfr_setup('refresh', False)
self.common_ixfr_setup('refresh', True)
self.assertEqual(RRType.IXFR(), self.xfr.xfrin_started_request_type)
def test_command_handler_retransfer_ixfr_disabled(self):
# Similar to the previous case, but explicitly disabled. AXFR should
# be used.
self.common_ixfr_setup('retransfer', True)
self.common_ixfr_setup('retransfer', False)
self.assertEqual(RRType.AXFR(), self.xfr.xfrin_started_request_type)
def test_command_handler_refresh_ixfr_disabled(self):
# Same for refresh
self.common_ixfr_setup('refresh', True)
self.common_ixfr_setup('refresh', False)
self.assertEqual(RRType.AXFR(), self.xfr.xfrin_started_request_type)
def raise_interrupt():
......
......@@ -876,7 +876,7 @@ class ZoneInfo:
self.set_master_port(config_data.get('master_port'))
self.set_zone_class(config_data.get('class'))
self.set_tsig_key(config_data.get('tsig_key'))
self.set_ixfr_disabled(config_data.get('ixfr_disabled'))
self.set_use_ixfr(config_data.get('use_ixfr'))
def set_name(self, name_str):
"""Set the name for this zone given a name string.
......@@ -951,15 +951,16 @@ class ZoneInfo:
errmsg = "bad TSIG key string: " + tsig_key_str
raise XfrinZoneInfoException(errmsg)
def set_ixfr_disabled(self, ixfr_disabled):
"""Set ixfr_disabled. If set to False (the default), it will use
IXFR for incoming transfers. If set to True, it will use AXFR.
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"""
# don't care what type it is; if evaluates to true, set to True
if ixfr_disabled:
self.ixfr_disabled = True
# TODO: http://bind10.isc.org/ticket/1279
if use_ixfr is None:
self.use_ixfr = \
self._module_cc.get_default_value("zones/use_ixfr")
else:
self.ixfr_disabled = False
self.use_ixfr = use_ixfr
def get_master_addr_info(self):
return (self.master_addr.family, socket.SOCK_STREAM,
......@@ -1065,12 +1066,15 @@ class Xfrin:
logger.error(XFRIN_RETRANSFER_UNKNOWN_ZONE, zone_name.to_text())
answer = create_answer(1, errmsg)
else:
request_type = RRType.AXFR()
if zone_info.use_ixfr:
request_type = RRType.IXFR()
master_addr = zone_info.get_master_addr_info()
ret = self.xfrin_start(zone_name,
rrclass,
self._get_db_file(),
master_addr,
zone_info.tsig_key, RRType.AXFR(),
zone_info.tsig_key, request_type,
True)
answer = create_answer(ret[0], ret[1])
......@@ -1086,7 +1090,7 @@ class Xfrin:
request_type = RRType.AXFR()
if zone_info:
tsig_key = zone_info.tsig_key
if not zone_info.ixfr_disabled:
if zone_info.use_ixfr:
request_type = RRType.IXFR()
db_file = args.get('db_file') or self._get_db_file()
ret = self.xfrin_start(zone_name,
......
......@@ -44,7 +44,7 @@
"item_type": "string",
"item_optional": true
},
{ "item_name": "ixfr_disabled",
{ "item_name": "use_ixfr",
"item_type": "boolean",
"item_optional": false,
"item_default": false
......
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