autonat_server/
autonat_server.rs1#![doc = include_str!("../../README.md")]
22
23use std::{error::Error, net::Ipv4Addr};
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,
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
43#[tokio::main]
44async fn main() -> Result<(), Box<dyn Error>> {
45 let _ = tracing_subscriber::fmt()
46 .with_env_filter(EnvFilter::from_default_env())
47 .try_init();
48
49 let opt = Opt::parse();
50
51 let mut swarm = libp2p::SwarmBuilder::with_new_identity()
52 .with_tokio()
53 .with_tcp(
54 tcp::Config::default(),
55 noise::Config::new,
56 yamux::Config::default,
57 )?
58 .with_behaviour(|key| Behaviour::new(key.public()))?
59 .build();
60
61 swarm.listen_on(
62 Multiaddr::empty()
63 .with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED))
64 .with(Protocol::Tcp(opt.listen_port.unwrap_or(0))),
65 )?;
66
67 loop {
68 match swarm.select_next_some().await {
69 SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"),
70 SwarmEvent::Behaviour(event) => println!("{event:?}"),
71 e => println!("{e:?}"),
72 }
73 }
74}
75
76#[derive(NetworkBehaviour)]
77struct Behaviour {
78 identify: identify::Behaviour,
79 auto_nat: autonat::Behaviour,
80}
81
82impl Behaviour {
83 fn new(local_public_key: identity::PublicKey) -> Self {
84 Self {
85 identify: identify::Behaviour::new(identify::Config::new(
86 "/ipfs/0.1.0".into(),
87 local_public_key.clone(),
88 )),
89 auto_nat: autonat::Behaviour::new(
90 local_public_key.to_peer_id(),
91 autonat::Config {
92 only_global_ips: false,
93 ..Default::default()
94 },
95 ),
96 }
97 }
98}