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

protocols/: Add basic AutoNAT implementation #2262

Merged
merged 87 commits into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from 79 commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
53bd428
Initial commit.
dvc94ch Jul 20, 2020
c4ae523
Implement protocol.
dvc94ch Jul 20, 2020
bccf94c
Add behaviour boilerplate.
dvc94ch Jul 20, 2020
28f3514
protocols/autonat: Add basic behaviour logic
elenaf9 Sep 27, 2021
2e042d8
protocols/autonat: clippy::module_name_repetitions
elenaf9 Oct 2, 2021
3fc78f0
protocols/autonat/behaviour: timeout config
elenaf9 Oct 3, 2021
1cc2fe1
protocols/autonat: rustdoc::broken-intra-doc-links
elenaf9 Oct 3, 2021
8650b97
protocols/autonat/behaviour: smaller fixes, docs
elenaf9 Oct 3, 2021
066c7cf
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Oct 22, 2021
806baaa
protocols/autonat/behaviour: refactor behaviour
elenaf9 Oct 25, 2021
ae63515
protocols/autonat/behaviour: config, filtering of addrs, errors
elenaf9 Oct 28, 2021
db21532
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Oct 28, 2021
b4cda19
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Nov 6, 2021
6b79e66
protocols/autonat/behaviour: clean Behaviour::poll
elenaf9 Nov 6, 2021
48ad51d
protocols/autonat: enhance logic for filtering addrs
elenaf9 Nov 15, 2021
f4c5c34
protocol/autonat/behaviour: small fix
elenaf9 Nov 15, 2021
292a43a
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Nov 15, 2021
2345515
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Nov 21, 2021
310b086
protocols/autonat/behaviour: set addrs via DialOpts
elenaf9 Nov 21, 2021
0a612c0
protocols/autonat/behaviour: methods for managing servers
elenaf9 Nov 21, 2021
99418f8
protocols/autonat/behaviour: wake task for auto-retry
elenaf9 Nov 21, 2021
1d3cdbd
protocols/autonat/behaviour: get observed addr from inner
elenaf9 Nov 21, 2021
9a3feb2
protocols/autonat/behaviour: report addr score on dial ok
elenaf9 Nov 21, 2021
79ce520
protocols/autonat/behaviour: retry status on new external addr
elenaf9 Nov 21, 2021
0e8683c
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Nov 24, 2021
cf7aa75
protocols/autonat/behaviour: clean types, apply review, add comments
elenaf9 Nov 25, 2021
cc14357
protocols/autonat/behaviour: track observed address
elenaf9 Nov 25, 2021
ddcd9ce
protocols/autonat/behaviour: skip dial if observed addr is relayed
elenaf9 Nov 25, 2021
b07ef43
protocols/autonat/examples: Add client example
mxinden Nov 26, 2021
494aed1
protocols/autonat: fix bugs, clean code
elenaf9 Nov 26, 2021
4560e3a
protocols/autonat/tests: add test
elenaf9 Nov 26, 2021
be155c7
Apply suggestions from code review
elenaf9 Nov 26, 2021
0a1df00
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Nov 27, 2021
753a6fb
protocols/autonat/behaviour: don't track listen addrs
elenaf9 Nov 27, 2021
8a23e00
protocols/autonat/behaviour: reorder trait methods
elenaf9 Nov 27, 2021
8971882
protocols/autonat: remove unused dev-deps
elenaf9 Nov 27, 2021
bd0215c
protocols/autonat/behaviour: fix duplicated server in probe
elenaf9 Nov 28, 2021
ab36bfd
protocols/autonat/behaviour: fix prove evaluation
elenaf9 Nov 28, 2021
960a2ed
protocols/autonat/behaviour: use random set of connected peers
elenaf9 Nov 28, 2021
778fbf3
protocols/autonat/behaviour: align ResponseErrors with Go impl
elenaf9 Nov 28, 2021
2f23e4b
protocols/autonat/behaviour: add status_text to DialResponse
elenaf9 Nov 28, 2021
ebd9d2a
protocols/autonat/behaviour: fix & test filter_valid_addrs
elenaf9 Nov 28, 2021
44f684a
protocols/autonat: add debug messages
elenaf9 Nov 28, 2021
96d24ca
Merge branch 'elenaf9/protocols/autonat' into autonat-examples-client
mxinden Nov 29, 2021
b75f0dd
protocols/autonat/examples/client: Address review comments
mxinden Nov 29, 2021
a4845c3
Merge pull request #1 from mxinden/autonat-examples-client
elenaf9 Nov 29, 2021
e613fdc
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Dec 5, 2021
3dfaa1c
protocols/autonat: statefull evaluation of probes
elenaf9 Dec 5, 2021
b567268
protocols/autonat/behaviour: fix intra-doc link
elenaf9 Dec 5, 2021
f1f8549
protocols/autonat/behaviour: clean code, improve docs
elenaf9 Dec 6, 2021
a3724b7
protocols/autonat/behaviour: enable simultaneous probes
elenaf9 Dec 6, 2021
4b5c1d0
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Dec 9, 2021
2775041
protocols/autonat: Enable manual trigger of probes
elenaf9 Dec 9, 2021
416fd06
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Dec 10, 2021
9901ab9
protocols/autonat/behaviour: report all NAT events
elenaf9 Dec 10, 2021
b25f6b1
protocols/autonat: small fixes, test manual probes
elenaf9 Dec 10, 2021
ac6d7c9
protocols/autonat: remove debug code
elenaf9 Dec 10, 2021
37ab4d9
protocols/autonat/behaviour: fix reported NAT status
elenaf9 Dec 10, 2021
a2c3ca1
protocols/autonat: only report probes if status flipped
elenaf9 Dec 12, 2021
750040c
protocols/autonat: tests
elenaf9 Dec 13, 2021
f742f35
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Dec 13, 2021
698ef8c
protocols/autonat: fix tests
elenaf9 Dec 13, 2021
5448952
protocols/autonat: improve example & docs
elenaf9 Dec 13, 2021
aa06f5e
protocols/autonat/behaviour: throttle clients per period
elenaf9 Dec 14, 2021
006771a
protocols/autonat/behaviour: handle different reported public addr
elenaf9 Dec 14, 2021
de15fc1
protocols/autonat: don't reduce confidence on status Unknown
elenaf9 Dec 14, 2021
037a330
Apply suggestions from code review
elenaf9 Dec 21, 2021
d194a93
protocols/autonat: report event for each probe
elenaf9 Dec 29, 2021
7c8cb0b
protocols/autonat: apply review comments
elenaf9 Dec 29, 2021
dbfc59e
protocols/autonat/behaviour: clean Behaviour::poll
elenaf9 Dec 29, 2021
f0cb16e
protocols/autonat/behaviour: fix report In-/Outbound Failures
elenaf9 Dec 30, 2021
27762f0
protocols/autonat/behaviour: clean Behaviour::poll
elenaf9 Dec 31, 2021
2057452
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Dec 31, 2021
3ed7b91
protocols/autonat/behaviour: fix throttle clients
elenaf9 Jan 1, 2022
17b23d1
protocols/autonat: clean client tests
elenaf9 Jan 1, 2022
8ea0112
protocols/autonat: add server tests
elenaf9 Jan 1, 2022
5b15dcb
protocols/autonat: Separate Client and Server logic
elenaf9 Jan 2, 2022
4ee4eb0
protocols/autonat: Use current Repo license
elenaf9 Jan 2, 2022
f8e8805
protocols/autonat/behaviour: fix broken_intra_doc_links
elenaf9 Jan 2, 2022
2a73082
protocols/autonat/behaviour: fix observed addrs
elenaf9 Jan 12, 2022
43518fb
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Jan 12, 2022
f238adf
protocols/autonat/src/protocol: Use ResponseStatus::from_i32
mxinden Jan 13, 2022
a6d9ab0
Merge pull request elenaf9#3 from mxinden/autonat-from-i32
elenaf9 Jan 13, 2022
c23a72f
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Jan 13, 2022
8f6a1a0
protocols/autonat: override dial concurrency factor
elenaf9 Jan 13, 2022
4071597
protocols/autonat/protocol: fix clippy::or_fun_call
elenaf9 Jan 13, 2022
629d573
Merge branch 'master' of github.com:libp2p/rust-libp2p into protocols…
elenaf9 Jan 13, 2022
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
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ categories = ["network-programming", "asynchronous"]

[features]
default = [
"autonat",
"deflate",
"dns-async-std",
"floodsub",
Expand All @@ -34,6 +35,7 @@ default = [
"websocket",
"yamux",
]
autonat = ["libp2p-autonat"]
deflate = ["libp2p-deflate"]
dns-async-std = ["libp2p-dns", "libp2p-dns/async-std"]
dns-tokio = ["libp2p-dns", "libp2p-dns/tokio"]
Expand Down Expand Up @@ -72,6 +74,8 @@ futures-timer = "3.0.2" # Explicit dependency to be used in `wasm-bindgen` featu
getrandom = "0.2.3" # Explicit dependency to be used in `wasm-bindgen` feature
instant = "0.1.11" # Explicit dependency to be used in `wasm-bindgen` feature
lazy_static = "1.2"

libp2p-autonat = { version = "0.20.0", path = "protocols/autonat", optional = true }
libp2p-core = { version = "0.31.0", path = "core", default-features = false }
libp2p-floodsub = { version = "0.33.0", path = "protocols/floodsub", optional = true }
libp2p-gossipsub = { version = "0.35.0", path = "./protocols/gossipsub", optional = true }
Expand Down Expand Up @@ -119,6 +123,7 @@ members = [
"misc/peer-id-generator",
"muxers/mplex",
"muxers/yamux",
"protocols/autonat",
"protocols/floodsub",
"protocols/gossipsub",
"protocols/rendezvous",
Expand Down
36 changes: 36 additions & 0 deletions protocols/autonat/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[package]
name = "libp2p-autonat"
edition = "2021"
rust-version = "1.56.1"
version = "0.20.0"
elenaf9 marked this conversation as resolved.
Show resolved Hide resolved
authors = ["David Craven <david@craven.ch>", "Elena Frank <elena.frank@protonmail.com>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"
keywords = ["peer-to-peer", "libp2p", "networking"]
categories = ["network-programming", "asynchronous"]

[build-dependencies]
prost-build = "0.6"

[dependencies]
async-trait = "0.1"
futures = "0.3"
futures-timer = "3.0"
instant = "0.1"
libp2p-core = { version = "0.31.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.33.0", path = "../../swarm" }
libp2p-request-response = { version = "0.15.0", path = "../request-response" }
log = "0.4"
rand = "0.8"
prost = "0.8"

[dev-dependencies]
async-std = { version = "1.10", features = ["attributes"] }
env_logger = "0.9"
structopt = "0.3"


[dev-dependencies.libp2p]
path = "../../"
default-features = false
features = ["autonat", "dns-async-std", "identify", "mplex", "noise", "tcp-async-io", "websocket", "yamux"]
23 changes: 23 additions & 0 deletions protocols/autonat/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2021 Protocol Labs.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

fn main() {
prost_build::compile_protos(&["src/structs.proto"], &["src"]).unwrap();
}
135 changes: 135 additions & 0 deletions protocols/autonat/examples/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright 2021 Protocol Labs.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Basic example that combines the AutoNAT and identify protocols.
//!
//! The identify protocol informs the local peer of its external addresses, that are then send in AutoNAT dial-back
//! requests to the server.
//!
//! To run this example, follow the instructions in `examples/server` to start a server, then run in a new terminal:
//! ```sh
//! cargo run --example client -- --server-address <server-addr> --server-peer-id <server-peer-id> --listen_port <port>
//! ```
//! The `listen_port` parameter is optional and allows to set a fixed port at which the local client should listen.

use futures::prelude::*;
use libp2p::autonat;
use libp2p::identify::{Identify, IdentifyConfig, IdentifyEvent};
use libp2p::multiaddr::Protocol;
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::{identity, Multiaddr, NetworkBehaviour, PeerId};
use std::error::Error;
use std::net::Ipv4Addr;
use std::time::Duration;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(name = "libp2p autonat")]
struct Opt {
#[structopt(long)]
listen_port: Option<u16>,

#[structopt(long)]
server_address: Multiaddr,

#[structopt(long)]
server_peer_id: PeerId,
}

#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();

let opt = Opt::from_args();

let local_key = identity::Keypair::generate_ed25519();
let local_peer_id = PeerId::from(local_key.public());
println!("Local peer id: {:?}", local_peer_id);

let transport = libp2p::development_transport(local_key.clone()).await?;

let behaviour = Behaviour::new(local_key.public());

let mut swarm = Swarm::new(transport, behaviour, local_peer_id);
swarm.listen_on(
Multiaddr::empty()
.with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED))
.with(Protocol::Tcp(opt.listen_port.unwrap_or(0))),
)?;

swarm
.behaviour_mut()
.auto_nat
.add_server(opt.server_peer_id, Some(opt.server_address));

loop {
match swarm.select_next_some().await {
SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {:?}", address),
SwarmEvent::Behaviour(event) => println!("{:?}", event),
e => println!("{:?}", e),
}
}
}

#[derive(NetworkBehaviour)]
#[behaviour(out_event = "Event")]
struct Behaviour {
identify: Identify,
auto_nat: autonat::Behaviour,
}

impl Behaviour {
fn new(local_public_key: identity::PublicKey) -> Self {
Self {
identify: Identify::new(IdentifyConfig::new(
"/ipfs/0.1.0".into(),
local_public_key.clone(),
)),
auto_nat: autonat::Behaviour::new(
local_public_key.to_peer_id(),
autonat::Config {
retry_interval: Duration::from_secs(10),
refresh_interval: Duration::from_secs(30),
boot_delay: Duration::from_secs(5),
throttle_server_period: Duration::ZERO,
..Default::default()
},
),
}
}
}

#[derive(Debug)]
enum Event {
AutoNat(autonat::Event),
Identify(IdentifyEvent),
}

impl From<IdentifyEvent> for Event {
fn from(v: IdentifyEvent) -> Self {
Self::Identify(v)
}
}

impl From<autonat::Event> for Event {
fn from(v: autonat::Event) -> Self {
Self::AutoNat(v)
}
}
114 changes: 114 additions & 0 deletions protocols/autonat/examples/server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2021 Protocol Labs.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Basic example for a AutoNAT server that supports the /libp2p/autonat/1.0.0 and "/ipfs/0.1.0" protocols.
//!
//! To start the server run:
//! ```sh
//! cargo run --example server -- --listen_port <port>
//! ```
//! The `listen_port` parameter is optional and allows to set a fixed port at which the local peer should listen.

use futures::prelude::*;
use libp2p::autonat;
use libp2p::identify::{Identify, IdentifyConfig, IdentifyEvent};
use libp2p::multiaddr::Protocol;
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::{identity, Multiaddr, NetworkBehaviour, PeerId};
use std::error::Error;
use std::net::Ipv4Addr;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(name = "libp2p autonat")]
struct Opt {
#[structopt(long)]
listen_port: Option<u16>,
}

#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();

let opt = Opt::from_args();

let local_key = identity::Keypair::generate_ed25519();
let local_peer_id = PeerId::from(local_key.public());
println!("Local peer id: {:?}", local_peer_id);

let transport = libp2p::development_transport(local_key.clone()).await?;

let behaviour = Behaviour::new(local_key.public());

let mut swarm = Swarm::new(transport, behaviour, local_peer_id);
swarm.listen_on(
Multiaddr::empty()
.with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED))
.with(Protocol::Tcp(opt.listen_port.unwrap_or(0))),
)?;

loop {
match swarm.select_next_some().await {
SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {:?}", address),
SwarmEvent::Behaviour(event) => println!("{:?}", event),
e => println!("{:?}", e),
}
}
}

#[derive(NetworkBehaviour)]
#[behaviour(out_event = "Event")]
struct Behaviour {
identify: Identify,
auto_nat: autonat::Behaviour,
}

impl Behaviour {
fn new(local_public_key: identity::PublicKey) -> Self {
Self {
identify: Identify::new(IdentifyConfig::new(
"/ipfs/0.1.0".into(),
local_public_key.clone(),
)),
auto_nat: autonat::Behaviour::new(
local_public_key.to_peer_id(),
autonat::Config::default(),
),
}
}
}

#[derive(Debug)]
enum Event {
AutoNat(autonat::Event),
Identify(IdentifyEvent),
}

impl From<IdentifyEvent> for Event {
fn from(v: IdentifyEvent) -> Self {
Self::Identify(v)
}
}

impl From<autonat::Event> for Event {
fn from(v: autonat::Event) -> Self {
Self::AutoNat(v)
}
}
Loading