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

request-response: Throttled can not count its receive budget properly. #1706

Closed
twittner opened this issue Aug 17, 2020 · 1 comment
Closed
Labels

Comments

@twittner
Copy link
Contributor

In libp2p-request-response there is a Throttled type which internally maintains counters for inbound and outbound requests per peer and limits their number. For inbound requests, it decrements its receive budget by 1 when receiving a RequestResponseHandlerEvent::Request from its inner RequestResponse behaviour. This budget should increase again, either when the request has been answered via Throttled::send_response, or when the request processing has timed out. The problem is that Throttled can not perform this increment correctly.

If it increments on a RequestResponseHandlerEvent::InboundTimeout it can not know if this timeout corresponds to a previously seen RequestResponseHandlerEvent::Request, because the timeout can also happen when the remote has not finished sending the request which would not cause a Request event. If it does not increment here it relies on the application to eventually invoke Throttled::send_response which is not guaranteed.

If we would only increment the budget in Throttled::send_response if sending over the oneshot channel succeeds (indicating that the upgrade is still in progress because the oneshot receiver has not been dropped yet), and otherwise increment on a timeout event, we are subject to a race condition because even after a successful send, the next poll of the future may determine first that the time is up and cause a timeout which makes us increment twice.

The proper solution to this is to attach an ID to inbound requests and errors, such as timeouts. This would allow Throttled to maintain a set of current requests and increment only if the ID is a element of this set. Unfortunately the ProtocolsHandler trait does not provide a way to attach information to inbound upgrades like it does for outbound ones.

@twittner twittner added the bug label Aug 17, 2020
twittner added a commit to twittner/rust-libp2p that referenced this issue Aug 18, 2020
Can be enabled again after libp2p#1706 is resolved.
twittner added a commit to twittner/rust-libp2p that referenced this issue Aug 18, 2020
Can be enabled again after libp2p#1706 is resolved.
romanb added a commit that referenced this issue Aug 18, 2020
Can be enabled again after #1706 is resolved.

Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
@romanb
Copy link
Contributor

romanb commented Sep 7, 2020

Resolved / Superseded by #1726.

@romanb romanb closed this as completed Sep 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants