xref: /webrtc/stun/examples/stun_client.rs (revision 5d8fe953)
1 use stun::agent::*;
2 use stun::client::*;
3 use stun::message::*;
4 use stun::xoraddr::*;
5 use stun::Error;
6 
7 use clap::{App, Arg};
8 use std::sync::Arc;
9 use tokio::net::UdpSocket;
10 
11 #[tokio::main]
main() -> Result<(), Error>12 async fn main() -> Result<(), Error> {
13     let mut app = App::new("STUN Client")
14         .version("0.1.0")
15         .author("Rain Liu <[email protected]>")
16         .about("An example of STUN Client")
17         .arg(
18             Arg::with_name("FULLHELP")
19                 .help("Prints more detailed help information")
20                 .long("fullhelp"),
21         )
22         .arg(
23             Arg::with_name("server")
24                 .required_unless("FULLHELP")
25                 .takes_value(true)
26                 .default_value("stun.l.google.com:19302")
27                 .long("server")
28                 .help("STUN Server"),
29         );
30 
31     let matches = app.clone().get_matches();
32 
33     if matches.is_present("FULLHELP") {
34         app.print_long_help().unwrap();
35         std::process::exit(0);
36     }
37 
38     let server = matches.value_of("server").unwrap();
39 
40     let (handler_tx, mut handler_rx) = tokio::sync::mpsc::unbounded_channel();
41 
42     let conn = UdpSocket::bind("0:0").await?;
43     println!("Local address: {}", conn.local_addr()?);
44 
45     println!("Connecting to: {server}");
46     conn.connect(server).await?;
47 
48     let mut client = ClientBuilder::new().with_conn(Arc::new(conn)).build()?;
49 
50     let mut msg = Message::new();
51     msg.build(&[Box::<TransactionId>::default(), Box::new(BINDING_REQUEST)])?;
52 
53     client.send(&msg, Some(Arc::new(handler_tx))).await?;
54 
55     if let Some(event) = handler_rx.recv().await {
56         let msg = event.event_body?;
57         let mut xor_addr = XorMappedAddress::default();
58         xor_addr.get_from(&msg)?;
59         println!("Got response: {xor_addr}");
60     }
61 
62     client.close().await?;
63 
64     Ok(())
65 }
66