@@ -416,6 +416,63 @@ ENR as its potential relay, the longer time that has passed since a peer sent us
416416the less guarantee we have that the peer is in fact connected to the owner of that ENR and
417417hence of its ability to relay.
418418
419+ ### Job of keeping the hole punched falls on Bob and Bob's incentive to do so  
420+ 
421+ UDP session table entry lifetimes are configurable, though a common lower bound is 20
422+ seconds. Bob must periodically reset the session table entry for Alice in its NAT to keep
423+ the hole for Alice punched. If Alice too is behind NAT, it must do the same for Bob.
424+ Implementations must ensure, when a node behind NAT does not send a packet to a peer
425+ within the entry lifetime then an empty packet is sent that is dropped by the peer.
426+ 
427+ NAT hole punching unavoidably creates overhead for all nodes in the network but once a
428+ hole is punched, keeping it punched requires no interaction between peers. The incentive
429+ for nodes behind NAT to keep holes for its peers punched is to avoid reestablishing a
430+ session. If there is no hole for Alice in Bob's NAT when Alice carries out a [ liveness
431+ check] , Bob is considered offline and the session to Bob useless. If the node behind NAT
432+ intends to frequently communicate with a peer, reestablishing the session is more costly
433+ than managing the interval of sent packets to that peer.
434+ 
435+ ### Discovering if the local node is behind NAT and must keep holes for peers punched  
436+ 
437+ A node may at start-up be assigned an externally reachable socket to advertise as well as
438+ a listen socket. If those sockets are not equivalent, the node is behind NAT and the
439+ [ mechanism for keeping holes punched]  is activated. Like so, a node assumes it is behind
440+ NAT if an externally reachable socket is omitted from the initial configuration and must
441+ activate the mechanism for keeping holes punched. The [ runtime address discovery] 
442+ mechanism can discovery the external endpoint address used by the local node. Once a new
443+ externally reachable endpoint is known, implementations will try to bind to its IP address
444+ at some number of randomly selected ports from a given range of probably unused ports. If
445+ binding succeeds with any port, the node is not behind NAT and the mechanism for keeping
446+ holes punched is deactivated.
447+ 
448+ This solution assumes, in most scenarios where port-forwarding cannot be configured the
449+ local node host's address is private to the address realm of the device operating the NAT
450+ level furthest from the local node host. If the host and NAT device use the same IP
451+ address, binding will always succeed, so this method may give a false negative. However,
452+ this is not detrimental. A node behind NAT that deactivates the mechanism for keeping
453+ holes punched will more frequently have to re-establish sessions to its peers.
454+ 
455+ ### Limiting resource consumption of peers behind symmetric NATs, useful for light-clients  
456+ 
457+ Peers with unreachable ENRs do not get inserted into node table buckets. Nodes that are
458+ behind symmetric NATs will naturally never succeed in pinpointing one external socket for
459+ peers to reach them on by [ runtime address discovery]  and therefore their unreachable ENRs
460+ will never update to reachable ENRs.
461+ 
462+ This means, these peers will never respond to requests, as only peers in the node table
463+ are sent requests. This does not cohere with the p2p-model, rather the server-client model
464+ where the peer with a unreachable ENR acts as the client. This misalignment is especially
465+ bothersome for well behaving (externally reachable) light-clients operating on limited
466+ resources. Discv5.2 corrects this side-effect of runtime address discovery by introducing
467+ a configurable limit to the number of sessions at a time with peers with unreachable ENRs,
468+ the lower limit being 1. Nodes must accept sessions with at least one peer with a
469+ unreachable ENR to for runtime address discovery to be enabled on the discv5.2 network.
470+ 
471+ ### Fault tolerance  
472+ 
473+ As was already the case in discv5, if a request to a node times out, (after the configured
474+ number of retries) that peer is considered unresponsive and the session can be failed.
475+ 
419476[ EIP-778 ] : ../enr.md 
420477[ identity scheme ] : ../enr.md#record-structure 
421478[ message packet ] : ./discv5-wire.md#ordinary-message-packet-flag--0 
@@ -430,6 +487,8 @@ hence of its ability to relay.
430487[ RELAYMSG ] : ./discv5-wire.md#relaymsg-notification-0x08 
431488
432489[ Sessions ] : ./discv5-theory.md#sessions 
490+ [ runtime address discovery ] : ./discv5-theory.md#maintaining-the-local-node-record 
491+ [ mechanism for keeping holes punched ] : ./discv5-theory.md#job-of-keeping-the-hole-punched-falls-on-bob-and-bobs-incentive-to-do-so 
433492[ natpaper ] : https://pdos.csail.mit.edu/papers/p2pnat.pdf 
434493[ RFC4787 ] : https://datatracker.ietf.org/doc/html/rfc4787 
435494[ RFC6146 ] : https://datatracker.ietf.org/doc/html/rfc6146 
0 commit comments