@@ -25,7 +25,9 @@ use std::{
25
25
task:: { Context , Poll } ,
26
26
time:: Duration ,
27
27
} ;
28
+ use tracing:: error;
28
29
30
+ use crate :: net_if:: resolve_net_if_ip;
29
31
#[ cfg( feature = "serde" ) ]
30
32
use serde_with:: { DeserializeFromStr , SerializeDisplay } ;
31
33
@@ -48,6 +50,8 @@ pub enum NatResolver {
48
50
PublicIp ,
49
51
/// Use the given [`IpAddr`]
50
52
ExternalIp ( IpAddr ) ,
53
+ /// Resolve external IP via the network interface.
54
+ NetIf ,
51
55
/// Resolve nothing
52
56
None ,
53
57
}
@@ -66,6 +70,7 @@ impl fmt::Display for NatResolver {
66
70
Self :: Upnp => f. write_str ( "upnp" ) ,
67
71
Self :: PublicIp => f. write_str ( "publicip" ) ,
68
72
Self :: ExternalIp ( ip) => write ! ( f, "extip:{ip}" ) ,
73
+ Self :: NetIf => f. write_str ( "netif" ) ,
69
74
Self :: None => f. write_str ( "none" ) ,
70
75
}
71
76
}
@@ -91,6 +96,7 @@ impl FromStr for NatResolver {
91
96
"upnp" => Self :: Upnp ,
92
97
"none" => Self :: None ,
93
98
"publicip" | "public-ip" => Self :: PublicIp ,
99
+ "netif" => Self :: NetIf ,
94
100
s => {
95
101
let Some ( ip) = s. strip_prefix ( "extip:" ) else {
96
102
return Err ( ParseNatResolverError :: UnknownVariant ( format ! (
@@ -185,6 +191,13 @@ pub async fn external_addr_with(resolver: NatResolver) -> Option<IpAddr> {
185
191
match resolver {
186
192
NatResolver :: Any | NatResolver :: Upnp | NatResolver :: PublicIp => resolve_external_ip ( ) . await ,
187
193
NatResolver :: ExternalIp ( ip) => Some ( ip) ,
194
+ NatResolver :: NetIf => match resolve_net_if_ip ( DEFAULT_NET_IF_NAME ) {
195
+ Ok ( ip) => Some ( ip) ,
196
+ Err ( err) => {
197
+ error ! ( "Failed to resolve network interface IP: {}" , err) ;
198
+ None
199
+ }
200
+ } ,
188
201
NatResolver :: None => None ,
189
202
}
190
203
}
0 commit comments