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

No route to host error with IPv6 #25

Closed
skrech opened this issue Mar 2, 2022 · 4 comments
Closed

No route to host error with IPv6 #25

skrech opened this issue Mar 2, 2022 · 4 comments
Assignees
Labels
bug Something isn't working enhancement New feature or request
Milestone

Comments

@skrech
Copy link

skrech commented Mar 2, 2022

Hello crashvb,

Thanks for the great package, I'm happy that there is docker/oci registry client that works with python!

I've encountered a problem, though. aiodns package, used for DNS resolution in DRCA, has a shortcoming of returning either IPv4 or IPv6 addresses, but not both on DNS resolution. This causes domains having both A and AAAA records to be resolved by aiodns with only IPv6. Since IPv6 is not common yet, most OSes have working IPv6 stacks but no default route setup, which leads to OSError No Route to Host when trying get a blob, for example. This is especially true if the application using DRCA is running in Docker container, however, then the error is even more cryptic: instead of No Route to Host, it fails with Errno 99 [Cannot assign requested address].

For this exact problem, aiohttp switched the default resolver to ThreadedResolver from AsyncResolver (aio-libs/aiohttp@9fbb7d7).

The problem with IPv6 is coming from c-ares C lib, actually:
c-ares/c-ares#70

And it's tracked in 'aiodns', here:
aio-libs/aiodns#23

One workaround is to pair AsyncResolver with aiohttp.TCPConnector class that have an explicit family kwargs set to IPv4. Unfortunately, DRCA only supports passing custom arguments to AsyncResolver, but not to aiohttp.TCPConnector. So, the following hack should be made:

class DRCA_PATCHED(drca.DockerRegistryClientAsync):
    async def _get_client_session(self):
        if not self.client_session:
            self.client_session = aiohttp.ClientSession(
                connector=aiohttp.TCPConnector(
                    resolver=aiohttp.AsyncResolver(**self.resolver_kwargs),
                    ssl=self.ssl,
                    family=socket.AF_INET,
                )
            )
        return self.client_session

So, I guess, this will be encountered very often by users (and even more often when domains start to acquire AAAA records, I've encountered it with trying to download layers of python:3.9 image from docker.io), so maybe it will be better for DRCA to allow passing Connector options, or be able to switch the Resolver class.

@crashvb crashvb self-assigned this Mar 2, 2022
@crashvb crashvb added bug Something isn't working enhancement New feature or request labels Mar 2, 2022
@crashvb crashvb added this to the sprint_82 milestone Mar 2, 2022
@crashvb
Copy link
Owner

crashvb commented Mar 2, 2022

@skrech,

Good find! :)

This might explain some of the weird DNS behavior I was experienced in downstream projects on-prem. There were several edge cases with c-ares not handling server rejections, process hosts aliases, or honoring lookup parameters ... but it got to the point where I gave up and did DNS resolution out-of-band up a layer (sad-but-true).

I agree that it should be possible to both specify the resolver and have the TCPConnector parameters exposed; I'll push out a fix.

Thank you

crashvb added a commit that referenced this issue Mar 2, 2022
@crashvb
Copy link
Owner

crashvb commented Mar 2, 2022

I pushed a fix to the dev branch; let me know if you think I'm missing something ...

@crashvb crashvb closed this as completed in 18703c4 Mar 3, 2022
@crashvb
Copy link
Owner

crashvb commented Mar 3, 2022

Released in v0.2.2.

@crashvb crashvb mentioned this issue Mar 4, 2022
@skrech
Copy link
Author

skrech commented Mar 4, 2022

Thank you for the fast reaction! Changes look good! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants