tetsy_libp2p_relay/lib.rs
1// Copyright 2019 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21//! Implementation of the [libp2p circuit relay
22//! specification](https://github.com/libp2p/specs/tree/master/relay).
23//!
24//! ## Example
25//!
26//! ```rust
27//! # use tetsy_libp2p_core::transport::memory::MemoryTransport;
28//! # use tetsy_libp2p_relay::{RelayConfig, new_transport_and_behaviour};
29//! # use tetsy_libp2p_swarm::Swarm;
30//! # use tetsy_libp2p_core::{identity, Multiaddr, multiaddr::Protocol, PeerId, upgrade, Transport};
31//! # use libp2p_remux::RemuxConfig;
32//! # use plaintext::PlainText2Config;
33//! # use std::convert::TryInto;
34//! # use std::str::FromStr;
35//! #
36//! # let local_key = identity::Keypair::generate_ed25519();
37//! # let local_public_key = local_key.public();
38//! # let local_peer_id = local_public_key.clone().into_peer_id();
39//! # let plain = PlainText2Config {
40//! # local_public_key: local_public_key.clone(),
41//! # };
42//! #
43//! let (relay_transport, relay_behaviour) = new_transport_and_behaviour(
44//! RelayConfig::default(),
45//! MemoryTransport::default(),
46//! );
47//!
48//! let transport = relay_transport
49//! .upgrade(upgrade::Version::V1)
50//! .authenticate(plain)
51//! .multiplex(RemuxConfig::default())
52//! .boxed();
53//!
54//! let mut swarm = Swarm::new(transport, relay_behaviour, local_peer_id);
55//!
56//! let relay_addr = Multiaddr::from_str("/memory/1234").unwrap()
57//! .with(Protocol::P2p(PeerId::random().into()))
58//! .with(Protocol::P2pCircuit);
59//! let dst_addr = relay_addr.clone().with(Protocol::Memory(5678));
60//!
61//! // Listen for incoming connections via relay node (1234).
62//! Swarm::listen_on(&mut swarm, relay_addr).unwrap();
63//!
64//! // Dial node (5678) via relay node (1234).
65//! Swarm::dial_addr(&mut swarm, dst_addr).unwrap();
66//! ```
67//!
68//! ## Terminology
69//!
70//! ### Entities
71//!
72//! - **Source**: The node initiating a connection via a *relay* to a *destination*.
73//!
74//! - **Relay**: The node being asked by a *source* to relay to a *destination*.
75//!
76//! - **Destination**: The node contacted by the *source* via the *relay*.
77//!
78//! ### Messages
79//!
80//! - **Outgoing relay request**: The request sent by a *source* to a *relay*.
81//!
82//! - **Incoming relay request**: The request received by a *relay* from a *source*.
83//!
84//! - **Outgoing destination request**: The request sent by a *relay* to a *destination*.
85//!
86//! - **Incoming destination request**: The request received by a *destination* from a *relay*.
87
88mod behaviour;
89
90mod message_proto {
91 include!(concat!(env!("OUT_DIR"), "/message.pb.rs"));
92}
93
94mod handler;
95mod protocol;
96mod transport;
97
98pub use behaviour::{Relay, RelayConfig};
99pub use transport::{RelayError, RelayTransport};
100
101use tetsy_libp2p_core::Transport;
102
103/// Create both a [`RelayTransport`] wrapping the provided [`Transport`]
104/// as well as a [`Relay`] [`NetworkBehaviour`](tetsy_libp2p_swarm::NetworkBehaviour).
105///
106/// Interconnects the returned [`RelayTransport`] and [`Relay`].
107pub fn new_transport_and_behaviour<T: Transport + Clone>(
108 config: RelayConfig,
109 transport: T,
110) -> (RelayTransport<T>, Relay) {
111 let (transport, from_transport) = RelayTransport::new(transport);
112 let behaviour = Relay::new(config, from_transport);
113 (transport, behaviour)
114}
115
116/// The ID of an outgoing / incoming, relay / destination request.
117#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
118pub struct RequestId(u64);
119
120impl RequestId {
121 fn new() -> RequestId {
122 RequestId(rand::random())
123 }
124}