autonat_client/
autonat_client.rs1#![doc = include_str!("../../README.md")]
22
23use std::{error::Error, net::Ipv4Addr, time::Duration};
24
25use clap::Parser;
26use futures::StreamExt;
27use libp2p::{
28 autonat,
29 core::{multiaddr::Protocol, Multiaddr},
30 identify, identity, noise,
31 swarm::{NetworkBehaviour, SwarmEvent},
32 tcp, yamux, PeerId,
33};
34use tracing_subscriber::EnvFilter;
35
36#[derive(Debug, Parser)]
37#[command(name = "libp2p autonat")]
38struct Opt {
39 #[arg(long)]
40 listen_port: Option<u16>,
41
42 #[arg(long)]
43 server_address: Multiaddr,
44
45 #[arg(long)]
46 server_peer_id: PeerId,
47}
48
49#[tokio::main]
50async fn main() -> Result<(), Box<dyn Error>> {
51 let _ = tracing_subscriber::fmt()
52 .with_env_filter(EnvFilter::from_default_env())
53 .try_init();
54
55 let opt = Opt::parse();
56
57 let mut swarm = libp2p::SwarmBuilder::with_new_identity()
58 .with_tokio()
59 .with_tcp(
60 tcp::Config::default(),
61 noise::Config::new,
62 yamux::Config::default,
63 )?
64 .with_behaviour(|key| Behaviour::new(key.public()))?
65 .build();
66
67 swarm.listen_on(
68 Multiaddr::empty()
69 .with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED))
70 .with(Protocol::Tcp(opt.listen_port.unwrap_or(0))),
71 )?;
72
73 swarm
74 .behaviour_mut()
75 .auto_nat
76 .add_server(opt.server_peer_id, Some(opt.server_address));
77
78 loop {
79 match swarm.select_next_some().await {
80 SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"),
81 SwarmEvent::Behaviour(event) => println!("{event:?}"),
82 e => println!("{e:?}"),
83 }
84 }
85}
86
87#[derive(NetworkBehaviour)]
88struct Behaviour {
89 identify: identify::Behaviour,
90 auto_nat: autonat::Behaviour,
91}
92
93impl Behaviour {
94 fn new(local_public_key: identity::PublicKey) -> Self {
95 Self {
96 identify: identify::Behaviour::new(identify::Config::new(
97 "/ipfs/0.1.0".into(),
98 local_public_key.clone(),
99 )),
100 auto_nat: autonat::Behaviour::new(
101 local_public_key.to_peer_id(),
102 autonat::Config {
103 retry_interval: Duration::from_secs(10),
104 refresh_interval: Duration::from_secs(30),
105 boot_delay: Duration::from_secs(5),
106 throttle_server_period: Duration::ZERO,
107 only_global_ips: false,
108 ..Default::default()
109 },
110 ),
111 }
112 }
113}