Skip to content
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

aiodns does not work with mDNS and is the default resolver #10186

Open
1 task done
gsmecher opened this issue Dec 20, 2024 · 4 comments
Open
1 task done

aiodns does not work with mDNS and is the default resolver #10186

gsmecher opened this issue Dec 20, 2024 · 4 comments
Labels

Comments

@gsmecher
Copy link

Describe the bug

With aiohttp v3.10.10, mDNS hostnames do not resolve when aiodns is installed.

When I force the use of a ThreadedResolver, or when I uninstall aiodns, mDNS hostnames resolve fine.

I see (#8522) that aiodns was made the default resolver again, recently, which explains the regression. The underlying c-ares library has a long-time open request for mDNS support (c-ares/c-ares#171) and no movement over the past few years.

To Reproduce

You will need a mDNS-resolvable service for this to work. (If you have avahi-daemon installed, your hostname with a .local suffix should suffice.)

>>> import aiohttp
>>> import asyncio
>>> async def main():
...    async with aiohttp.ClientSession() as session:
...        async with session.get('http://some_mdns_hostname.local') as resp:
...            print(resp.status)
...            print(await resp.text())
>>>asyncio.run(main())
ClientConnectorDNSError: Cannot connect to host rfmux0033.local:80 ssl:default [Domain name not found]

Expected behavior

Correct resolution of the hostname via mDNS.

Logs/tracebacks

ClientConnectorDNSError: Cannot connect to host some_mdns_hostname.local:80 ssl:default [Domain name not found]

Python Version

$ python --version
Python 3.12.8

aiohttp Version

aiohttp.__version__
'3.10.10'

multidict Version

multidict.__version__
'6.1.0'

propcache Version

Not installed.

yarl Version

yarl.__version__
'1.13.1'

OS

Debian Linux (testing)

Related component

Client

Additional context

No response

Code of Conduct

  • I agree to follow the aio-libs Code of Conduct
@gsmecher gsmecher added the bug label Dec 20, 2024
@Dreamsorcerer
Copy link
Member

Perhaps we can bypass aiodns for .local or something, in order to improve the situation?

@bdraco
Copy link
Member

bdraco commented Dec 20, 2024

At least for Home Assistant, .local domains get resolved by the local DNS server, so there's no need to fall back to ThreadedResolver for these.

While .local domains are rare enough that it probably wouldn't matter that much for performance (unless all of the domains the user is resolving are .local) if we did force the ThreadedResolver for .local when using AsyncResolver, mDNS resolution is usually implemented via some type of glibc plug-in (sometimes https://github.com/avahi/nss-mdns) or similar so it wouldn't cover all the cases. If you are using musl it might be tied into the DNS server like Home Assistant is doing. Adding fallback for .local feels like a bit of a slippery slope to start trying to guess what the behavior the user wants so I'm -0 on adding it to AsyncResolver.

If your target system is making use of such plug-ins, it won't be obvious to aiohttp, and I would recommend creating the threaded resolver manually instead. The downside is the performance hit can be substantial as the threading cost has to be paid for all domains and not only .local domains, this is especially relavant if you aren't accessing the same domains over and over as with that case resolution is mostly cached.

If fallback for .local is something we are really want to do I'd be more comfortable if we added a new hybrid resolver class so the fallback behavior wasn't forced for AsyncResolver. We could consider making the new resolver class the default for 3.12, but considering AsyncResolver has been the default for 3.10+, and we are already shipping 3.11 now, I wouldn't want to change it in a patch release.

@gsmecher
Copy link
Author

I have added a workaround for our codebase (gsmecher/tuberd#54), so we're OK for now.

Our aiohttp code runs client-side on a PC, not in an embedded appliance - so we don't control the execution environment enough to insist on any local infrastructure (DNS cache, DNS server, or resolver modifications). In fact, this lack of control over client networks is why we went with mDNS in the first place. It's a shame to see support moving backwards here.

@bdraco
Copy link
Member

bdraco commented Dec 21, 2024

so we don't control the execution environment enough to insist on any local infrastructure (DNS cache, DNS server, or resolver modifications)

On a side note, since you don't control the environment, using zeroconf to resolve the hosts might be a better fit for your use case as it's not going to dependent on the libc stack or nss configuration as even with ThreadedResolver mDNS is likely not to work on Alpine or any Linux using musl without some local dns server configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants