Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Iroh Quinn
# n0 Quinn

> This is a fork based on [quinn](https://github.com/quinn-rs/quinn), maintained
> by [n0](https://github.com/n0-computer). Currently published to crates.io under
Expand Down
4 changes: 2 additions & 2 deletions quinn-proto/src/config/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@ impl TransportConfig {
/// Sets the maximum number of nat traversal addresses this endpoint allows the remote to
/// advertise
///
/// Setting this to any nonzero value will enable Iroh's holepunching, loosely based in the Nat
/// Traversal Extension for QUIC, see
/// Setting this to any nonzero value will enable n0's nat traversal protocol, loosely based in
/// the Nat Traversal Extension for QUIC, see
/// <https://www.ietf.org/archive/id/draft-seemann-quic-nat-traversal-02.html>
///
/// This implementation expects the multipath extension to be enabled as well. if not yet
Expand Down
81 changes: 45 additions & 36 deletions quinn-proto/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::{
self, Close, DataBlocked, Datagram, FrameStruct, NewToken, ObservedAddr, StreamDataBlocked,
StreamsBlocked,
},
iroh_hp,
n0_nat_traversal,
packet::{
FixedLengthConnectionIdParser, Header, InitialHeader, InitialPacket, LongType, Packet,
PacketNumber, PartialDecode, SpaceId,
Expand Down Expand Up @@ -309,7 +309,8 @@ pub struct Connection {
// paths. Or a set together with a minimum. Or something.
abandoned_paths: FxHashSet<PathId>,

iroh_hp: iroh_hp::State,
/// State for n0's (<https://n0.computer>) nat traversal protocol.
n0_nat_traversal: n0_nat_traversal::State,
qlog: QlogSink,
}

Expand Down Expand Up @@ -483,8 +484,7 @@ impl Connection {
max_path_id_with_cids: PathId::ZERO,
abandoned_paths: Default::default(),

// iroh's nat traversal
iroh_hp: Default::default(),
n0_nat_traversal: Default::default(),
qlog,
};
if path_validated {
Expand Down Expand Up @@ -2002,7 +2002,7 @@ impl Connection {
buf: &mut Vec<u8>,
path_id: PathId,
) -> Option<Transmit> {
let server_side = self.iroh_hp.server_side_mut().ok()?;
let server_side = self.n0_nat_traversal.server_side_mut().ok()?;
let probe = server_side.next_probe()?;
if !self.paths.get(&path_id)?.data.validated {
// Path is not usable for probing
Expand Down Expand Up @@ -5158,7 +5158,7 @@ impl Connection {
}
}
Frame::AddAddress(addr) => {
let client_state = match self.iroh_hp.client_side_mut() {
let client_state = match self.n0_nat_traversal.client_side_mut() {
Ok(state) => state,
Err(err) => {
return Err(TransportError::PROTOCOL_VIOLATION(format!(
Expand All @@ -5176,7 +5176,7 @@ impl Connection {
Ok(maybe_added) => {
if let Some(added) = maybe_added {
self.events.push_back(Event::NatTraversal(
iroh_hp::Event::AddressAdded(added),
n0_nat_traversal::Event::AddressAdded(added),
));
}
}
Expand All @@ -5186,7 +5186,7 @@ impl Connection {
}
}
Frame::RemoveAddress(addr) => {
let client_state = match self.iroh_hp.client_side_mut() {
let client_state = match self.n0_nat_traversal.client_side_mut() {
Ok(state) => state,
Err(err) => {
return Err(TransportError::PROTOCOL_VIOLATION(format!(
Expand All @@ -5195,15 +5195,14 @@ impl Connection {
}
};
if let Some(removed_addr) = client_state.remove_remote_address(addr) {
self.events
.push_back(Event::NatTraversal(iroh_hp::Event::AddressRemoved(
removed_addr,
)));
self.events.push_back(Event::NatTraversal(
n0_nat_traversal::Event::AddressRemoved(removed_addr),
));
}
}
Frame::ReachOut(reach_out) => {
let ipv6 = self.is_ipv6();
let server_state = match self.iroh_hp.server_side_mut() {
let server_state = match self.n0_nat_traversal.server_side_mut() {
Ok(state) => state,
Err(err) => {
return Err(TransportError::PROTOCOL_VIOLATION(format!(
Expand Down Expand Up @@ -6220,11 +6219,14 @@ impl Connection {
{
let max_local_addresses = max_remotely_allowed_remote_addresses.get();
let max_remote_addresses = max_locally_allowed_remote_addresses.get();
self.iroh_hp =
iroh_hp::State::new(max_remote_addresses, max_local_addresses, self.side());
self.n0_nat_traversal = n0_nat_traversal::State::new(
max_remote_addresses,
max_local_addresses,
self.side(),
);
debug!(
%max_remote_addresses, %max_local_addresses,
"iroh hole punching negotiated"
"n0's nat traversal negotiated"
);

match self.side() {
Expand All @@ -6249,7 +6251,7 @@ impl Connection {
}
}
} else {
debug!("iroh nat traversal enabled for both endpoints, but multipath is missing")
debug!("n0 nat traversal enabled for both endpoints, but multipath is missing")
}
}

Expand Down Expand Up @@ -6604,8 +6606,11 @@ impl Connection {
}

/// Add addresses the local endpoint considers are reachable for nat traversal.
pub fn add_nat_traversal_address(&mut self, address: SocketAddr) -> Result<(), iroh_hp::Error> {
if let Some(added) = self.iroh_hp.add_local_address(address)? {
pub fn add_nat_traversal_address(
&mut self,
address: SocketAddr,
) -> Result<(), n0_nat_traversal::Error> {
if let Some(added) = self.n0_nat_traversal.add_local_address(address)? {
self.spaces[SpaceId::Data].pending.add_address.insert(added);
};
Ok(())
Expand All @@ -6617,8 +6622,8 @@ impl Connection {
pub fn remove_nat_traversal_address(
&mut self,
address: SocketAddr,
) -> Result<(), iroh_hp::Error> {
if let Some(removed) = self.iroh_hp.remove_local_address(address)? {
) -> Result<(), n0_nat_traversal::Error> {
if let Some(removed) = self.n0_nat_traversal.remove_local_address(address)? {
self.spaces[SpaceId::Data]
.pending
.remove_address
Expand All @@ -6628,14 +6633,18 @@ impl Connection {
}

/// Get the current local nat traversal addresses
pub fn get_local_nat_traversal_addresses(&self) -> Result<Vec<SocketAddr>, iroh_hp::Error> {
self.iroh_hp.get_local_nat_traversal_addresses()
pub fn get_local_nat_traversal_addresses(
&self,
) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> {
self.n0_nat_traversal.get_local_nat_traversal_addresses()
}

/// Get the currently advertised nat traversal addresses by the server
pub fn get_remote_nat_traversal_addresses(&self) -> Result<Vec<SocketAddr>, iroh_hp::Error> {
pub fn get_remote_nat_traversal_addresses(
&self,
) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> {
Ok(self
.iroh_hp
.n0_nat_traversal
.client_side()?
.get_remote_nat_traversal_addresses())
}
Expand Down Expand Up @@ -6683,14 +6692,14 @@ impl Connection {
pub fn initiate_nat_traversal_round(
&mut self,
now: Instant,
) -> Result<Vec<SocketAddr>, iroh_hp::Error> {
) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> {
if self.state.is_closed() {
return Err(iroh_hp::Error::Closed);
return Err(n0_nat_traversal::Error::Closed);
}

let ipv6 = self.is_ipv6();
let client_state = self.iroh_hp.client_side_mut()?;
let iroh_hp::NatTraversalRound {
let client_state = self.n0_nat_traversal.client_side_mut()?;
let n0_nat_traversal::NatTraversalRound {
new_round,
reach_out_at,
addresses_to_probe,
Expand Down Expand Up @@ -6737,7 +6746,7 @@ impl Connection {
probed_addresses.push(remote);
}
Err(e) => {
self.iroh_hp
self.n0_nat_traversal
.client_side_mut()
.expect("validated")
.report_in_continuation(id, e);
Expand All @@ -6749,11 +6758,11 @@ impl Connection {
if let Some(err) = err {
// We failed to probe any addresses, bail out
if probed_addresses.is_empty() {
return Err(iroh_hp::Error::Multipath(err));
return Err(n0_nat_traversal::Error::Multipath(err));
}
}

self.iroh_hp
self.n0_nat_traversal
.client_side_mut()
.expect("connection side validated")
.set_round_path_ids(path_ids);
Expand All @@ -6767,10 +6776,10 @@ impl Connection {
/// successfully open.
fn continue_nat_traversal_round(&mut self, now: Instant) -> Option<bool> {
let ipv6 = self.is_ipv6();
let client_state = self.iroh_hp.client_side_mut().ok()?;
let client_state = self.n0_nat_traversal.client_side_mut().ok()?;
let (id, address) = client_state.continue_nat_traversal_round(ipv6)?;
let open_result = self.open_nat_traversal_path(now, address);
let client_state = self.iroh_hp.client_side_mut().expect("validated");
let client_state = self.n0_nat_traversal.client_side_mut().expect("validated");
match open_result {
Ok(None) => Some(true),
Ok(Some((path_id, _remote))) => {
Expand Down Expand Up @@ -7042,8 +7051,8 @@ pub enum Event {
DatagramsUnblocked,
/// (Multi)Path events
Path(PathEvent),
/// Iroh's nat traversal events
NatTraversal(iroh_hp::Event),
/// n0's nat traversal events
NatTraversal(n0_nat_traversal::Event),
}

impl From<PathEvent> for Event {
Expand Down
2 changes: 1 addition & 1 deletion quinn-proto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ mod address_discovery;
mod token_memory_cache;
pub use token_memory_cache::TokenMemoryCache;

pub mod iroh_hp;
pub mod n0_nat_traversal;

// Deal with time
#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! iroh NAT Traversal
//! n0's (<https://n0.computer>) NAT Traversal protocol implementation.

use std::{
collections::hash_map::Entry,
Expand All @@ -25,7 +25,7 @@ pub enum Error {
#[error("Not allowed for this endpoint's connection side")]
WrongConnectionSide,
/// The extension was not negotiated
#[error("Iroh's nat traversal was not negotiated")]
#[error("n0's nat traversal was not negotiated")]
ExtensionNotNegotiated,
/// Not enough addresses to complete the operation
#[error("Not enough addresses")]
Expand Down Expand Up @@ -63,7 +63,7 @@ pub enum Event {
AddressRemoved(SocketAddr),
}

/// State kept for Iroh's nat traversal
/// State kept for n0's nat traversal
#[derive(Debug, Default)]
pub(crate) enum State {
#[default]
Expand Down Expand Up @@ -91,7 +91,7 @@ pub(crate) struct ClientState {
/// Candidate addresses the local client reports as potentially reachable, to use for nat
/// traversal attempts.
local_addresses: FxHashSet<IpPort>,
/// Current nat holepunching round.
/// Current nat traversal round.
round: VarInt,
/// [`PathId`]s used to probe remotes assigned to this round.
round_path_ids: Vec<PathId>,
Expand Down Expand Up @@ -296,7 +296,7 @@ pub(crate) struct ServerState {
local_addresses: FxHashMap<IpPort, VarInt>,
/// The next id to use for local addresses sent to the client.
next_local_addr_id: VarInt,
/// Current nat holepunching round
/// Current nat traversal round
///
/// Servers keep track of the client's most recent round and cancel probing related to previous
/// rounds.
Expand Down
10 changes: 5 additions & 5 deletions quinn-proto/src/tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,36 +708,36 @@ impl ConnPair {
&mut self,
side: Side,
address: SocketAddr,
) -> Result<(), iroh_hp::Error> {
) -> Result<(), n0_nat_traversal::Error> {
self.conn_mut(side).add_nat_traversal_address(address)
}

pub(super) fn remove_nat_traversal_address(
&mut self,
side: Side,
address: SocketAddr,
) -> Result<(), iroh_hp::Error> {
) -> Result<(), n0_nat_traversal::Error> {
self.conn_mut(side).remove_nat_traversal_address(address)
}

pub(super) fn get_local_nat_traversal_addresses(
&self,
side: Side,
) -> Result<Vec<SocketAddr>, iroh_hp::Error> {
) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> {
self.conn(side).get_local_nat_traversal_addresses()
}

pub(super) fn get_remote_nat_traversal_addresses(
&self,
side: Side,
) -> Result<Vec<SocketAddr>, iroh_hp::Error> {
) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> {
self.conn(side).get_remote_nat_traversal_addresses()
}

pub(super) fn initiate_nat_traversal_round(
&mut self,
side: Side,
) -> Result<Vec<SocketAddr>, iroh_hp::Error> {
) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> {
let now = self.pair.time;
self.conn_mut(side).initiate_nat_traversal_round(now)
}
Expand Down
12 changes: 6 additions & 6 deletions quinn-proto/src/transport_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ impl TransportParameters {
w.write(val);
}
}
TransportParameterId::IrohNatTraversal => {
TransportParameterId::N0NatTraversal => {
if let Some(val) = self.max_remote_nat_traversal_addresses {
w.write_var(id as u64);
w.write(VarInt(1));
Expand Down Expand Up @@ -548,7 +548,7 @@ impl TransportParameters {

params.initial_max_path_id = Some(value);
}
TransportParameterId::IrohNatTraversal => {
TransportParameterId::N0NatTraversal => {
if params.max_remote_nat_traversal_addresses.is_some() {
return Err(Error::Malformed);
}
Expand Down Expand Up @@ -731,8 +731,8 @@ pub(crate) enum TransportParameterId {
InitialMaxPathId = 0x3e,

// inspired by https://www.ietf.org/archive/id/draft-seemann-quic-nat-traversal-02.html,
// simplified to iroh's needs
IrohNatTraversal = 0x3d7f91120401,
// simplified to n0's own protocol.
N0NatTraversal = 0x3d7f91120401,
}

impl TransportParameterId {
Expand Down Expand Up @@ -761,7 +761,7 @@ impl TransportParameterId {
Self::MinAckDelayDraft07,
Self::ObservedAddr,
Self::InitialMaxPathId,
Self::IrohNatTraversal,
Self::N0NatTraversal,
];
}

Expand Down Expand Up @@ -803,7 +803,7 @@ impl TryFrom<u64> for TransportParameterId {
id if Self::MinAckDelayDraft07 == id => Self::MinAckDelayDraft07,
id if Self::ObservedAddr == id => Self::ObservedAddr,
id if Self::InitialMaxPathId == id => Self::InitialMaxPathId,
id if Self::IrohNatTraversal == id => Self::IrohNatTraversal,
id if Self::N0NatTraversal == id => Self::N0NatTraversal,
_ => return Err(()),
};
Ok(param)
Expand Down
Loading
Loading