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

feat(webrtc): implement fin ack #5687

Open
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

tesol2y090
Copy link

@tesol2y090 tesol2y090 commented Nov 24, 2024

Description

Implements FIN_ACK support for WebRTC streams to ensure reliable closure handshaking as specified in the WebRTC spec. This adds:

  • FIN_ACK flag handling in state machine
  • Timeout mechanism for FIN_ACK wait
  • Proper state transitions for graceful closure
  • webrtc: support FIN_ACK #4600

Notes & open questions

  • Using Instant for deadline tracking instead of tokio timer to avoid extra dependencies
  • Timeout is set to 10 seconds - should this be configurable?
  • State machine ensures FIN_ACK is only sent/processed in appropriate states

Change checklist

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
    • Added documentation for FIN_ACK related functions
    • Updated state machine documentation
  • I have added tests that prove my fix is effective or that my feature works
    • Added tests for FIN_ACK state transitions
    • Added tests for timeout behavior
    • Added tests for edge cases

@tesol2y090 tesol2y090 changed the title Feat/webrtc fin ack [WIP] Feat/webrtc fin ack Nov 24, 2024
@tesol2y090 tesol2y090 changed the title [WIP] Feat/webrtc fin ack Feat/webrtc fin ack Dec 1, 2024
@tesol2y090 tesol2y090 marked this pull request as ready for review December 1, 2024 08:43
@tesol2y090 tesol2y090 changed the title Feat/webrtc fin ack feat(webrtc): implement fin ack Dec 1, 2024
@elenaf9 elenaf9 self-requested a review December 10, 2024 11:08
@elenaf9 elenaf9 linked an issue Dec 10, 2024 that may be closed by this pull request
@elenaf9
Copy link
Contributor

elenaf9 commented Dec 10, 2024

Thank you for your contribution @tesol2y090 and sorry for the delay here! Will try to give this a review in the next days.

Copy link
Contributor

@elenaf9 elenaf9 left a comment

Choose a reason for hiding this comment

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

Sorry for the delay here @tesol2y090.

Some first comments.

misc/webrtc-utils/CHANGELOG.md Outdated Show resolved Hide resolved
Comment on lines 257 to 265
// Check if we've received FIN_ACK or deadline has passed
if self.state.fin_ack_received()
|| self
.fin_ack_deadline
.is_some_and(|deadline| Instant::now() >= deadline)
{
if !self.state.fin_ack_received() {
tracing::warn!("FIN_ACK timeout, forcing close");
}
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 do early returns instead of nested if-statements here?

.expect("to not close twice")
.send(GracefullyClosed {});
// Check if we've received FIN_ACK or deadline has passed
if self.state.fin_ack_received()
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure about this, but don't we need to somehow continue reading here to be able to receive the FIN_ACK?

With AsyncWriteExt for instance a future will be created that only returns after poll_close succeeded i.e. no concurrent call to poll_read happens. With the current impl, I don't think a FIN_ACK will ever be read in that case?

On the other hand, we'd then have to discard the read messages or buffer them. Not sure how this is handled e.g. in QUIC, or in the go implementation.

Comment on lines +57 to +58
/// FIN_ACK timeout
const FIN_ACK_TIMEOUT: Duration = Duration::from_secs(10);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this number part of specs or was discussed somewhere?
This is time that we'll have to wait each time when closing a stream if the remote doesn't support FIN_ACK right?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, that's right. I follow the go-libp2p implementation. https://github.com/libp2p/go-libp2p/blob/master/p2p/transport/webrtc/stream.go#L45

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

webrtc: support FIN_ACK
2 participants