Skip to content

Commit

Permalink
chore: Upgrade arti_client to 0.24 (#18)
Browse files Browse the repository at this point in the history
* feat: Upgrade arti_client to 0.24

* feat: force use of tokio / rustls, upgrade libp2p to 0.53, migrate example to new libp2p API

* bump: Crate version to 0.2.0

* feat: use tracing to log connection establishement

* Update Cargo.toml

Co-authored-by: Hannes <[email protected]>

* fix: revert removal of copyright, change of repository url, remove redundant features for tokio

* fix: revert removal of example from Cargo.toml

* feat: Add example for constructing tokio TorTransport

* fix: use tokio-test for doctest

* docs: Update readme to reflect changelogs

* refactor: constructor method for onion transport in examples/ping-onion

* fix: match ConnectionEstablished, OutgoingConnectionError in swarm event loop

* refactor: add comments, switch order of functions to reduce diff

* refactor: remove type alias for TorClientBuilder since generics have been removed

* feat: add from_client constructor

* fix: remaining clippy warnings

---------

Co-authored-by: Hannes <[email protected]>
  • Loading branch information
binarybaron and umgefahren authored Nov 20, 2024
1 parent 36ecad6 commit 75d2540
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 258 deletions.
28 changes: 9 additions & 19 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "libp2p-community-tor"
version = "0.3.0-alpha"
version = "0.4.0"
edition = "2021"
license = "MIT"
resolver = "2"
Expand All @@ -9,30 +9,20 @@ repository = "https://github.com/umgefahren/libp2p-tor"
authors = ["umgefahren <[email protected]>"]

[dependencies]
arti-client = { version = "0.8", default-features = false }
async-std-crate = { package = "async-std", version = "1", optional = true, default-features = false }
arti-client = "0.24.0"
futures = "0.3"
libp2p-core = { version = "0.39" }
thiserror = "1"
tokio-crate = { package = "tokio", version = "1", optional = true, default-features = false }
tor-rtcompat = "0.8"
libp2p = { version = "^0.53", default-features = false, features = ["tokio", "tcp", "tls"] }
tor-rtcompat = { version = "0.24.0", features = ["tokio", "rustls"] }
tokio = { version = "1.0", features = ["macros"] }
tracing = "0.1.40"

[dev-dependencies]
libp2p = { version = "0.51", features = ["mplex", "noise", "ping", "yamux", "macros", "async-std"] }
tokio-crate = { package = "tokio", version = "1", features = ["rt", "macros"] }
async-std-crate = { package = "async-std", version = "1", features = ["attributes"] }

[features]
tokio = ["arti-client/tokio", "dep:tokio-crate"]
async-std = ["arti-client/async-std", "dep:async-std-crate"]
native-tls = ["arti-client/native-tls"]
rustls = ["arti-client/rustls"]
libp2p = { version = "0.53", default-features = false, features = ["tokio", "noise", "yamux", "ping", "noise", "macros", "tcp", "tls"] }
tokio-test = "0.4.4"

[[example]]
name = "ping-onion"
required-features = ["async-std", "rustls"]

[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
rustc-args = ["--cfg", "docsrs"]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
19 changes: 4 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,20 @@ are dealing with.

### Add to your dependencies

This won't work:
```bash
cargo add libp2p-community-tor@0.3.0-alpha
cargo add libp2p-community-tor
```

You have to choose a TLS provider **and** a runtime.
The TLS providers are:
This crate uses tokio with rustls for its runtime and TLS implementation.
No other combinations are supported.

- [`rustls`](https://github.com/rustls/rustls)
- [`native-tls`](https://github.com/sfackler/rust-native-tls)

The runtimes are:

- [`tokio`](https://github.com/tokio-rs/tokio)
- [`async-std`](https://github.com/async-rs/async-std)

| | **rustls** | **native-tls** |
|---------------|------------------------------------------------------------------|----------------------------------------------------------------------|
| **tokio** | `cargo add [email protected] -F tokio,rustls` | `cargo add [email protected] -F tokio,native-tls` |
| **async-std** | `cargo add [email protected] -F async-std,rustls` | `cargo add [email protected] -F async-std,native-tls` |

### Example
```rust
let address = "/dns/www.torproject.org/tcp/1000".parse()?;
let mut transport = libp2p_community_tor::AsyncStdNativeTlsTorTransport::bootstrapped().await?;
let mut transport = libp2p_community_tor::TorTransport::bootstrapped().await?;
// we have achieved tor connection
let _conn = transport.dial(address)?.await?;
```
Expand Down
108 changes: 65 additions & 43 deletions examples/ping-onion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,78 +43,100 @@
//! The two nodes establish a connection, negotiate the ping protocol
//! and begin pinging each other over Tor.
use async_std_crate as async_std;
use futures::prelude::*;
use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent};
use libp2p::{core::upgrade, identity, mplex, noise, ping, yamux, Multiaddr, PeerId, Transport};
use libp2p_community_tor::{AddressConversion, AsyncStdRustlsTorTransport};
use futures::StreamExt;
use libp2p::core::upgrade::Version;
use libp2p::Transport;
use libp2p::{
core::muxing::StreamMuxerBox,
identity, noise,
swarm::{NetworkBehaviour, SwarmEvent},
yamux, Multiaddr, PeerId, SwarmBuilder,
};
use libp2p_community_tor::{AddressConversion, TorTransport};
use std::error::Error;

async fn onion_transport(
keypair: identity::Keypair,
) -> Result<
libp2p_core::transport::Boxed<(PeerId, libp2p_core::muxing::StreamMuxerBox)>,
libp2p::core::transport::Boxed<(PeerId, libp2p::core::muxing::StreamMuxerBox)>,
Box<dyn Error>,
> {
use std::time::Duration;

let transport = AsyncStdRustlsTorTransport::bootstrapped()
let transport = TorTransport::bootstrapped()
.await?
.with_address_conversion(AddressConversion::IpAndDns);
Ok(transport
.upgrade(upgrade::Version::V1)
.authenticate(
noise::NoiseAuthenticated::xx(&keypair)
.expect("Signing libp2p-noise static DH keypair failed."),
)
.multiplex(upgrade::SelectUpgrade::new(
yamux::YamuxConfig::default(),
mplex::MplexConfig::default(),
))
.timeout(Duration::from_secs(20))
.boxed())
.with_address_conversion(AddressConversion::IpAndDns)
.boxed();

let auth_upgrade = noise::Config::new(&keypair)?;
let multiplex_upgrade = yamux::Config::default();

let transport = transport
.upgrade(Version::V1)
.authenticate(auth_upgrade)
.multiplex(multiplex_upgrade)
.map(|(peer, muxer), _| (peer, StreamMuxerBox::new(muxer)))
.boxed();

Ok(transport)
}

#[async_std::main]
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let addr = std::env::args().nth(1).expect("no multiaddr given");
let local_key = identity::Keypair::generate_ed25519();
let local_peer_id = PeerId::from(local_key.public());
println!("Local peer id: {:?}", local_peer_id);

println!("Local peer id: {local_peer_id}");

let transport = onion_transport(local_key).await?;

let mut swarm =
SwarmBuilder::with_async_std_executor(transport, Behaviour::default(), local_peer_id)
.build();
let mut swarm = SwarmBuilder::with_new_identity()
.with_tokio()
.with_tcp(
Default::default(),
(libp2p::tls::Config::new, libp2p::noise::Config::new),
libp2p::yamux::Config::default,
)
.unwrap()
.with_other_transport(|_| transport)
.unwrap()
.with_behaviour(|_| Behaviour {
ping: libp2p::ping::Behaviour::default(),
})
.unwrap()
.build();

// Tell the swarm to listen on all interfaces and a random, OS-assigned
// port.
swarm
.listen_on("/ip4/0.0.0.0/tcp/0".parse().unwrap())
.unwrap();

// Dial the peer identified by the multi-address given as the second
// command-line argument, if any.
let remote: Multiaddr = addr.parse()?;
swarm.dial(remote)?;
println!("Dialed {}", addr);
if let Some(addr) = std::env::args().nth(1) {
let remote: Multiaddr = addr.parse()?;
swarm.dial(remote)?;
println!("Dialed {addr}")
}

loop {
match swarm.select_next_some().await {
SwarmEvent::ConnectionEstablished { endpoint, .. } => {
let endpoint_addr = endpoint.get_remote_address();
println!("Connection established to {:?}", endpoint_addr);
SwarmEvent::ConnectionEstablished {
endpoint, peer_id, ..
} => {
println!("Connection established with {peer_id} on {endpoint:?}");
}
SwarmEvent::OutgoingConnectionError { error, .. } => {
println!("Error establishing outgoing connection: {:?}", error)
SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => {
println!("Outgoing connection error with {peer_id:?}: {error:?}");
}
SwarmEvent::Behaviour(event) => println!("{:?}", event),
SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"),
SwarmEvent::Behaviour(event) => println!("{event:?}"),
_ => {}
}
}
}

/// Our network behaviour.
///
/// For illustrative purposes, this includes the [`KeepAlive`](behaviour::KeepAlive) behaviour so a continuous sequence of
/// pings can be observed.
#[derive(NetworkBehaviour, Default)]
#[derive(NetworkBehaviour)]
struct Behaviour {
keep_alive: keep_alive::Behaviour,
ping: ping::Behaviour,
ping: libp2p::ping::Behaviour,
}
2 changes: 1 addition & 1 deletion src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
// DEALINGS IN THE SOFTWARE.

use arti_client::{DangerouslyIntoTorAddr, IntoTorAddr, TorAddr};
use libp2p_core::{multiaddr::Protocol, Multiaddr};
use libp2p::{core::multiaddr::Protocol, Multiaddr};
use std::net::SocketAddr;

/// "Dangerously" extract a Tor address from the provided [`Multiaddr`].
Expand Down
Loading

0 comments on commit 75d2540

Please sign in to comment.