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(relay): emit external address on reservation #4809

Merged
merged 26 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4a9932a
feat: Implement external address on successful reservation
dariusc93 Nov 2, 2023
b8aa098
chore: Emit event before reservation accepted event
dariusc93 Nov 2, 2023
02aff86
fix: remove extra protocol
dariusc93 Nov 2, 2023
441fccf
chore: Update CHANGELOG.md
dariusc93 Nov 2, 2023
f21b7a6
Merge remote-tracking branch 'origin/master' into feat/relay-external…
dariusc93 Nov 3, 2023
82b7e7a
Merge branch 'master' into feat/relay-external-addr
dariusc93 Nov 6, 2023
cbecab9
chore: Update test
dariusc93 Nov 6, 2023
c3042f9
Merge branch 'master' into feat/relay-external-addr
dariusc93 Nov 9, 2023
66c4fe7
chore: Check external addr
dariusc93 Nov 9, 2023
b6c7347
chore: Use event to get relay address provided
dariusc93 Nov 9, 2023
5f91043
chore: Update dcutr test
dariusc93 Nov 9, 2023
b775b9c
chore: Format code
dariusc93 Nov 9, 2023
7b15110
chore: Update Cargo.toml
dariusc93 Nov 9, 2023
84f59c9
chore: Check client address
dariusc93 Nov 9, 2023
604bba7
chore: Emit event is reservation isnt renewed
dariusc93 Nov 9, 2023
deb3182
chore: Check renewal in test
dariusc93 Nov 9, 2023
8982465
chore: Check renewal
dariusc93 Nov 9, 2023
e9372d8
Update protocols/relay/CHANGELOG.md
dariusc93 Nov 9, 2023
8ac345c
Merge branch 'master' into feat/relay-external-addr
dariusc93 Nov 13, 2023
b121cd6
Merge branch 'feat/relay-external-addr' of github.com:dariusc93/rust-…
dariusc93 Nov 13, 2023
17e7a8e
chore: check if reservation exist prior to emitting event
dariusc93 Nov 13, 2023
b781678
fix: Correct package version
dariusc93 Nov 13, 2023
9e18f6b
chore: use a single map to track reservation
dariusc93 Nov 14, 2023
cc0c26b
chore: Correct naming
dariusc93 Nov 14, 2023
f9f2ee6
Don't use `matches!` if not necessary
thomaseizinger Nov 14, 2023
396fb8a
Merge branch 'master' into feat/relay-external-addr
mergify[bot] Nov 14, 2023
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 Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ libp2p-ping = { version = "0.44.0", path = "protocols/ping" }
libp2p-plaintext = { version = "0.41.0", path = "transports/plaintext" }
libp2p-pnet = { version = "0.24.0", path = "transports/pnet" }
libp2p-quic = { version = "0.10.1", path = "transports/quic" }
libp2p-relay = { version = "0.17.0", path = "protocols/relay" }
libp2p-relay = { version = "0.17.1", path = "protocols/relay" }
libp2p-rendezvous = { version = "0.14.0", path = "protocols/rendezvous" }
libp2p-request-response = { version = "0.26.0", path = "protocols/request-response" }
libp2p-server = { version = "0.12.4", path = "misc/server" }
Expand Down
3 changes: 3 additions & 0 deletions protocols/dcutr/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ async fn wait_for_reservation(
}
SwarmEvent::Behaviour(ClientEvent::Identify(_)) => {}
SwarmEvent::NewExternalAddrCandidate { .. } => {}
SwarmEvent::ExternalAddrConfirmed { address } if !is_renewal => {
assert_eq!(address, client_addr);
}
e => panic!("{e:?}"),
}
}
Expand Down
6 changes: 5 additions & 1 deletion protocols/relay/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## 0.17.0

## 0.17.1 - unreleased
- Automatically register relayed addresses as external addresses.
See [PR 4809](https://github.com/libp2p/rust-lib2pp/pulls/4809).

## 0.17.0
- Don't close connections on protocol failures within the relay-server.
To achieve this, error handling was restructured:
- `libp2p::relay::outbound::stop::FatalUpgradeError` has been removed.
Expand Down
2 changes: 1 addition & 1 deletion protocols/relay/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "libp2p-relay"
edition = "2021"
rust-version = { workspace = true }
description = "Communications relaying for libp2p"
version = "0.17.0"
version = "0.17.1"
authors = ["Parity Technologies <[email protected]>", "Max Inden <[email protected]>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"
Expand Down
71 changes: 63 additions & 8 deletions protocols/relay/src/priv_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use futures::future::{BoxFuture, FutureExt};
use futures::io::{AsyncRead, AsyncWrite};
use futures::ready;
use futures::stream::StreamExt;
use libp2p_core::multiaddr::Protocol;
use libp2p_core::{Endpoint, Multiaddr};
use libp2p_identity::PeerId;
use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm};
Expand Down Expand Up @@ -69,6 +70,12 @@ pub enum Event {
},
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum ReservationStatus {
Pending,
Confirmed,
}

/// [`NetworkBehaviour`] implementation of the relay client
/// functionality of the circuit relay v2 protocol.
pub struct Behaviour {
Expand All @@ -79,6 +86,11 @@ pub struct Behaviour {
/// connection.
directly_connected_peers: HashMap<PeerId, Vec<ConnectionId>>,

/// Stores the address of a pending or confirmed reservation.
///
/// This is indexed by the [`ConnectionId`] to a relay server and the address is the `/p2p-circuit` address we reserved on it.
reservation_addresses: HashMap<ConnectionId, (Multiaddr, ReservationStatus)>,

/// Queue of actions to return when polled.
queued_actions: VecDeque<ToSwarm<Event, Either<handler::In, Void>>>,

Expand All @@ -92,6 +104,7 @@ pub fn new(local_peer_id: PeerId) -> (Transport, Behaviour) {
local_peer_id,
from_transport,
directly_connected_peers: Default::default(),
reservation_addresses: Default::default(),
queued_actions: Default::default(),
pending_handler_commands: Default::default(),
};
Expand Down Expand Up @@ -126,6 +139,12 @@ impl Behaviour {
unreachable!("`on_connection_closed` for unconnected peer.")
}
};
if let Some((addr, ReservationStatus::Confirmed)) =
self.reservation_addresses.remove(&connection_id)
{
self.queued_actions
.push_back(ToSwarm::ExternalAddrExpired(addr));
}
}
}
}
Expand Down Expand Up @@ -200,6 +219,7 @@ impl NetworkBehaviour for Behaviour {
self.on_connection_closed(connection_closed)
}
FromSwarm::DialFailure(DialFailure { connection_id, .. }) => {
self.reservation_addresses.remove(&connection_id);
self.pending_handler_commands.remove(&connection_id);
}
_ => {}
Expand All @@ -209,7 +229,7 @@ impl NetworkBehaviour for Behaviour {
fn on_connection_handler_event(
&mut self,
event_source: PeerId,
_connection: ConnectionId,
connection: ConnectionId,
handler_event: THandlerOutEvent<Self>,
) {
let handler_event = match handler_event {
Expand All @@ -219,6 +239,17 @@ impl NetworkBehaviour for Behaviour {

let event = match handler_event {
handler::Event::ReservationReqAccepted { renewal, limit } => {
let (addr, status) = self
.reservation_addresses
.get_mut(&connection)
.expect("Relay connection exist");

if !renewal && *status == ReservationStatus::Pending {
*status = ReservationStatus::Confirmed;
self.queued_actions
.push_back(ToSwarm::ExternalAddrConfirmed(addr.clone()));
}

Event::ReservationReqAccepted {
relay_peer_id: event_source,
renewal,
Expand All @@ -236,7 +267,7 @@ impl NetworkBehaviour for Behaviour {
}
};

self.queued_actions.push_back(ToSwarm::GenerateEvent(event))
self.queued_actions.push_back(ToSwarm::GenerateEvent(event));
}

#[tracing::instrument(level = "trace", name = "NetworkBehaviour::poll", skip(self, cx))]
Expand All @@ -259,18 +290,42 @@ impl NetworkBehaviour for Behaviour {
.get(&relay_peer_id)
.and_then(|cs| cs.first())
{
Some(connection_id) => ToSwarm::NotifyHandler {
peer_id: relay_peer_id,
handler: NotifyHandler::One(*connection_id),
event: Either::Left(handler::In::Reserve { to_listener }),
},
Some(connection_id) => {
self.reservation_addresses.insert(
*connection_id,
(
relay_addr
.with(Protocol::P2p(relay_peer_id))
.with(Protocol::P2pCircuit)
.with(Protocol::P2p(self.local_peer_id)),
ReservationStatus::Pending,
),
);

ToSwarm::NotifyHandler {
peer_id: relay_peer_id,
handler: NotifyHandler::One(*connection_id),
event: Either::Left(handler::In::Reserve { to_listener }),
}
}
None => {
let opts = DialOpts::peer_id(relay_peer_id)
.addresses(vec![relay_addr])
.addresses(vec![relay_addr.clone()])
.extend_addresses_through_behaviour()
.build();
let relayed_connection_id = opts.connection_id();

self.reservation_addresses.insert(
relayed_connection_id,
(
relay_addr
.with(Protocol::P2p(relay_peer_id))
.with(Protocol::P2pCircuit)
.with(Protocol::P2p(self.local_peer_id)),
ReservationStatus::Pending,
),
);

self.pending_handler_commands
.insert(relayed_connection_id, handler::In::Reserve { to_listener });
ToSwarm::Dial { opts }
Expand Down
11 changes: 10 additions & 1 deletion protocols/relay/tests/lib.rs
dariusc93 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fn new_reservation_to_same_relay_replaces_old() {
));

// Trigger new reservation.
let new_listener = client.listen_on(client_addr).unwrap();
let new_listener = client.listen_on(client_addr.clone()).unwrap();

// Wait for
// - listener of old reservation to close
Expand Down Expand Up @@ -169,6 +169,12 @@ fn new_reservation_to_same_relay_replaces_old() {
break;
}
}
SwarmEvent::ExternalAddrConfirmed { address } => {
assert_eq!(
address,
client_addr.clone().with(Protocol::P2p(client_peer_id))
);
}
SwarmEvent::Behaviour(ClientEvent::Ping(_)) => {}
e => panic!("{e:?}"),
}
Expand Down Expand Up @@ -521,6 +527,9 @@ async fn wait_for_reservation(

loop {
match client.select_next_some().await {
SwarmEvent::ExternalAddrConfirmed { address } if !is_renewal => {
assert_eq!(address, client_addr);
}
SwarmEvent::Behaviour(ClientEvent::Relay(
relay::client::Event::ReservationReqAccepted {
relay_peer_id: peer_id,
Expand Down