99//! cargo run --example stun_discover -- --port 51258
1010//! ```
1111
12- use rustun:: client:: p2p:: stun:: { StunClient , NatType } ;
12+ use rustun:: client:: p2p:: stun:: { NatType , StunClient } ;
1313use std:: time:: Duration ;
1414
1515#[ derive( clap:: Parser , Debug ) ]
@@ -19,15 +19,15 @@ struct Args {
1919 /// Local UDP port to bind (0 for automatic)
2020 #[ arg( short, long, default_value = "0" ) ]
2121 port : u16 ,
22-
22+
2323 /// Custom STUN server (can be specified multiple times)
2424 #[ arg( short, long) ]
2525 stun_server : Vec < String > ,
26-
26+
2727 /// Request timeout in seconds
2828 #[ arg( short, long, default_value = "5" ) ]
2929 timeout : u64 ,
30-
30+
3131 /// Enable verbose logging
3232 #[ arg( short, long) ]
3333 verbose : bool ,
@@ -37,16 +37,14 @@ struct Args {
3737async fn main ( ) {
3838 use clap:: Parser ;
3939 let args = Args :: parse ( ) ;
40-
40+
4141 // Setup logging
4242 let log_level = if args. verbose { "debug" } else { "info" } ;
43- tracing_subscriber:: fmt ( )
44- . with_env_filter ( log_level)
45- . init ( ) ;
46-
43+ tracing_subscriber:: fmt ( ) . with_env_filter ( log_level) . init ( ) ;
44+
4745 println ! ( "🔍 STUN Discovery Tool" ) ;
4846 println ! ( "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" ) ;
49-
47+
5048 // Create STUN client
5149 let stun_client = if args. stun_server . is_empty ( ) {
5250 println ! ( "📡 Using default Google STUN servers" ) ;
@@ -55,35 +53,42 @@ async fn main() {
5553 println ! ( "📡 Using custom STUN servers: {:?}" , args. stun_server) ;
5654 StunClient :: with_servers ( args. stun_server )
5755 } ;
58-
56+
5957 let stun_client = stun_client. with_timeout ( Duration :: from_secs ( args. timeout ) ) ;
60-
61- println ! ( "🔌 Local port: {}" , if args. port == 0 { "auto" . to_string( ) } else { args. port. to_string( ) } ) ;
58+
59+ println ! (
60+ "🔌 Local port: {}" ,
61+ if args. port == 0 {
62+ "auto" . to_string( )
63+ } else {
64+ args. port. to_string( )
65+ }
66+ ) ;
6267 println ! ( ) ;
63-
68+
6469 // Perform discovery
6570 println ! ( "⏳ Discovering public address..." ) ;
6671 match stun_client. discover ( args. port ) . await {
6772 Ok ( result) => {
6873 println ! ( "✅ STUN Discovery Successful!\n " ) ;
69-
74+
7075 println ! ( "📍 Results:" ) ;
7176 println ! ( " Local Address: {}" , result. local_addr) ;
7277 println ! ( " Public Address: {}" , result. public_addr( ) ) ;
7378 println ! ( " Public IP: {}" , result. public_ip) ;
7479 println ! ( " Public Port: {}" , result. public_port) ;
7580 println ! ( ) ;
76-
81+
7782 println ! ( "🌐 NAT Information:" ) ;
7883 println ! ( " Type: {:?}" , result. nat_type) ;
7984 println ! ( " Description: {}" , result. nat_type. description( ) ) ;
8085 println ! ( ) ;
81-
86+
8287 // Show P2P compatibility
8388 println ! ( "🔗 P2P Compatibility:" ) ;
8489 show_p2p_compatibility ( & result. nat_type ) ;
8590 println ! ( ) ;
86-
91+
8792 // Recommendations
8893 println ! ( "💡 Recommendations:" ) ;
8994 match result. nat_type {
@@ -117,7 +122,7 @@ async fn main() {
117122 }
118123 }
119124 Err ( e) => {
120- eprintln ! ( "❌ STUN Discovery Failed: {}" , e ) ;
125+ eprintln ! ( "❌ STUN Discovery Failed: {e}" ) ;
121126 eprintln ! ( ) ;
122127 eprintln ! ( "Possible reasons:" ) ;
123128 eprintln ! ( " - No internet connection" ) ;
@@ -137,7 +142,7 @@ fn show_p2p_compatibility(nat_type: &NatType) {
137142 ( "Port-Restricted" , NatType :: PortRestricted ) ,
138143 ( "Symmetric NAT" , NatType :: Symmetric ) ,
139144 ] ;
140-
145+
141146 println ! ( " Success rates with different peer NAT types:" ) ;
142147 for ( name, peer_nat) in & scenarios {
143148 let rate = nat_type. hole_punch_success_rate ( peer_nat) ;
@@ -146,4 +151,3 @@ fn show_p2p_compatibility(nat_type: &NatType) {
146151 println ! ( " {:18} {:3}% {}" , name, percentage, bar) ;
147152 }
148153}
149-
0 commit comments