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
Fix setting of IPV6_V6ONLY on Windows #5139
Fix setting of IPV6_V6ONLY on Windows #5139
Conversation
@levitte I noticed that the cygwin test stalls while the normal windows test worked on the |
crypto/bio/b_sock2.c
Outdated
if ((options & BIO_SOCK_V6_ONLY) && BIO_ADDR_family(addr) == AF_INET6) { | ||
if (BIO_ADDR_family(addr) == AF_INET6) { | ||
/* Note: Windows default of IPV6_V6ONLY is ON, and Linux is OFF. | ||
* Therefore we always have to use setsockopt here. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Block comment must be like this:
/*
* text...
* text...
*/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay, I did just copy the style from a few lines above.
Will fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe I fix the other comment as well.
Well, since the tests use hard-coded ports, the two runs are going to trample over each other. No surprise there... |
I did of course not run both at the same time. |
Could you check the presence of |
I would like to point out that the Linux behavior is actually something you can control. Also some other OSs don't support IPv6 mapped IPv4. |
The working setup is Strawberry Perl: The non-working (but fixed by this PR) setup is cygwin-perl: There may also be a difference what "localhost" is resolved into. The failed test run on cygwin stalls here:
|
Is there a configuration option other than using the sockopt for that? |
Regarding Cygwin, that set of modules should have make the s_server and s_client commands IPv4 only, i.e. there should be a |
Whoops... yes, I forgot to update. With -4 that would not have happened. |
The server binds to the first address it gets when looking up |
With the client I can make it sure what I get when I say "-connect [::1]:4443" or |
I know already that the sever uses getaddrinfo(NULL, ...) |
We really should change s_server to |
But the point of this PR is still that the socket should bind to IPv6 and IPv4 |
Aehm, apparently there is an IP module as well, but in a different directory. |
Hmm, and Windows Perl picks INET6, which I failed to find previously. |
Is there a configuration option other than using the sockopt for that?
I think it's /proc/sys/net/ipv6/bindv6only
|
Yes, thanks, you're right. I would not want to depend on that setting, though. |
@@ -206,7 +208,12 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) | |||
} | |||
|
|||
# ifdef IPV6_V6ONLY | |||
if ((options & BIO_SOCK_V6_ONLY) && BIO_ADDR_family(addr) == AF_INET6) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a side note one can wonder if it's appropriate to ignore BIO_SOCK_V6_ONLY in cases when IPV6_V6ONLY is not defined. I mean following. If you have platform that supports AF_INET6, but not IPV6_V6ONLY, then wouldn't it be appropriate to return error to application that attempts BIO_SOCK_V6_ONLY on such platform? Instead of silently ignoring it as it is now that is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it as a kind of best effort.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it as a kind of best effort.
And question is this is adequate view. I mean if you pass unrecognized option, wouldn't you like to know that it's not supported? Well, one can always argue that AF_INET6 platforms that don't have IPV6_V6ONLY don't deserve respect... For reference, so far I've spotted only one, Windows 2003/XP. So no biggie... Once again, this is a side note.
@@ -175,8 +175,10 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) | |||
return 0; | |||
|
|||
# ifndef OPENSSL_SYS_WINDOWS | |||
/* SO_REUSEADDR has different behavior on Windows than on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On side note one can wonder how does it affect Cygwin. I mean Cygwin has no other option by to rely on Windows sockets... So maybe condition has to cover even Cygwin...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On related note, since SO_REUSEADDR is special on Windows, maybe it would be appropriate to support its "antipode", SO_EXCLUSIVEADDRUSE. I mean b_sock2.c is supposed to provide OS-neutral interface to sockets, right? So that one write multi-platform application. This kind of implies that it should be expressive enough to do various useful things. And it's not inappropriate to expect that BIO socket is created "exclusive". In fact one can wonder if they should be created "exclusive" unconditionally on Windows, as reflection of fact that it's "exclusive" on Unix... Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So they are saying that another process from another user account for instance
can intercept new connections with SO_REUSEADDR, unless we use
SO_EXCLUSIVADDRUSE?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So they are saying
Originally it was the case, yes. By now they have some improvements, like bound port can be hijacked only from same account...
Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from #5139)
Merged. Thanks! |
On Windows, the default of IPV6_V6ONLY is different than on Linux.
That means that on Windows (at least Windows 7)
openssl s_server -accept 4443 -6
listens on [::]:4443 only,
that means:
openssl s_client -connect [::1]:4443
succeedswhile
openssl s_client -connect [127.0.0.1]:4443
fails.while on Linux both commands succeed.