Commit b841cd30 authored by Petr Špaček's avatar Petr Špaček

Support multiple ADDRESS parameters in RANGE block.

Multiple IPv4/IPv6 addresses can be specified for single RANGE.
This allows to specify responses for zones with multiple
name servers without copy-pasting the data for each server's address.
parent 0dcc0ddb
......@@ -104,20 +104,22 @@ Format:
- **n1** and **n2** respectively minimal or maximal step ids (see below) to which this
range can be applied.
- **addr** - IP address for which **RANGE** datablock is prepared; this statement can be omitted.
- **addr** - IP address for which **RANGE** datablock is prepared; this statement can be omitted or repeated multiple times.
Datablock will be used for fetching reply to query only for these steps, whose identificators greater then or equal n1 and
lesser then or equal n2. Also one of the next condition must be met :
- addr is not set
- addr is set, and query is directed to this addr
- address, to which query is directed, can not be found within the range addresses list for whole scenario
- addr is set, and query is directed to one of listed addresses
- address, to which query is directed, can not be found within the range addresses lists for whole scenario
**STEP datablock**
......@@ -236,8 +236,9 @@ def play_object(path, binary_name, config_name, j2template, binary_additional_pa
# Bind to test servers
for r in case.ranges:
family = socket.AF_INET6 if ':' in r.address else socket.AF_INET
server.start_srv((r.address, 53), family)
for addr in r.addresses:
family = socket.AF_INET6 if ':' in addr else socket.AF_INET
server.start_srv((addr, 53), family)
# Bind addresses in ad-hoc REPLYs
for s in case.steps:
if s.type == 'REPLY':
......@@ -381,14 +381,14 @@ class Range:
""" Initialize reply range. """
self.a = a
self.b = b
self.address = None
self.addresses = set()
self.stored = []
self.args = {}
self.received = 0
self.sent = 0
def __del__(self):
dtag = '[ RANGE %d-%d ] %s' % (self.a, self.b, self.address)
dtag = '[ RANGE %d-%d ] %s' % (self.a, self.b, self.addresses)
dprint(dtag, 'received: %d sent: %d' % (self.received, self.sent))
def add(self, entry):
......@@ -398,7 +398,9 @@ class Range:
def eligible(self, id, address):
""" Return true if this range is eligible for fetching reply. """
if self.a <= id <= self.b:
return None in (self.address, address) or (self.address == address)
return (None == address
or set() == self.addresses
or address in self.addresses)
return False
def reply(self, query):
......@@ -643,7 +645,10 @@ class Scenario:
step_id =
# Unknown address, select any match
# TODO: workaround until the server supports stub zones
if address not in [rng.address for rng in self.ranges]:
all_addresses = set()
for rng in self.ranges:
if address not in all_addresses:
address = None
# Find current valid query response range
for rng in self.ranges:
......@@ -799,7 +804,7 @@ def parse_range(op, args, file_in):
out = Range(int(args[0]), int(args[1]))
# Shortcut for address
if len(args) > 2:
out.address = args[2]
# Parameters
if len(args) > 3:
out.args = {}
......@@ -808,7 +813,7 @@ def parse_range(op, args, file_in):
out.args[k] = v
for op, args in iter(lambda: get_next(file_in), False):
if op == 'ADDRESS':
out.address = args[0]
elif op == 'ENTRY_BEGIN':
out.add(parse_entry(op, args, file_in, in_entry = True))
elif op == 'RANGE_END':
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