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 socket creation when APR_UNSPEC is used #44
Conversation
When APR_UNSPEC is used, socket family is automaticaly set to APR_INET6 in apr_socket_create() and therefore if apr_sockaddr_info_get() finds out that the given address is in IPv4 format, it fails when calling apr_socket_connect(). So we first call apr_sockaddr_info_get() to get info about addr family and then pass it to apr_socket_create().
Reproducer: run: $ ./memcachecon 127.0.0.1 11211
|
Ah, hmm. I think this is still incorrect. The proper way is to loop over the returned addresses until a connect() succeeds. e.g. this: |
Ohh, I thought this job is done in apr_sockaddr_info_get --> find_addresses --> call_resolver(): https://github.com/apache/apr/blob/trunk/network_io/unix/sockaddr.c#L446 But this will only go through the list of addresses until the first AF_INET/AF_INET6 address is found. In case we pass hostname to it, it will indeed try only the first returned address which is not correct approach. I will to alter this patch and add the part where it will loop through all returned addresses until a connect() succeeds. |
to which is possible connect.
Altered the way how conn_connect() creates a socket connection. It should go now through all addresses returned by apr_sockaddr_info_get(). |
} | ||
|
||
apr_socket_close(conn->sock); | ||
} | ||
} |
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 needs to catch the error case where no loop iteration succeeds, if sa is NULL after the for() loop then it should return with an error.
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.
Shouldn't the below directly after the for() loop fix this?
} | |
} | |
if (rv != APR_SUCCESS) { | |
return rv; | |
} |
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 would also work IMHO. I think, since we set apr_socket_timeout_set on closed socket, it would fail anyway... But it is the better way how to handle it - explicitly say that we were not able to connect to any of given addresses.
Thanks Lubos! |
When APR_UNSPEC is used, socket family is automaticaly set to APR_INET6 in apr_socket_create() and therefore if apr_sockaddr_info_get() finds out that the given address is in IPv4 format, it fails when calling apr_socket_connect(). So we first call apr_sockaddr_info_get() to get info about addr family and then pass it to apr_socket_create().