[dnssd-server] skip additional records on a PTR query with multiple answers (#9281)

This commit updates `Dns::ServiceDiscovery::Server` such that when
answering a PTR query with more than one answer, it does not include
additional records. This is to keep the size of the response small.

This commit also updates the test scripts validating browse (PTR
query) function to check the new behavior. In particular, a common
python function `_parse_dns_service_info()` is added to parse service
info in CLI output of "dns browse" or "dns service" commands and
handle if output of "dns browse" does not include service info.
This commit is contained in:
Abtin Keshavarzian
2023-07-17 13:09:06 -07:00
committed by GitHub
parent 55cb65de62
commit bec592084c
8 changed files with 72 additions and 66 deletions
+35 -42
View File
@@ -3310,6 +3310,31 @@ class NodeImpl:
return list(zip(ip, ttl))
def _parse_dns_service_info(self, output):
# Example of `output`
# Port:22222, Priority:2, Weight:2, TTL:7155
# Host:host2.default.service.arpa.
# HostAddress:0:0:0:0:0:0:0:0 TTL:0
# TXT:[a=00, b=02bb] TTL:7155
m = re.match(
r'.*Port:(\d+), Priority:(\d+), Weight:(\d+), TTL:(\d+)\s+Host:(.*?)\s+HostAddress:(\S+) TTL:(\d+)\s+TXT:\[(.*?)\] TTL:(\d+)',
'\r'.join(output))
if not m:
return {}
port, priority, weight, srv_ttl, hostname, address, aaaa_ttl, txt_data, txt_ttl = m.groups()
return {
'port': int(port),
'priority': int(priority),
'weight': int(weight),
'host': hostname,
'address': address,
'txt_data': txt_data,
'srv_ttl': int(srv_ttl),
'txt_ttl': int(txt_ttl),
'aaaa_ttl': int(aaaa_ttl),
}
def dns_resolve_service(self, instance, service, server=None, port=53):
"""
Resolves the service instance and returns the instance information as a dict.
@@ -3335,33 +3360,10 @@ class NodeImpl:
self.send_command(cmd)
self.simulator.go(10)
output = self._expect_command_output()
# Example output:
# DNS service resolution response for ins2 for service _ipps._tcp.default.service.arpa.
# Port:22222, Priority:2, Weight:2, TTL:7155
# Host:host2.default.service.arpa.
# HostAddress:0:0:0:0:0:0:0:0 TTL:0
# TXT:[a=00, b=02bb] TTL:7155
# Done
m = re.match(
r'.*Port:(\d+), Priority:(\d+), Weight:(\d+), TTL:(\d+)\s+Host:(.*?)\s+HostAddress:(\S+) TTL:(\d+)\s+TXT:\[(.*?)\] TTL:(\d+)',
'\r'.join(output))
if m:
port, priority, weight, srv_ttl, hostname, address, aaaa_ttl, txt_data, txt_ttl = m.groups()
return {
'port': int(port),
'priority': int(priority),
'weight': int(weight),
'host': hostname,
'address': address,
'txt_data': txt_data,
'srv_ttl': int(srv_ttl),
'txt_ttl': int(txt_ttl),
'aaaa_ttl': int(aaaa_ttl),
}
else:
info = self._parse_dns_service_info(output)
if not info:
raise Exception('dns resolve service failed: %s.%s' % (instance, service))
return info
@staticmethod
def __parse_hex_string(hexstr: str) -> bytes:
@@ -3404,9 +3406,10 @@ class NodeImpl:
self.send_command(cmd)
self.simulator.go(10)
output = '\n'.join(self._expect_command_output())
output = self._expect_command_output()
# Example output:
# DNS browse response for _ipps._tcp.default.service.arpa.
# ins2
# Port:22222, Priority:2, Weight:2, TTL:7175
# Host:host2.default.service.arpa.
@@ -3420,21 +3423,11 @@ class NodeImpl:
# Done
result = {}
for ins, port, priority, weight, srv_ttl, hostname, address, aaaa_ttl, txt_data, txt_ttl in re.findall(
r'(.*?)\s+Port:(\d+), Priority:(\d+), Weight:(\d+), TTL:(\d+)\s*Host:(\S+)\s+HostAddress:(\S+) TTL:(\d+)\s+TXT:\[(.*?)\] TTL:(\d+)',
output):
result[ins] = {
'port': int(port),
'priority': int(priority),
'weight': int(weight),
'host': hostname,
'address': address,
'txt_data': txt_data,
'srv_ttl': int(srv_ttl),
'txt_ttl': int(txt_ttl),
'aaaa_ttl': int(aaaa_ttl),
}
index = 1 # skip first line
while index < len(output):
ins = output[index].strip()
result[ins] = self._parse_dns_service_info(output[index + 1:index + 6])
index = index + (5 if result[ins] else 1)
return result
def set_mliid(self, mliid: str):