autonatv2_server/
autonatv2_server.rs

1use std::{error::Error, net::Ipv4Addr, time::Duration};
2
3use cfg_if::cfg_if;
4use clap::Parser;
5use libp2p::{
6    autonat,
7    futures::StreamExt,
8    identify, identity,
9    multiaddr::Protocol,
10    noise,
11    swarm::{NetworkBehaviour, SwarmEvent},
12    tcp, yamux, Multiaddr, SwarmBuilder,
13};
14use rand::rngs::OsRng;
15
16#[derive(Debug, Parser)]
17#[command(name = "libp2p autonatv2 server")]
18struct Opt {
19    #[arg(short, long, default_value_t = 0)]
20    listen_port: u16,
21}
22
23#[tokio::main]
24async fn main() -> Result<(), Box<dyn Error>> {
25    cfg_if! {
26        if #[cfg(feature = "jaeger")] {
27            use tracing_subscriber::layer::SubscriberExt;
28            use opentelemetry_sdk::runtime::Tokio;
29            let tracer = opentelemetry_jaeger::new_agent_pipeline()
30                .with_endpoint("jaeger:6831")
31                .with_service_name("autonatv2")
32                .install_batch(Tokio)?;
33            let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
34            let subscriber = tracing_subscriber::Registry::default()
35                .with(telemetry);
36        } else {
37            let subscriber = tracing_subscriber::fmt()
38                .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
39                .finish();
40        }
41    }
42    tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
43
44    let opt = Opt::parse();
45
46    let mut swarm = SwarmBuilder::with_new_identity()
47        .with_tokio()
48        .with_tcp(
49            tcp::Config::default(),
50            noise::Config::new,
51            yamux::Config::default,
52        )?
53        .with_quic()
54        .with_dns()?
55        .with_behaviour(|key| Behaviour::new(key.public()))?
56        .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
57        .build();
58
59    swarm.listen_on(
60        Multiaddr::empty()
61            .with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED))
62            .with(Protocol::Tcp(opt.listen_port)),
63    )?;
64
65    loop {
66        match swarm.select_next_some().await {
67            SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"),
68            SwarmEvent::Behaviour(event) => println!("{event:?}"),
69            e => println!("{e:?}"),
70        }
71    }
72}
73
74#[derive(NetworkBehaviour)]
75pub struct Behaviour {
76    autonat: autonat::v2::server::Behaviour,
77    identify: identify::Behaviour,
78}
79
80impl Behaviour {
81    pub fn new(key: identity::PublicKey) -> Self {
82        Self {
83            autonat: autonat::v2::server::Behaviour::new(OsRng),
84            identify: identify::Behaviour::new(identify::Config::new("/ipfs/0.1.0".into(), key)),
85        }
86    }
87}