Skip to content

Make ServiceInfo first question QU #852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions tests/services/test_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,8 @@ def send(out, addr=const._MDNS_ADDR, port=const._MDNS_PORT):
zeroconf.close()


def test_asking_qm_questions_are_default():
"""Verify default is QM questions."""
def test_asking_qm_questions():
"""Verify explictly asking QM questions."""
type_ = "_quservice._tcp.local."
zeroconf = r.Zeroconf(interfaces=['127.0.0.1'])

Expand All @@ -701,6 +701,6 @@ def send(out, addr=const._MDNS_ADDR, port=const._MDNS_PORT):

# patch the zeroconf send
with patch.object(zeroconf, "async_send", send):
zeroconf.get_service_info(f"name.{type_}", type_, 500)
zeroconf.get_service_info(f"name.{type_}", type_, 500, question_type=r.DNSQuestionType.QM)
assert first_outgoing.questions[0].unicast == False
zeroconf.close()
47 changes: 47 additions & 0 deletions tests/test_aio.py
Original file line number Diff line number Diff line change
Expand Up @@ -776,3 +776,50 @@ def send(out, addr=const._MDNS_ADDR, port=const._MDNS_PORT, v6_flow_scope=()):
assert service_removed.is_set()
await browser.async_cancel()
await aiozc.async_close()


@pytest.mark.asyncio
async def test_info_asking_default_is_asking_qm_questions_after_the_first_qu():
"""Verify the service info first question is QU and subsequent ones are QM questions."""
type_ = "_quservice._tcp.local."
aiozc = AsyncZeroconf(interfaces=['127.0.0.1'])
zeroconf_info = aiozc.zeroconf

name = "xxxyyy"
registration_name = "%s.%s" % (name, type_)

desc = {'path': '/~paulsm/'}
info = ServiceInfo(
type_, registration_name, 80, 0, 0, desc, "ash-2.local.", addresses=[socket.inet_aton("10.0.1.2")]
)

zeroconf_info.registry.add(info)

# we are going to patch the zeroconf send to check query transmission
old_send = zeroconf_info.async_send

first_outgoing = None
second_outgoing = None

def send(out, addr=const._MDNS_ADDR, port=const._MDNS_PORT):
"""Sends an outgoing packet."""
nonlocal first_outgoing
nonlocal second_outgoing
if out.questions:
if first_outgoing is not None and second_outgoing is None:
second_outgoing = out
if first_outgoing is None:
first_outgoing = out
old_send(out, addr=addr, port=port)

# patch the zeroconf send
with patch.object(zeroconf_info, "async_send", send):
aiosinfo = AsyncServiceInfo(type_, registration_name)
# Patch _is_complete so we send multiple times
with patch("zeroconf.aio.AsyncServiceInfo._is_complete", False):
await aiosinfo.async_request(aiozc.zeroconf, 1200)
try:
assert first_outgoing.questions[0].unicast == True
assert second_outgoing.questions[0].unicast == False
finally:
await aiozc.async_close()
6 changes: 5 additions & 1 deletion zeroconf/_services/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ async def async_request(
if self.load_from_cache(zc):
return True

first_request = True
now = current_time_millis()
delay = _LISTENER_TIME
next_ = now
Expand All @@ -449,7 +450,10 @@ async def async_request(
if last <= now:
return False
if next_ <= now:
out = self.generate_request_query(zc, now, question_type)
out = self.generate_request_query(
zc, now, question_type or DNSQuestionType.QU if first_request else DNSQuestionType.QM
)
first_request = False
if not out.questions:
return self.load_from_cache(zc)
zc.async_send(out)
Expand Down