@@ -20,6 +20,7 @@ use current_mapping::CurrentMapping;
2020mod current_mapping;
2121mod mapping;
2222mod metrics;
23+ mod nat_pmp;
2324mod pcp;
2425mod upnp;
2526
@@ -38,20 +39,20 @@ const UNAVAILABILITY_TRUST_DURATION: Duration = Duration::from_secs(5);
3839
3940/// Output of a port mapping probe.
4041#[ derive( Debug , Clone , PartialEq , Eq , derive_more:: Display ) ]
41- #[ display( "portmap={{ UPnP: {upnp}, PMP: {pmp }, PCP: {pcp} }}" ) ]
42+ #[ display( "portmap={{ UPnP: {upnp}, PMP: {nat_pmp }, PCP: {pcp} }}" ) ]
4243pub struct ProbeOutput {
4344 /// If UPnP can be considered available.
4445 pub upnp : bool ,
4546 /// If PCP can be considered available.
4647 pub pcp : bool ,
4748 /// If PMP can be considered available.
48- pub pmp : bool ,
49+ pub nat_pmp : bool ,
4950}
5051
5152impl ProbeOutput {
5253 /// Indicates if all port mapping protocols are available.
5354 pub fn all_available ( & self ) -> bool {
54- self . upnp && self . pcp && self . pmp
55+ self . upnp && self . pcp && self . nat_pmp
5556 }
5657}
5758
@@ -214,8 +215,8 @@ struct Probe {
214215 last_upnp_gateway_addr : Option < ( upnp:: Gateway , Instant ) > ,
215216 /// Last time PCP was seen.
216217 last_pcp : Option < Instant > ,
217- // TODO(@divma): PMP placeholder .
218- last_pmp : Option < Instant > ,
218+ /// Last time NAT- PMP was seen .
219+ last_nat_pmp : Option < Instant > ,
219220}
220221
221222impl Default for Probe {
@@ -224,7 +225,7 @@ impl Default for Probe {
224225 last_probe : Instant :: now ( ) - AVAILABILITY_TRUST_DURATION ,
225226 last_upnp_gateway_addr : None ,
226227 last_pcp : None ,
227- last_pmp : None ,
228+ last_nat_pmp : None ,
228229 }
229230 }
230231}
@@ -237,11 +238,11 @@ impl Probe {
237238 local_ip : Ipv4Addr ,
238239 gateway : Ipv4Addr ,
239240 ) -> Probe {
240- let ProbeOutput { upnp, pcp, pmp : _ } = output;
241+ let ProbeOutput { upnp, pcp, nat_pmp } = output;
241242 let Config {
242243 enable_upnp,
243244 enable_pcp,
244- enable_nat_pmp : _ ,
245+ enable_nat_pmp,
245246 } = config;
246247 let mut upnp_probing_task = util:: MaybeFuture {
247248 inner : ( enable_upnp && !upnp) . then ( || {
@@ -264,31 +265,37 @@ impl Probe {
264265 } ) ,
265266 } ;
266267
267- let pmp_probing_task = async { None } ;
268+ let mut nat_pmp_probing_task = util:: MaybeFuture {
269+ inner : ( enable_nat_pmp && !nat_pmp) . then ( || {
270+ Box :: pin ( async {
271+ nat_pmp:: probe_available ( local_ip, gateway)
272+ . await
273+ . then ( Instant :: now)
274+ } )
275+ } ) ,
276+ } ;
268277
269278 if upnp_probing_task. inner . is_some ( ) {
270279 inc ! ( Metrics , upnp_probes) ;
271280 }
272281
273282 let mut upnp_done = upnp_probing_task. inner . is_none ( ) ;
274283 let mut pcp_done = pcp_probing_task. inner . is_none ( ) ;
275- let mut pmp_done = true ;
276-
277- tokio:: pin!( pmp_probing_task) ;
284+ let mut nat_pmp_done = nat_pmp_probing_task. inner . is_none ( ) ;
278285
279286 let mut probe = Probe :: default ( ) ;
280287
281- while !upnp_done || !pcp_done || !pmp_done {
288+ while !upnp_done || !pcp_done || !nat_pmp_done {
282289 tokio:: select! {
283290 last_upnp_gateway_addr = & mut upnp_probing_task, if !upnp_done => {
284291 trace!( "tick: upnp probe ready" ) ;
285292 probe. last_upnp_gateway_addr = last_upnp_gateway_addr;
286293 upnp_done = true ;
287294 } ,
288- last_pmp = & mut pmp_probing_task , if !pmp_done => {
289- trace!( "tick: pmp probe ready" ) ;
290- probe. last_pmp = last_pmp ;
291- pmp_done = true ;
295+ last_nat_pmp = & mut nat_pmp_probing_task , if !nat_pmp_done => {
296+ trace!( "tick: nat_pmp probe ready" ) ;
297+ probe. last_nat_pmp = last_nat_pmp ;
298+ nat_pmp_done = true ;
292299 } ,
293300 last_pcp = & mut pcp_probing_task, if !pcp_done => {
294301 trace!( "tick: pcp probe ready" ) ;
@@ -318,10 +325,13 @@ impl Probe {
318325 . map ( |last_probed| * last_probed + AVAILABILITY_TRUST_DURATION > now)
319326 . unwrap_or_default ( ) ;
320327
321- // not probing for now
322- let pmp = false ;
328+ let nat_pmp = self
329+ . last_nat_pmp
330+ . as_ref ( )
331+ . map ( |last_probed| * last_probed + AVAILABILITY_TRUST_DURATION > now)
332+ . unwrap_or_default ( ) ;
323333
324- ProbeOutput { upnp, pcp, pmp }
334+ ProbeOutput { upnp, pcp, nat_pmp }
325335 }
326336
327337 /// Updates a probe with the `Some` values of another probe that is _assumed_ newer.
@@ -330,7 +340,7 @@ impl Probe {
330340 last_probe,
331341 last_upnp_gateway_addr,
332342 last_pcp,
333- last_pmp ,
343+ last_nat_pmp ,
334344 } = probe;
335345 if last_upnp_gateway_addr. is_some ( ) {
336346 inc ! ( Metrics , upnp_available) ;
@@ -359,8 +369,8 @@ impl Probe {
359369 inc ! ( Metrics , pcp_available) ;
360370 self . last_pcp = last_pcp;
361371 }
362- if last_pmp . is_some ( ) {
363- self . last_pmp = last_pmp ;
372+ if last_nat_pmp . is_some ( ) {
373+ self . last_nat_pmp = last_nat_pmp ;
364374 }
365375
366376 self . last_probe = last_probe;
@@ -571,7 +581,7 @@ impl Service {
571581 Err ( e) => return debug ! ( "can't get mapping: {e}" ) ,
572582 } ;
573583
574- let ProbeOutput { upnp, pcp, pmp : _ } = self . full_probe . output ( ) ;
584+ let ProbeOutput { upnp, pcp, nat_pmp } = self . full_probe . output ( ) ;
575585
576586 debug ! ( "getting a port mapping for {local_ip}:{local_port} -> {external_addr:?}" ) ;
577587 let recently_probed =
@@ -583,6 +593,10 @@ impl Service {
583593 self . mapping_task = if pcp || ( !recently_probed && self . config . enable_pcp ) {
584594 let task = mapping:: Mapping :: new_pcp ( local_ip, local_port, gateway, external_addr) ;
585595 Some ( tokio:: spawn ( task) . into ( ) )
596+ } else if nat_pmp || ( !recently_probed && self . config . enable_nat_pmp ) {
597+ let task =
598+ mapping:: Mapping :: new_nat_pmp ( local_ip, local_port, gateway, external_addr) ;
599+ Some ( tokio:: spawn ( task) . into ( ) )
586600 } else if upnp || self . config . enable_upnp {
587601 let external_port = external_addr. map ( |( _addr, port) | port) ;
588602 let gateway = self
0 commit comments