-
Notifications
You must be signed in to change notification settings - Fork 121
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 send for connected UDP socket #4402
base: 25.lts.1+
Are you sure you want to change the base?
Conversation
Added connected flag to handle platform-specific behavior for UDP sockets. This flag enables conditional use of send for connected sockets, preventing errors on platforms like macOS and BSD where sendto may fail with 'already connected' errors.
@jellefoks wdyt ? It looks like a good attempt at fixing this. From another side though, i wonder if this knowledge or fallback behavior shouldn't be living in a calling code, rather than written in Starboard implementation ? E.g. we expect this logic to eventually be working with plain |
The unexpected behavior here is that the upstream posix implementation in (Edit): I gave it some more thought, and I think I understand the root cause here. We may need this approach in the interim. I'll elaborate after the weekend. |
So the root cause is the edge case behavior as described, that the platforms don't behave exactly the same for connected UDP sockets. While connecting UDP sockets theoretically seems to not have a benefit, since UDP is a connectionless protocol, connecting the sockets allows the kernel to do less work per packet, since for connected sockets, the outcome of the packet filtering rule lookup and routing table processing can be memoized and re-used for each subsequent packet. Originally, Cobalt addressed this by simply not connecting UDP sockets, and therefore avoiding the difference in behavior between the platforms. In addition, a hard assert was added to To improve UDP throughput, #4270 was added to allow UDP sockets to be connected, and that PR also removed the hard assert in As a result, when This PR solves that by remembering when a socket is connected, and (for connected UDP sockets) redirecting to use When Cobalt switches from This change does add a struct member and processing for all sockets, so it could have a negative impact on application performance. On the other hand, there may also be a positive impact on performance when Concluding, there are a few options here:
Unless there are any 3p devices that are not linux, I would suggest implementing |
I'd actually try and minimize build-time config of Starboard as much as possible and deprecate the entire concept of QUIRK or such in Starboard 17, i'd consider other options. |
For Starboard 17, this QUIRK can be retired because we will no longer will use |
Perhaps as an alternative, we could revert commit in this PR #4270 since we’ll be migrating to a new version soon that won’t include |
#4270 gives a large performance boost. |
Could we please align on the next steps for this PR? Should we proceed with the current fix, or go with one of the solutions suggested by @jellefoks? |
I think using But instead of using And the reason we need it is an interplay with older Starboard implementations: We connected the UDP socket to improve performance, and since doing that we have to provide an address to So on newer Starboard, we won't need it, because we won't be passing an address to Add a define such as And then write the code under the macro, such that the additional processing and memory is only used when It should only be needed temporarily, we should be able to drop that macro for Starboard 17 and up. |
Okay to go with QUIRK then - @jellefoks i'll leave the actual code review to you |
In this PR #4270, functionality was added to connect a UDP socket. When we call the
SbSocketSendTo
function, which invokessendto
for a UDP socket, the issue arises that if this function is called for a socket that was previously connected, it throws anerrno 56 (already connected)
error on certain platforms, such asmacOS
orBSD
. To address this, we need to call the send function instead ofsendto
. This behavior is platform-specific, as it works fine on Windows or Linux.To resolve this issue, I propose a minimal patch that, depending on whether the UDP socket is already connected, will call either
sendto
or send accordingly. In my opinion, another approach could involve splitting theSbSocketSendTo
function intoSbSocketSendTo
(specifically for non-connected UDP sockets) andSbSocketSend
(for TCP and connected UDP sockets). However, this would require significant code changes.I suggest keeping
SbSocketSendTo
and handling the connected socket state as I’ve done in this PR. In the future, when we fully transition to the POSIX API, we can directly call the appropriate function (send
orsendto
) within theUDPSocketStarboard
class, instead of using wrappers likeSbSocketSendTo
. This transition would also create a clearer interface, as currently, when we callSbSocketSendTo
for an already connected socket, we pass an address that is ultimately unused. I look forward to hearing your feedback.