[svn] commit: r1851 - in /branches/trac185/src/bin/xfrin: tests/xfrin_test.py xfrin.py.in
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed May 19 01:34:56 UTC 2010
Author: jinmei
Date: Wed May 19 01:34:56 2010
New Revision: 1851
Log:
- fixed a bug that xfrin doesn't support IPv6 master address.
- used getaddrinfo instead of inet_pton as part of it (so we can even support IPv8:-)
- existing unit tests confirmed there shouldn't be regression
Modified:
branches/trac185/src/bin/xfrin/tests/xfrin_test.py
branches/trac185/src/bin/xfrin/xfrin.py.in
Modified: branches/trac185/src/bin/xfrin/tests/xfrin_test.py
==============================================================================
--- branches/trac185/src/bin/xfrin/tests/xfrin_test.py (original)
+++ branches/trac185/src/bin/xfrin/tests/xfrin_test.py Wed May 19 01:34:56 2010
@@ -26,7 +26,13 @@
TEST_RRCLASS = rr_class.IN()
TEST_DB_FILE = 'db_file'
TEST_MASTER_IPV4_ADDRESS = '127.0.0.1'
+TEST_MASTER_IPV4_ADDRINFO = (socket.AF_INET, socket.SOCK_STREAM,
+ socket.IPPROTO_TCP, '',
+ (TEST_MASTER_IPV4_ADDRESS, 53))
TEST_MASTER_IPV6_ADDRESS = '::1'
+TEST_MASTER_IPV6_ADDRINFO = (socket.AF_INET6, socket.SOCK_STREAM,
+ socket.IPPROTO_TCP, '',
+ (TEST_MASTER_IPV6_ADDRESS, 53))
# XXX: This should be a non priviledge port that is unlikely to be used.
# If some other process uses this port test will fail.
TEST_MASTER_PORT = '53535'
@@ -132,7 +138,7 @@
os.remove(TEST_DB_FILE)
self.conn = MockXfrinConnection('example.com.', TEST_DB_FILE,
threading.Event(),
- TEST_MASTER_IPV4_ADDRESS)
+ TEST_MASTER_IPV4_ADDRINFO)
def tearDown(self):
self.conn.close()
@@ -147,9 +153,8 @@
# uncovers such a bug.
c = MockXfrinConnection('example.com.', TEST_DB_FILE,
threading.Event(),
- TEST_MASTER_IPV6_ADDRESS)
- #This test currently fails. Fix the code, then enable it
- #c.bind(('::', 0))
+ TEST_MASTER_IPV6_ADDRINFO)
+ c.bind(('::', 0))
c.close()
def test_response_with_invalid_msg(self):
@@ -310,19 +315,21 @@
return self.xfr._parse_cmd_params(self.args)
def test_parse_cmd_params(self):
- name, master, port, db_file = self._do_parse()
- self.assertEqual(port, int(TEST_MASTER_PORT))
+ name, master_addrinfo, db_file = self._do_parse()
+ self.assertEqual(master_addrinfo[4][1], int(TEST_MASTER_PORT))
self.assertEqual(name, TEST_ZONE_NAME)
- self.assertEqual(master, TEST_MASTER_IPV4_ADDRESS)
+ self.assertEqual(master_addrinfo[4][0], TEST_MASTER_IPV4_ADDRESS)
self.assertEqual(db_file, TEST_DB_FILE)
def test_parse_cmd_params_default_port(self):
del self.args['port']
- self.assertEqual(self._do_parse()[2], 53)
+ master_addrinfo = self._do_parse()[1]
+ self.assertEqual(master_addrinfo[4][1], 53)
def test_parse_cmd_params_ip6master(self):
self.args['master'] = TEST_MASTER_IPV6_ADDRESS
- self.assertEqual(self._do_parse()[1], TEST_MASTER_IPV6_ADDRESS)
+ master_addrinfo = self._do_parse()[1]
+ self.assertEqual(master_addrinfo[4][0], TEST_MASTER_IPV6_ADDRESS)
def test_parse_cmd_params_nozone(self):
# zone name is mandatory.
@@ -347,6 +354,9 @@
self.assertRaises(XfrinException, self._do_parse)
self.args['port'] = '65536'
+ self.assertRaises(XfrinException, self._do_parse)
+
+ self.args['port'] = 'http'
self.assertRaises(XfrinException, self._do_parse)
def test_command_handler_shutdown(self):
Modified: branches/trac185/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac185/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac185/src/bin/xfrin/xfrin.py.in Wed May 19 01:34:56 2010
@@ -51,6 +51,8 @@
# define xfrin rcode
XFRIN_OK = 0
+DEFAULT_MASTER_PORT = '53'
+
def log_error(msg):
sys.stderr.write("[b10-xfrin] ")
sys.stderr.write(str(msg))
@@ -63,15 +65,15 @@
'''Do xfrin in this class. '''
def __init__(self,
- zone_name, db_file, shutdown_event, master_addr,
- port = 53, verbose = False, idle_timeout = 60):
+ zone_name, db_file, shutdown_event, master_addrinfo,
+ verbose = False, idle_timeout = 60):
''' idle_timeout: max idle time for read data from socket.
db_file: specify the data source file.
check_soa: when it's true, check soa first before sending xfr query
'''
asyncore.dispatcher.__init__(self)
- self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.create_socket(master_addrinfo[0], master_addrinfo[1])
self._zone_name = zone_name
self._db_file = db_file
self._soa_rr_count = 0
@@ -79,17 +81,17 @@
self.setblocking(1)
self._shutdown_event = shutdown_event
self._verbose = verbose
- self._master_addr = master_addr
- self._port = port
+ self._master_address = master_addrinfo[4]
def connect_to_master(self):
'''Connect to master in TCP.'''
try:
- self.connect((self._master_addr, self._port))
+ self.connect(self._master_address)
return True
except socket.error as e:
- self.log_msg('Failed to connect:(%s:%d), %s' % (self._master_addr, self._port, str(e)))
+ self.log_msg('Failed to connect:(%s), %s' % (self._master_address,
+ str(e)))
return False
def _create_query(self, query_type):
@@ -287,11 +289,10 @@
def process_xfrin(xfrin_recorder, zone_name, db_file,
- shutdown_event, master_addr, port, check_soa, verbose):
- port = int(port)
+ shutdown_event, master_addrinfo, check_soa, verbose):
xfrin_recorder.increment(zone_name)
conn = XfrinConnection(zone_name, db_file, shutdown_event,
- master_addr, port, verbose)
+ master_addrinfo, verbose)
if conn.connect_to_master():
conn.do_xfrin(check_soa)
@@ -376,13 +377,14 @@
self._shutdown_event.set()
elif cmd == 'retransfer':
- zone_name, master, port, db_file = self._parse_cmd_params(args)
- ret = self.xfrin_start(zone_name, db_file, master, port, False)
+ zone_name, master_addrinfo, db_file = self._parse_cmd_params(args)
+ ret = self.xfrin_start(zone_name, db_file, master_addrinfo,
+ False)
answer = create_answer(ret[0], ret[1])
elif cmd == 'refresh':
- zone_name, master, port, db_file = self._parse_cmd_params(args)
- ret = self.xfrin_start(zone_name, db_file, master, port)
+ zone_name, master_addrinfo, db_file = self._parse_cmd_params(args)
+ ret = self.xfrin_start(zone_name, db_file, master_addrinfo)
answer = create_answer(ret[0], ret[1])
except XfrinException as err:
@@ -399,27 +401,23 @@
if not master:
raise XfrinException('master address should be provided')
- check_addr(master)
- port = 53
port_str = args.get('port')
- if port_str:
- port = int(port_str)
- check_port(port)
+ if not port_str:
+ port_str = DEFAULT_MASTER_PORT
+ 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
db_file = '@@LOCALSTATEDIR@@/@PACKAGE@/zone.sqlite3'
- return (zone_name, master, port, db_file)
-
+ return (zone_name, master_addrinfo, db_file)
def startup(self):
while not self._shutdown_event.is_set():
self._cc_check_command()
- def xfrin_start(self, zone_name, db_file, master_addr,
- port = 53,
+ def xfrin_start(self, zone_name, db_file, master_addrinfo,
check_soa = True):
if "bind10_dns" not in sys.modules:
return (1, "xfrin failed, can't load dns message python library: 'bind10_dns'")
@@ -436,8 +434,8 @@
zone_name,
db_file,
self._shutdown_event,
- master_addr,
- port, check_soa, self._verbose))
+ master_addrinfo, check_soa,
+ self._verbose))
xfrin_thread.start()
return (0, 'zone xfrin is started')
@@ -454,20 +452,20 @@
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
-def check_port(value):
- if (value < 0) or (value > 65535):
- raise XfrinException('requires a port number (0-65535)')
-
-def check_addr(ipstr):
- ip_family = socket.AF_INET
- if (ipstr.find(':') != -1):
- ip_family = socket.AF_INET6
-
+def check_addr_port(addrstr, portstr):
try:
- socket.inet_pton(ip_family, ipstr)
- except:
- raise XfrinException("%s invalid ip address" % ipstr)
-
+ addrinfo = socket.getaddrinfo(addrstr, portstr, socket.AF_UNSPEC,
+ socket.SOCK_STREAM, socket.IPPROTO_TCP,
+ socket.AI_NUMERICHOST|
+ socket.AI_NUMERICSERV)
+ except socket.gaierror as err:
+ raise XfrinException("failed to resolve master address/port=%s/%s: %s" %
+ (addrstr, portstr, str(err)))
+ if len(addrinfo) != 1:
+ # with the parameters above the result must be uniquely determined.
+ errmsg = "unexpected result for address/port resolution for %s:%s"
+ raise XfrinException(errmsg % (addrstr, portstr))
+ return addrinfo[0]
def set_cmd_options(parser):
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
More information about the bind10-changes
mailing list