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

How to bind all interfaces dual-stack? #140

Closed
jaraco opened this issue Mar 11, 2018 · 6 comments
Closed

How to bind all interfaces dual-stack? #140

jaraco opened this issue Mar 11, 2018 · 6 comments

Comments

@jaraco
Copy link
Contributor

jaraco commented Mar 11, 2018

I wish to write a server application that binds to all interfaces in a dual-stack IPv4/IPv6 environment.

I thought the example server would be doing that, as it appears to bind to '::0'. In other applications, like CherryPy, binding to that address makes the server available on all interfaces, IPv4 and IPv6, but in aiosmtpd, the server is only reachable on IPv6. As a result, when the application moves to an environment that only supports IPv4 (looking at you, Docker), the application is unreachable.

Reading up on the docs for create_server, I see that passing a None value for the host should bind to all interfaces on both stacks, and indeed, that's the behavior I see.

But aiosmtpd doesn't allow passing None due to the the localhost default behavior.

I did find one interface that worked, but I'm not happy with it:

	cont = controller.Controller(proxy, port=8025)
	# no really, I want all interfaces
	cont.hostname = None
	cont.start()
@jaraco
Copy link
Contributor Author

jaraco commented Mar 11, 2018

One approach I'm considering is to use a value other than None as the sentinel for "hostname unspecified", have that value be translated into ::1.

But as I consider that, I realize the issue is broader. What if one specifies "::1" or relies on the default fallback - that binding also will be IPv6 only.

I'd really like to be able to bind to all interfaces in a dual-stack way.

@jaraco jaraco changed the title How to bind to all interfaces? How to bind all interfaces dual-stack? Mar 11, 2018
@jaraco
Copy link
Contributor Author

jaraco commented Mar 11, 2018

I do see that one may pass ['::1', '127.0.0.1'] for hostname, and that does bind to both stacks. Similarly, ['::0', '0.0.0.0'] works.

@jaraco
Copy link
Contributor Author

jaraco commented Mar 11, 2018

Also, binding to 'localhost' will bind similarly to ['::1', '127.0.0.1'], but as far as I know, there's no way to simply specify "all interfaces".

Another solution I'm considering is for aiosmtpd to present a constant:

all_interfaces = ['::0', '0.0.0.0']
"hostname to bind to all interfaces"

And use that in the example server to draw attention to it.

@jaraco
Copy link
Contributor Author

jaraco commented Mar 11, 2018

Aha! I just noticed that create_server also accepts '' to indicate all interfaces. And that does work in aiosmtpd. I think for now I'll update the docstring to reflect that as a recommendation.

@jaraco
Copy link
Contributor Author

jaraco commented Mar 11, 2018

I've presented a PR, and that approach feels minimally invasive to address the concern.

@Mortal
Copy link
Contributor

Mortal commented Mar 11, 2018

I think we can label this issue "rubber ducking" :-)

Thanks for the PR and for figuring this out!

warsaw pushed a commit that referenced this issue Jun 16, 2018
* Add docstring to Controller, explaining how to use it to bind dual-stack (local or all interfaces). Fixes #140.

* Move the documentation to the published docs. For inline docs, reference the published docs.

* Add link to Wikipedia's description of dual-stack for easy context.

* Disable the (broken) IPv6 in Travis. Ref travis-ci/travis-ci#8711
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants