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
Make BIO connect to allow multiple IP addresses #11971
Conversation
I find it weird to do this in the blocked state... and I have a hard time understanding why you'd have a configuration where one IP version is blocked while the other isn't. But there's new stuff going on that I frankly don't always understand... back when I was doing network management, a block was a block was a block. |
For whatever reason, I got the issue only in non-blocking mode (when
That's not the point here. |
BTW, |
I think this should be back-ported to 1.1.1 |
I think you're just using the API wrong. On failure, the application calling BIO_connect() should use the next address, and that it what for instance s_client does in init_client(). It iterates over the addresses. |
This also most likely seem to cause errors, since the address family of the socket you've created with BIO_socket() doesn't actually match with what BIO_connect() is trying to do now |
Or am mixing up the APIs |
I may be wrong as well.... |
Clearly I was mixing up APIs. That code at least looks weird. I think it's missing a BIO_sock_should_retry() call. I think we can be in 3 states: success, failure, still waiting. And it seems now it's only success or failure. |
@kroeckx, |
So it seems we agree the IP address iteration should be handled internally (like the fix now make sure)? |
see the case BIO_CONN_S_CONNECT: |
I think the BIO_CONN_S_BLOCKED_CONNECT is at least a confusing name, I think it's waiting for the connect to succeed there. I was also expecting that if you ran out of addresses you'd go to BIO_CONN_S_CONNECT_ERROR |
Yes, agree, maybe move the |
However while a connection to localhost will always fail quickly, |
A quick look at |
Yeah, s_client does not use this API, but it would be a good idea to use this there. |
s_client also does try alternative addresses, via |
I also have the impression it would be better if s_client used |
I think the commit message should mention BIO_do_connect, |
You should fix the BIO_socket_wait function before you do that: |
Hmm, actually, I don't really see this function in libcrypto. |
Anyway, this PR is okay, also for 1.1.1, |
I also don't see the point of BIO_connect_retry(). It seems to
turn the non-blocking case in a blocking case. Maybe the behaviour
should just change depending on BIO_set_nbio()?
|
2d0dfa8
to
7293586
Compare
Done. |
As far as I recall, the type cast was needed for Windows builds (AppVeyor),
So I've added the following input check to the function:
|
7293586
to
b7b3fc8
Compare
b7b3fc8
to
f8e8dad
Compare
The point of
This is mentioned in its documentation:
|
f8e8dad
to
33f4812
Compare
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.
OK, for master and 1.1.1
c3f43a7
to
33f4812
Compare
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.
This makes sense to me.
This pull request is ready to merge |
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from #11971)
Merged - thanks all involved! |
This seems like a change that would be noticed. manpage and/or CHANGES entry? |
I've made a new issue since this PR is closed: #12017 |
/* | ||
* if there are more addresses to try, do that first | ||
*/ | ||
BIO_closesocket(b->num); |
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.
This is copied from above.
b->num should be initialized to INVALID_SOCKET.
since it takes a risk that the socket is close twice.
I think both places should clear that value since the
BIO_socket could fail, and the following BIO_reset
will close the socket a second time.
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.
We need either new PR or add it to #12017
When doing CLI-based tests with the new CMP client and mock server I faced strange
Connection refused
errors when using non-blocking I/O with timeout enabled.It took me quite a while to find out that this only happened when connecting to, e.g.,
localhost
(but not when using IPv4 addresses such as127.0.0.1
) and only when/etc/hosts
contains both IPv4 and IPv6 addresses forlocalhost
and when IPv6 is preferred.It turns out that
conn_state()
incrypto/bio/bss_conn.c
is simply not flexible enough to handle alternative IP addresses on connect (BIO_C_DO_STATE_MACHINE
). This madeBIO_connect_retry()
fail on the first retry when the host islocalhost
and thetimeout
parameter is non-zero.The patch given fixes this problem by making sure that all IP addresses (of any type) are tried in case a hostname (i.e., DNS name) is resolved to more than one IP address.
A workaround at least in my case is to comment out in
/etc/hosts/
the line