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
OpenSSL 3.2.0, QUIC, macOS, error 56 on connected UDP socket #23396
Conversation
crypto/bio/bss_dgram.c
Outdated
struct sockaddr_storage ss; | ||
socklen_t ss_len = sizeof(ss); | ||
|
||
return (getpeername(b->num, (struct sockaddr *)&ss, &ss_len) == 0); |
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 do not think we want to add a syscall to every BIO_sendmmsg
invocation.
Whether a socket is connected is supposed to be tracked by BIO_CTRL_DGRAM_SET_CONNECTED (data->connected
).
On Mon, Jan 29, 2024 at 12:46:50AM -0800, Hugo Landau wrote:
@hlandau requested changes on this pull request.
__________________________________________________________________
In [1]crypto/bio/bss_dgram.c:
>
mh->msg_iov = iov;
mh->msg_iovlen = 1;
mh->msg_control = msg->local != NULL ? control : NULL;
mh->msg_controllen = msg->local != NULL ? BIO_CMSG_ALLOC_LEN : 0;
mh->msg_flags = 0;
}
+
+static int is_connected(BIO *b)
+{
+ struct sockaddr_storage ss;
+ socklen_t ss_len = sizeof(ss);
+
+ return (getpeername(b->num, (struct sockaddr *)&ss, &ss_len) == 0);
I do not think we want to add a syscall to every BIO_sendmmsg
invocation.
Whether a socket is connected is supposed to be tracked by
BIO_CTRL_DGRAM_SET_CONNECTED (data->connected).
yes, it makes sense. I'll send updated PR shortly. The new version
calls `getpeername()` in `dgram_ctrl()` when `BIO_C_SET_FD` command.
I think this is the kind of change Hugo expects.
|
f86585c
to
f274cef
Compare
On Mon, Jan 29, 2024 at 08:03:08AM -0800, Tom???? Mr??z wrote:
@t8m requested changes on this pull request.
__________________________________________________________________
In [1]crypto/bio/bss_dgram.c:
>
mh->msg_iov = iov;
mh->msg_iovlen = 1;
mh->msg_control = msg->local != NULL ? control : NULL;
mh->msg_controllen = msg->local != NULL ? BIO_CMSG_ALLOC_LEN : 0;
mh->msg_flags = 0;
}
+
Please drop this spurious addition.
__________________________________________________________________
In [2]test/quic_client_test.c:
> + if (test_get_argument_count() > 0) {
+ mode = test_get_argument(0);
+ if (TEST_ptr(mode) && strcasecmp(mode, "connect_first") == 0) {
+ connect_socket();
+ }
+
+ if (cc_fd == INVALID_SOCKET) {
+ TEST_error("Could not create connected socket");
+ return 0;
+ }
+ }
Not sure if it is worth changing it (probably not) but it would be much
easier to just make the test_quic_client to have 2 iterations.
(ADD_ALL_TESTS(test_quic_client, 2);) In one iteration you would use a
connected socket and in the other unconnected one.
I can give it a try, so we will be able to decide which variant will look better.
…
--
Reply to this email directly, [3]view it on GitHub, or [4]unsubscribe.
You are receiving this because you were assigned. Message ID:
***@***.***>
References
1. #23396 (comment)
2. #23396 (comment)
3. #23396 (review)
4. https://github.com/notifications/unsubscribe-auth/AACSZTZLZBREHJYOXVF6C3DYQ7B3ZAVCNFSM6AAAAABCMDUEU2VHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMYTQNBZGAZTGMRXGU
|
6e44fcd
to
664e8d9
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.
Approving with or without the unresolved nit fixed.
Also please use git commit -a --fixup <commitid>
instead of force pushes to make the incremental review easier.
crypto/bio/bss_dgram.c
Outdated
@@ -573,6 +575,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) | |||
b->shutdown = (int)num; | |||
b->init = 1; | |||
dgram_update_local_addr(b); | |||
if (getpeername(b->num, (struct sockaddr *)&ss, &ss_len) == 0) { |
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.
indentation needs fixing in this file
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, @Sashan it seems your editor needs to be configured to replace tabs with spaces.
crypto/bio/bss_dgram.c
Outdated
data = (bio_dgram_data *)b->ptr; | ||
if (data->connected == 0) { | ||
/* macOS requires msg_namelen be 0 if msg_name is NULL */ | ||
mh->msg_name = msg->peer != NULL ? &msg->peer->sa : NULL; |
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.
indentation
crypto/bio/bss_dgram.c
Outdated
else | ||
mh->msg_namelen = 0; | ||
} else { | ||
mh->msg_name = NULL; |
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.
indentation
test/quic_client_test.c
Outdated
htons(port)))) | ||
goto err; | ||
} else { | ||
c_fd = fd_arg; |
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.
indentation also in this file
This PR is in a state where it requires action by @openssl/committers but the last update was 30 days ago |
current `translate_msg()` function attempts to set `->msg_name` (and `->msg_namelen`) with `BIO`'s peer name (connection destination) regardless if underlying socket is connected or not. Such implementation uncovers differences in socket implementation between various OSes. As we have learned hard way `sendmsg()` and `sendmmsg()` on `OpenBSD` and (`MacOS` too) fail to send messages with `->msg_name` being set on connected socket. In such case the caller receives `EISCON` errro. I think `translate_msg()` caller should provide a hint to indicate whether we deal with connected (or un-connected) socket. For connected sockets the peer's name should not be set/filled by `translate_msg()`. On the other hand if socket is un-connected, then `translate_msg()` must populate `->msg_name` and `->msg_namelen` members. The caller can use `getpeername(2)` to see if socket is connected. If `getpeername()` succeeds then we must be dealing with connected socket and `translate_msg()` must not set `->msg_name` and `->msg_namelen` members. If `getpeername(2)` fails, then `translate_msg()` must provide peer's name (destination address) in `->msg_name` and set `->msg_namelen` accordingly. The propposed fix introduces `is_connected()` function, which applies `getpeername()` to socket bound to `BIO` instance. The `dgram_sendmmsg()` uses `is_connected()` as a hint for `translate_msg()` function, so msghdr gets initialized with respect to socket state. The change also modifies existing `test/quic_client_test.c` so it also covers the case of connected socket. To keep things simple we can introduce optional argument `connect_first` to `./quic_client_test` function. Without `connect_first` the test run as usual. With `connect_first` the test creates and connects socket first. Then it passes such socket to `BIO` sub-system to perform `QUIC` connect test as usual. Fixes openssl#23251
- fixes tabs vs. spaces pointed by hlandau
This pull request is ready to merge |
Merged to the master, 3.3 and 3.2 branches. Thank you. |
current `translate_msg()` function attempts to set `->msg_name` (and `->msg_namelen`) with `BIO`'s peer name (connection destination) regardless if underlying socket is connected or not. Such implementation uncovers differences in socket implementation between various OSes. As we have learned hard way `sendmsg()` and `sendmmsg()` on `OpenBSD` and (`MacOS` too) fail to send messages with `->msg_name` being set on connected socket. In such case the caller receives `EISCON` errro. I think `translate_msg()` caller should provide a hint to indicate whether we deal with connected (or un-connected) socket. For connected sockets the peer's name should not be set/filled by `translate_msg()`. On the other hand if socket is un-connected, then `translate_msg()` must populate `->msg_name` and `->msg_namelen` members. The caller can use `getpeername(2)` to see if socket is connected. If `getpeername()` succeeds then we must be dealing with connected socket and `translate_msg()` must not set `->msg_name` and `->msg_namelen` members. If `getpeername(2)` fails, then `translate_msg()` must provide peer's name (destination address) in `->msg_name` and set `->msg_namelen` accordingly. The propposed fix introduces `is_connected()` function, which applies `getpeername()` to socket bound to `BIO` instance. The `dgram_sendmmsg()` uses `is_connected()` as a hint for `translate_msg()` function, so msghdr gets initialized with respect to socket state. The change also modifies existing `test/quic_client_test.c` so it also covers the case of connected socket. To keep things simple we can introduce optional argument `connect_first` to `./quic_client_test` function. Without `connect_first` the test run as usual. With `connect_first` the test creates and connects socket first. Then it passes such socket to `BIO` sub-system to perform `QUIC` connect test as usual. Fixes #23251 Reviewed-by: Neil Horman <nhorman@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #23396) (cherry picked from commit c062403)
current `translate_msg()` function attempts to set `->msg_name` (and `->msg_namelen`) with `BIO`'s peer name (connection destination) regardless if underlying socket is connected or not. Such implementation uncovers differences in socket implementation between various OSes. As we have learned hard way `sendmsg()` and `sendmmsg()` on `OpenBSD` and (`MacOS` too) fail to send messages with `->msg_name` being set on connected socket. In such case the caller receives `EISCON` errro. I think `translate_msg()` caller should provide a hint to indicate whether we deal with connected (or un-connected) socket. For connected sockets the peer's name should not be set/filled by `translate_msg()`. On the other hand if socket is un-connected, then `translate_msg()` must populate `->msg_name` and `->msg_namelen` members. The caller can use `getpeername(2)` to see if socket is connected. If `getpeername()` succeeds then we must be dealing with connected socket and `translate_msg()` must not set `->msg_name` and `->msg_namelen` members. If `getpeername(2)` fails, then `translate_msg()` must provide peer's name (destination address) in `->msg_name` and set `->msg_namelen` accordingly. The propposed fix introduces `is_connected()` function, which applies `getpeername()` to socket bound to `BIO` instance. The `dgram_sendmmsg()` uses `is_connected()` as a hint for `translate_msg()` function, so msghdr gets initialized with respect to socket state. The change also modifies existing `test/quic_client_test.c` so it also covers the case of connected socket. To keep things simple we can introduce optional argument `connect_first` to `./quic_client_test` function. Without `connect_first` the test run as usual. With `connect_first` the test creates and connects socket first. Then it passes such socket to `BIO` sub-system to perform `QUIC` connect test as usual. Fixes #23251 Reviewed-by: Neil Horman <nhorman@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #23396) (cherry picked from commit c062403)
current `translate_msg()` function attempts to set `->msg_name` (and `->msg_namelen`) with `BIO`'s peer name (connection destination) regardless if underlying socket is connected or not. Such implementation uncovers differences in socket implementation between various OSes. As we have learned hard way `sendmsg()` and `sendmmsg()` on `OpenBSD` and (`MacOS` too) fail to send messages with `->msg_name` being set on connected socket. In such case the caller receives `EISCON` errro. I think `translate_msg()` caller should provide a hint to indicate whether we deal with connected (or un-connected) socket. For connected sockets the peer's name should not be set/filled by `translate_msg()`. On the other hand if socket is un-connected, then `translate_msg()` must populate `->msg_name` and `->msg_namelen` members. The caller can use `getpeername(2)` to see if socket is connected. If `getpeername()` succeeds then we must be dealing with connected socket and `translate_msg()` must not set `->msg_name` and `->msg_namelen` members. If `getpeername(2)` fails, then `translate_msg()` must provide peer's name (destination address) in `->msg_name` and set `->msg_namelen` accordingly. The propposed fix introduces `is_connected()` function, which applies `getpeername()` to socket bound to `BIO` instance. The `dgram_sendmmsg()` uses `is_connected()` as a hint for `translate_msg()` function, so msghdr gets initialized with respect to socket state. The change also modifies existing `test/quic_client_test.c` so it also covers the case of connected socket. To keep things simple we can introduce optional argument `connect_first` to `./quic_client_test` function. Without `connect_first` the test run as usual. With `connect_first` the test creates and connects socket first. Then it passes such socket to `BIO` sub-system to perform `QUIC` connect test as usual. Fixes #23251 Reviewed-by: Neil Horman <nhorman@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #23396)
current
translate_msg()
function attempts to set->msg_name
(and->msg_namelen
) withBIO
's peer name (connection destination) regardless if underlying socket is connected or not. Such implementation uncovers differences in socket implementation between various OSes.As we have learned hard way
sendmsg()
andsendmmsg()
onOpenBSD
and (MacOS
too) fail to send messages with->msg_name
being set on connected socket. In such case the caller receivesEISCON
errro.I think
translate_msg()
caller should provide a hint to indicate whether we deal with connected (or un-connected) socket. For connected sockets the peer's name should not be set/filled bytranslate_msg()
. On the other hand if socket is un-connected, thentranslate_msg()
must populate->msg_name
and->msg_namelen
members.The caller can use
getpeername(2)
to see if socket is connected. Ifgetpeername()
succeeds then we must be dealing with connected socket andtranslate_msg()
must not set->msg_name
and->msg_namelen
members. Ifgetpeername(2)
fails, thentranslate_msg()
must provide peer's name (destination address) in->msg_name
and set->msg_namelen
accordingly.The propposed fix introduces
is_connected()
function, which appliesgetpeername()
to socket bound toBIO
instance. Thedgram_sendmmsg()
usesis_connected()
as a hint fortranslate_msg()
function, so msghdr gets initialized with respect to socket state.The change also modifies existing
test/quic_client_test.c
so it also covers the case of connected socket. To keep things simple we can introduce optional argumentconnect_first
to./quic_client_test
function. Withoutconnect_first
the test run as usual. Withconnect_first
the test creates and connects socket first. Then it passes such socket toBIO
sub-system to performQUIC
connect test as usual.Fixes #23251
Checklist