Skip to content
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: [Network] connections can use an invalid socket due to a race condition #9731

Merged
merged 1 commit into from Dec 4, 2021

Conversation

TrueBrain
Copy link
Member

@TrueBrain TrueBrain commented Dec 4, 2021

Motivation / Problem

Fixes #9730.

Description

As by commit message:

A race condition happens when an IPv6 connection takes more than
250ms to report an error, but does return before the IPv4 connection
is established.
In result, an invalid socket might be used for that connection.

Bit difficult story:

  • You have an IPv4 and IPv6 connection, and are connecting to an IPv4+IPv6 server
  • You try IPv6 first, but it takes more than 250ms to get a reply from the network stack
  • Happy Eyeballs kicks in, and IPv4 connection is attempted too
  • The IPv6 responds before the IPv4 does, and says: no connection

The code never assumed this situation to happen. As such, it didn't check if any of the remaining connections was actually connected, but instead assumed at least one of the remaining was. This in result means that connected_socket became INVALID_SOCKET and things went from bad to worse from there.

So now instead, check if any non-error'd socket is in writable state. If so, only than safely assume one of the sockets is connected.

The if (this->sockets.empty()) { meant this worked for most people, as it is rare two connections are actually pending, and the first reporting an error before the second manages to connect. Just when timing was bad, it broke.
(Normally IPv6 just times out, which takes a few seconds. The IPv4 attempt will succeed well before that, and that case would work perfectly fine).

The if (this->sockets.empty()) { can safely be removed, as the start of the function does exactly this already. So next CheckActivity the exact same code is executed and starts another connection attempt if needed. Less code duplication is beter :)

Limitations

None

Checklist for review

Some things are not automated, and forgotten often. This list is a reminder for the reviewers.

  • The bug fix is important enough to be backported? (label: 'backport requested')
  • This PR touches english.txt or translations? Check the guidelines
  • This PR affects the save game format? (label 'savegame upgrade')
  • This PR affects the GS/AI API? (label 'needs review: Script API')
    • ai_changelog.hpp, gs_changelog.hpp need updating.
    • The compatibility wrappers (compat_*.nut) need updating.
  • This PR affects the NewGRF API? (label 'needs review: NewGRF')

@TrueBrain TrueBrain added the backport requested This PR should be backport to current release (RC / stable) label Dec 4, 2021
frosch123
frosch123 previously approved these changes Dec 4, 2021
…ver connections

When an IPv6 connection takes more than 250ms to report an error,
but does return before the IPv4 connection is established, can cause
an invalid socket to be used for a server connection.
@TrueBrain TrueBrain changed the title Fix: [Network] bad timing can cause invalid socket to be used for server connections Fix: [Network] race condition causes invalid socket to be used for connections Dec 4, 2021
@TrueBrain TrueBrain changed the title Fix: [Network] race condition causes invalid socket to be used for connections Fix: [Network] race condition causes connection to use an invalid socket Dec 4, 2021
@TrueBrain TrueBrain changed the title Fix: [Network] race condition causes connection to use an invalid socket Fix: [Network] connections can use an invalid socket due to a race condition Dec 4, 2021
@RealDeuce
Copy link

Comfirmed that with this fix, issue #9730 did not happen 10/10 times. It appears to be good. :shipit:

@TrueBrain TrueBrain merged commit ea4f6bb into OpenTTD:master Dec 4, 2021
@TrueBrain TrueBrain deleted the fix-happy-eyeballs branch December 4, 2021 19:56
@TrueBrain TrueBrain added backported This PR is backported to a current release (RC / stable) and removed backport requested This PR should be backport to current release (RC / stable) labels Jan 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backported This PR is backported to a current release (RC / stable)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: crash on opening Multiplayer
3 participants