Commit 2054fa11 authored by Petr Špaček's avatar Petr Špaček

deckard: document basic functions in query/answer processing

parent db7c1c32
...@@ -404,7 +404,12 @@ class Range: ...@@ -404,7 +404,12 @@ class Range:
return False return False
def reply(self, query): def reply(self, query):
""" Find matching response to given query. """ """
Get answer for given query (adjusted if needed).
Returns:
(DNS message object) or None if there is no candidate in this range
"""
self.received += 1 self.received += 1
for candidate in self.stored: for candidate in self.stored:
try: try:
...@@ -539,7 +544,11 @@ class Step: ...@@ -539,7 +544,11 @@ class Step:
def __query(self, ctx, tcp = False, choice = None, source = None): def __query(self, ctx, tcp = False, choice = None, source = None):
""" Resolve a query. """ """
Send query and wait for an answer (if the query is not RAW).
The received answer is stored in self.answer and ctx.last_answer.
"""
if len(self.data) == 0: if len(self.data) == 0:
raise Exception("query definition required") raise Exception("query definition required")
if self.data[0].is_raw_data_entry is True: if self.data[0].is_raw_data_entry is True:
...@@ -637,10 +646,16 @@ class Scenario: ...@@ -637,10 +646,16 @@ class Scenario:
self.force_ipv6 = False self.force_ipv6 = False
def reply(self, query, address = None): def reply(self, query, address = None):
""" Attempt to find a range reply for a query. """ """
step_id = 0 Generate answer packet for given query.
The answer can be DNS message object or a binary blob.
Returns:
(answer, boolean "is the answer binary blob?")
"""
current_step_id = 0
if self.current_step is not None: if self.current_step is not None:
step_id = self.current_step.id current_step_id = self.current_step.id
# Unknown address, select any match # Unknown address, select any match
# TODO: workaround until the server supports stub zones # TODO: workaround until the server supports stub zones
all_addresses = set() all_addresses = set()
...@@ -650,12 +665,12 @@ class Scenario: ...@@ -650,12 +665,12 @@ class Scenario:
address = None address = None
# Find current valid query response range # Find current valid query response range
for rng in self.ranges: for rng in self.ranges:
if rng.eligible(step_id, address): if rng.eligible(current_step_id, address):
self.current_range = rng self.current_range = rng
return (rng.reply(query), False) return (rng.reply(query), False)
# Find any prescripted one-shot replies # Find any prescripted one-shot replies
for step in self.steps: for step in self.steps:
if step.id < step_id or step.type != 'REPLY': if step.id < current_step_id or step.type != 'REPLY':
continue continue
try: try:
candidate = step.data[0] candidate = step.data[0]
......
...@@ -11,7 +11,13 @@ import binascii ...@@ -11,7 +11,13 @@ import binascii
from dprint import dprint from dprint import dprint
def recvfrom_msg(stream, raw = False): def recvfrom_msg(stream, raw = False):
""" Receive DNS/UDP/TCP message. """ """
Receive DNS message from TCP/UDP socket.
Returns:
if raw == False: (DNS message object, peer address)
if raw == True: (blob, peer address)
"""
if stream.type == socket.SOCK_DGRAM: if stream.type == socket.SOCK_DGRAM:
data, addr = stream.recvfrom(4096) data, addr = stream.recvfrom(4096)
elif stream.type == socket.SOCK_STREAM: elif stream.type == socket.SOCK_STREAM:
...@@ -156,7 +162,13 @@ class TestServer: ...@@ -156,7 +162,13 @@ class TestServer:
return addrlist; return addrlist;
def handle_query(self, client): def handle_query(self, client):
""" Handle incoming queries. """ """
Receive query from client socket and send an answer.
Returns:
True if client socket should be closed by caller
False if client socket should be kept open
"""
client_address = client.getsockname()[0] client_address = client.getsockname()[0]
query, addr = recvfrom_msg(client) query, addr = recvfrom_msg(client)
if query is None: if query is None:
......
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