Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Throw SocketAddressError (cf. fatalError) in SocketAddress.convert for unknown address family #2477

Conversation

simonjbeaumont
Copy link
Contributor

Motivation:

NIO currently fails with fatalError when converting a sockaddr_storage if it is not one of the socket addresses that NIO explicitly supports (AF_UNIX, AF_INET, or AF_INET6). However, since NIO offers API that allows users to create sockets out of band (withConnectedSocket(_:) and withBoundSocket(_:)), it's possible a user has provided a socket of a different family.

Modifications:

Instead of crashing, SocketAddress.convert() now throws SocketAddressError.unsupported, and whether to crash (or just propagate the error) is moved up the stack.

Result:

It's possible to bootstrap clients and servers with other kinds of sockets, even if NIO cannot convert them to one of the SocketAddress cases it knows about.

…r unknown address family

Signed-off-by: Si Beaumont <beaumont@apple.com>
Signed-off-by: Si Beaumont <beaumont@apple.com>
@Lukasa Lukasa added the 🔨 semver/patch No public API change. label Jul 18, 2023
let address: SocketAddress = self.sockaddrVector[i].convert()
let address: SocketAddress
do { address = try self.sockaddrVector[i].convert() }
catch { fatalError("Socket address conversion failed.") }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer try!.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know—I assumed that try! would be discouraged in review. Although I appreciate that all we do here is fail with a different string.

Changed in 805f1ca.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try! falls into the same bucket as !, which is that you need to write down why you know it won't crash in a comment.

let address: SocketAddress = self.sockaddrVector[i].convert()
let address: SocketAddress
do { address = try self.sockaddrVector[i].convert() }
catch { fatalError("Socket address conversion failed.") }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More broadly, should we tolerate this error in this location?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great question.

I suppose we have to choose between failing hard or silently dropping these messages, given that we will be unable to construct an AddressedEnvelope without a SocketAddress.

I opted to fail because:

  1. It's closest to the behaviour before this patch—where it would have still crashed, just inside convert().
  2. Above these lines there are a number of precondition checks so failing hard seemed to be "the done thing" here.

Happy to revisit though if you think this is the wrong choice here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a third option, which is to throw. The preconditions above are correctness checks, but this is not. Throwing here is consistent with the scalar read path.

Copy link
Contributor Author

@simonjbeaumont simonjbeaumont Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -651,7 +651,7 @@ final class DatagramChannel: BaseSocketChannel<Socket> {
metadata = nil
}

let msg = AddressedEnvelope(remoteAddress: rawAddress.convert(),
let msg = AddressedEnvelope(remoteAddress: try rawAddress.convert(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we lift the call to convert higher in the .processed block? Let's not trigger any side-effects until we know we're going to process the read.

Copy link
Contributor Author

@simonjbeaumont simonjbeaumont Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 48d98b8.

Signed-off-by: Si Beaumont <beaumont@apple.com>
Signed-off-by: Si Beaumont <beaumont@apple.com>
@simonjbeaumont simonjbeaumont force-pushed the sb-throw-non-fatal-error-for-unknown-sockets branch from f7ca742 to 48d98b8 Compare July 18, 2023 13:44
Signed-off-by: Si Beaumont <beaumont@apple.com>
@simonjbeaumont
Copy link
Contributor Author

@swift-server-bot test this please

@simonjbeaumont simonjbeaumont requested a review from Lukasa July 20, 2023 08:54
Signed-off-by: Si Beaumont <beaumont@apple.com>
@FranzBusch
Copy link
Member

5.9 allocation regression is known and to be investigated
nightly crash is also known and fixed in Swift already.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
🔨 semver/patch No public API change.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants