A cancelled dial stops instead of connecting to the next address - #113
Merged
Merged
Conversation
The connect loop caught every error, Canceled included, and moved on to the next resolved address, whose connect the cancellation could no longer interrupt. A caller bounding dial by cancelling it still waited out the TCP connect timeout against a host that never answers the SYN. Canceled now returns at once. getaddrinfo is also asked for stream sockets only. Without hints it listed every address once per socket type, so each was tried twice. The dial documentation says how to bound it, and a test pins that a dial waiting on a silent peer can be cancelled and frees what it allocated. Closes #112.
Carries #111 and the fix on this branch: a dial can be abandoned cleanly, whether it is cancelled while connecting, fails after the TLS handshake, or is cancelled while waiting for the websocket upgrade.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #112.
dialtakes no deadline, so the way to bound it is to run it withio.concurrentand cancel it. Two things stopped that from working against a relay whose host never answers the SYN:Canceledincluded, and moved on to the next resolved address. Once a task has been cancelled, its later I/O can no longer be interrupted, so that next connect ran to its own timeout.Cancelednow returns at once.getaddrinfowas called without hints and listed every address once per socket type, so each address was tried twice. It is now asked for stream sockets only.The
dialdocumentation now says how to bound it, and that the name lookup is the one step a cancel cannot interrupt, since it is a plain libc call.Verified
a dial waiting on a silent peer can be cancelled, and frees what it maderuns in CI. It dials a local listener that never answers the upgrade, cancels after 100 ms, and requires the cancel to land promptly with nothing leaked.The SYN case needs a listener whose backlog is full so the kernel drops the SYN, which is not something to do in CI. Driven by hand against that, with a 2 second deadline, under a leak-checking allocator:
TimeoutCanceledA peer that accepts and stays silent cancels in 0 ms on both builds, which the new test pins.
All 211 tests pass.
Release
The last commit bumps the version to 0.14.4, carrying this and #111.