1 use clap::{App, AppSettings, Arg};
2 use std::fs::File;
3 use std::io::{BufReader, Write};
4 use std::sync::Arc;
5 use tokio::net::UdpSocket;
6 use util::Conn;
7 use webrtc_dtls::Error;
8 use webrtc_dtls::{config::*, conn::DTLSConn};
9 
10 // cargo run --example dial_verify -- --server 127.0.0.1:4444
11 
12 #[tokio::main]
main() -> Result<(), Error>13 async fn main() -> Result<(), Error> {
14     env_logger::Builder::new()
15         .format(|buf, record| {
16             writeln!(
17                 buf,
18                 "{}:{} [{}] {} - {}",
19                 record.file().unwrap_or("unknown"),
20                 record.line().unwrap_or(0),
21                 record.level(),
22                 chrono::Local::now().format("%H:%M:%S.%6f"),
23                 record.args()
24             )
25         })
26         .filter(None, log::LevelFilter::Trace)
27         .init();
28 
29     let mut app = App::new("DTLS Client")
30         .version("0.1.0")
31         .author("Rain Liu <[email protected]>")
32         .about("An example of DTLS Client")
33         .setting(AppSettings::DeriveDisplayOrder)
34         .setting(AppSettings::SubcommandsNegateReqs)
35         .arg(
36             Arg::with_name("FULLHELP")
37                 .help("Prints more detailed help information")
38                 .long("fullhelp"),
39         )
40         .arg(
41             Arg::with_name("server")
42                 .required_unless("FULLHELP")
43                 .takes_value(true)
44                 .default_value("127.0.0.1:4444")
45                 .long("server")
46                 .help("DTLS Server name."),
47         );
48 
49     let matches = app.clone().get_matches();
50 
51     if matches.is_present("FULLHELP") {
52         app.print_long_help().unwrap();
53         std::process::exit(0);
54     }
55 
56     let server = matches.value_of("server").unwrap();
57 
58     let conn = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
59     conn.connect(server).await?;
60     println!("connecting {server}..");
61 
62     let certificate = hub::utilities::load_key_and_certificate(
63         "dtls/examples/certificates/client.pem.private_key.pem".into(),
64         "dtls/examples/certificates/client.pub.pem".into(),
65     )?;
66 
67     let mut cert_pool = rustls::RootCertStore::empty();
68     let f = File::open("dtls/examples/certificates/server.pub.pem")?;
69     let mut reader = BufReader::new(f);
70     if cert_pool.add_pem_file(&mut reader).is_err() {
71         return Err(Error::Other("cert_pool add_pem_file failed".to_owned()));
72     }
73 
74     let config = Config {
75         certificates: vec![certificate],
76         extended_master_secret: ExtendedMasterSecretType::Require,
77         roots_cas: cert_pool,
78         server_name: "webrtc.rs".to_owned(),
79         ..Default::default()
80     };
81     let dtls_conn: Arc<dyn Conn + Send + Sync> =
82         Arc::new(DTLSConn::new(conn, config, true, None).await?);
83 
84     println!("Connected; type 'exit' to shutdown gracefully");
85     let _ = hub::utilities::chat(Arc::clone(&dtls_conn)).await;
86 
87     dtls_conn.close().await?;
88 
89     Ok(())
90 }
91