@@ -35,7 +35,6 @@ import (
35
35
"github.com/ethereum/go-ethereum/log"
36
36
"github.com/ethereum/go-ethereum/p2p/discover"
37
37
"github.com/ethereum/go-ethereum/p2p/enode"
38
- "github.com/ethereum/go-ethereum/p2p/enr"
39
38
"github.com/ethereum/go-ethereum/p2p/nat"
40
39
"github.com/ethereum/go-ethereum/p2p/netutil"
41
40
"golang.org/x/exp/slices"
@@ -195,6 +194,9 @@ type Server struct {
195
194
discmix * enode.FairMix
196
195
dialsched * dialScheduler
197
196
197
+ // This is read by the NAT port mapping loop.
198
+ portMappingRegister chan * portMapping
199
+
198
200
// Channels into the run loop.
199
201
quit chan struct {}
200
202
addtrusted chan * enode.Node
@@ -483,6 +485,11 @@ func (srv *Server) Start() (err error) {
483
485
if err := srv .setupLocalNode (); err != nil {
484
486
return err
485
487
}
488
+
489
+ // The NAT protocol mapping channel can receive up to two messages: one for
490
+ // enabling TCP port mapping, and one more for enabling the UDP port mapping.
491
+ srv .setupPortMapping ()
492
+
486
493
if srv .ListenAddr != "" {
487
494
if err := srv .setupListening (); err != nil {
488
495
return err
@@ -521,24 +528,6 @@ func (srv *Server) setupLocalNode() error {
521
528
srv .localnode .Set (e )
522
529
}
523
530
}
524
- switch srv .NAT .(type ) {
525
- case nil :
526
- // No NAT interface, do nothing.
527
- case nat.ExtIP :
528
- // ExtIP doesn't block, set the IP right away.
529
- ip , _ := srv .NAT .ExternalIP ()
530
- srv .localnode .SetStaticIP (ip )
531
- default :
532
- // Ask the router about the IP. This takes a while and blocks startup,
533
- // do it in the background.
534
- srv .loopWG .Add (1 )
535
- go func () {
536
- defer srv .loopWG .Done ()
537
- if ip , err := srv .NAT .ExternalIP (); err == nil {
538
- srv .localnode .SetStaticIP (ip )
539
- }
540
- }()
541
- }
542
531
return nil
543
532
}
544
533
@@ -657,12 +646,12 @@ func (srv *Server) setupListening() error {
657
646
658
647
// Update the local node record and map the TCP listening port if NAT is configured.
659
648
tcp , isTCP := listener .Addr ().(* net.TCPAddr )
660
- if srv . NAT != nil && isTCP && ! tcp .IP .IsLoopback () {
661
- srv .loopWG . Add ( 1 )
662
- go func () {
663
- srv . natMapLoop ( srv . NAT , "tcp" , tcp . Port , tcp . Port , "ethereum p2p" , nat . DefaultMapTimeout )
664
- srv . loopWG . Done ()
665
- }()
649
+ if isTCP && ! tcp .IP .IsLoopback () {
650
+ srv .portMappingRegister <- & portMapping {
651
+ protocol : "TCP" ,
652
+ name : "ethereum p2p" ,
653
+ port : tcp . Port ,
654
+ }
666
655
}
667
656
668
657
srv .loopWG .Add (1 )
@@ -690,78 +679,17 @@ func (srv *Server) setupUDPListening() (*net.UDPConn, error) {
690
679
srv .localnode .SetFallbackUDP (realaddr .Port )
691
680
srv .log .Debug ("UDP listener up" , "addr" , realaddr )
692
681
693
- // Enable port mapping if configured.
694
- if srv .NAT != nil && ! realaddr .IP .IsLoopback () {
695
- srv .loopWG .Add (1 )
696
- go func () {
697
- defer srv .loopWG .Done ()
698
- srv .natMapLoop (srv .NAT , "udp" , realaddr .Port , realaddr .Port , "ethereum p2p" , nat .DefaultMapTimeout )
699
- }()
682
+ if ! realaddr .IP .IsLoopback () {
683
+ srv .portMappingRegister <- & portMapping {
684
+ protocol : "UDP" ,
685
+ name : "ethereum peer discovery" ,
686
+ port : realaddr .Port ,
687
+ }
700
688
}
701
689
702
690
return conn , nil
703
691
}
704
692
705
- // natMapLoop performs initialization mapping for nat and repeats refresh.
706
- func (srv * Server ) natMapLoop (natm nat.Interface , protocol string , intport , extport int , name string , interval time.Duration ) {
707
- newLogger := func (p string , e int , i int , n nat.Interface ) log.Logger {
708
- return log .New ("proto" , p , "extport" , e , "intport" , i , "interface" , n )
709
- }
710
- log := newLogger (protocol , extport , intport , natm )
711
-
712
- var (
713
- hasMapping bool
714
- internal = intport
715
- external = extport
716
- mapTimeout = interval
717
- refresh = time .NewTimer (time .Duration (0 ))
718
- )
719
- // Set to 0 to perform initial port mapping. This will return C
720
- // immediately and set it to mapTimeout in the next loop.
721
- defer func () {
722
- refresh .Stop ()
723
- if hasMapping {
724
- log .Debug ("Deleting port mapping" )
725
- natm .DeleteMapping (protocol , external , internal )
726
- }
727
- }()
728
-
729
- loop:
730
- for {
731
- select {
732
- case <- srv .quit :
733
- return
734
-
735
- case <- refresh .C :
736
- log .Trace ("Start port mapping" )
737
- p , err := natm .AddMapping (protocol , external , internal , name , mapTimeout )
738
- if err != nil {
739
- hasMapping = false
740
- log .Debug ("Couldn't add port mapping" , "err" , err )
741
- continue loop
742
- }
743
- // It was mapped!
744
- hasMapping = true
745
- if p != uint16 (external ) {
746
- external = int (p )
747
- log = newLogger (protocol , external , internal , natm )
748
- log .Info ("NAT mapped alternative port" )
749
- } else {
750
- log .Info ("NAT mapped port" )
751
- }
752
-
753
- // Update port in local ENR.
754
- switch protocol {
755
- case "tcp" :
756
- srv .localnode .Set (enr .TCP (external ))
757
- case "udp" :
758
- srv .localnode .SetFallbackUDP (external )
759
- }
760
- refresh .Reset (mapTimeout )
761
- }
762
- }
763
- }
764
-
765
693
// doPeerOp runs fn on the main loop.
766
694
func (srv * Server ) doPeerOp (fn peerOpFunc ) {
767
695
select {
0 commit comments