@@ -416,6 +416,63 @@ ENR as its potential relay, the longer time that has passed since a peer sent us
416
416
the less guarantee we have that the peer is in fact connected to the owner of that ENR and
417
417
hence of its ability to relay.
418
418
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
+
419
476
[ EIP-778 ] : ../enr.md
420
477
[ identity scheme ] : ../enr.md#record-structure
421
478
[ message packet ] : ./discv5-wire.md#ordinary-message-packet-flag--0
@@ -430,6 +487,8 @@ hence of its ability to relay.
430
487
[ RELAYMSG ] : ./discv5-wire.md#relaymsg-notification-0x08
431
488
432
489
[ 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
433
492
[ natpaper ] : https://pdos.csail.mit.edu/papers/p2pnat.pdf
434
493
[ RFC4787 ] : https://datatracker.ietf.org/doc/html/rfc4787
435
494
[ RFC6146 ] : https://datatracker.ietf.org/doc/html/rfc6146
0 commit comments