Skip to content

Commit 721bd2d

Browse files
Frando“ramfox”
andauthored
refactor!: make OutgoingZeroRttConnection implement Clone (#3607)
## Description This allows to get hold of a future that resolves with `ZeroRttStatus` while doing work with the connection (e.g. opening streams) in parallel, without having to give up ownership of the `OutgoingZeroRttConnection`. Used in n0-computer/irpc#81 ## Breaking Changes * `OutgoingZeroRttConnection::handshake_completed()` now takes `&self` instead of `self` ## Notes & open questions <!-- Any notes, remarks or open questions you have to make about the PR. --> ## Change checklist <!-- Remove any that are not relevant. --> - [x] Self-review. - [x] Documentation updates following the [style guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text), if relevant. - [x] Tests if relevant. - [x] All breaking changes documented. - [ ] List all breaking changes in the above "Breaking Changes" section. - [ ] Open an issue or PR on any number0 repos that are affected by this breaking change. Give guidance on how the updates should be handled or do the actual updates themselves. The major ones are: - [ ] [`quic-rpc`](https://github.com/n0-computer/quic-rpc) - [ ] [`iroh-gossip`](https://github.com/n0-computer/iroh-gossip) - [ ] [`iroh-blobs`](https://github.com/n0-computer/iroh-blobs) - [ ] [`dumbpipe`](https://github.com/n0-computer/dumbpipe) - [ ] [`sendme`](https://github.com/n0-computer/sendme) --------- Co-authored-by: “ramfox” <“kasey@n0.computer”>
1 parent 238925a commit 721bd2d

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

iroh/src/endpoint/connection.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use std::{
2626
};
2727

2828
use ed25519_dalek::{VerifyingKey, pkcs8::DecodePublicKey};
29+
use futures_util::{FutureExt, future::Shared};
2930
use iroh_base::EndpointId;
3031
use n0_error::{e, stack_error};
3132
use n0_future::time::Duration;
@@ -396,7 +397,8 @@ impl Connecting {
396397
accepted: ZeroRttAccepted {
397398
inner: zrtt_accepted,
398399
_discovery_drop_guard: self._discovery_drop_guard,
399-
},
400+
}
401+
.shared(),
400402
})
401403
}
402404
Err(inner) => Err(Self {
@@ -524,6 +526,7 @@ impl Future for Accepting {
524526
}
525527
}
526528
}
529+
527530
/// Future that completes when a connection is fully established.
528531
///
529532
/// For clients, the resulting value indicates if 0-RTT was accepted. For servers, the resulting
@@ -560,13 +563,13 @@ impl Future for ZeroRttAccepted {
560563
///
561564
/// Look at the [`OutgoingZeroRttConnection::handshake_completed`] method for
562565
/// more details.
563-
#[derive(Debug)]
566+
#[derive(Debug, Clone)]
564567
pub struct OutgoingZeroRttConnection {
565568
inner: quinn::Connection,
566-
accepted: ZeroRttAccepted,
569+
accepted: Shared<ZeroRttAccepted>,
567570
}
568571

569-
/// Returned from a `OutgoingZeroRttConnection::handshake_complete` method.
572+
/// Returned from [`OutgoingZeroRttConnection::handshake_completed`].
570573
#[derive(Debug)]
571574
pub enum ZeroRttStatus {
572575
/// If the 0-RTT data was accepted, you can continue to use any streams
@@ -598,9 +601,9 @@ impl OutgoingZeroRttConnection {
598601
///
599602
/// Thus, those errors should only occur if someone connects to you with a
600603
/// modified iroh endpoint or with a plain QUIC client.
601-
pub async fn handshake_completed(self) -> Result<ZeroRttStatus, AuthenticationError> {
602-
let accepted = self.accepted.await;
603-
let conn = conn_from_quinn_conn(self.inner)?;
604+
pub async fn handshake_completed(&self) -> Result<ZeroRttStatus, AuthenticationError> {
605+
let accepted = self.accepted.clone().await;
606+
let conn = conn_from_quinn_conn(self.inner.clone())?;
604607

605608
Ok(match accepted {
606609
true => ZeroRttStatus::Accepted(conn),

iroh/src/protocol.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,21 @@ pub trait ProtocolHandler: Send + Sync + std::fmt::Debug + 'static {
159159
///
160160
/// Can be implemented as `async fn on_accepting(&self, accepting: Accepting) -> Result<Connection>`.
161161
///
162-
/// This enables accepting 0-RTT data from clients, among other things.
162+
/// Typically, this method is used as an early interception point to accept
163+
/// or reject a connection.
164+
///
165+
/// However, this method can also be used to implement the accept side of a
166+
/// 0-RTT connection.
167+
///
168+
/// ## 0-RTT
169+
///
170+
/// `ProtocolHandler::on_accepting` allows you to take over the connection
171+
/// state machine early in the handshake processes, by calling [`Accepting::into_0rtt`].
172+
///
173+
/// When working with 0-RTT, you may want to implement all of your protocol
174+
/// logic in `on_accepting`. This is fine because `on_accepting` can handle
175+
/// long-running processes. In this case, the [`ProtocolHandler::accept`] method
176+
/// can simply return `Ok(())`.
163177
fn on_accepting(
164178
&self,
165179
accepting: Accepting,

0 commit comments

Comments
 (0)