99 "io"
1010 "log"
1111 "net"
12- "net/http"
1312 "os"
1413 "sync"
1514 "time"
@@ -23,7 +22,6 @@ import (
2322 "github.com/libp2p/go-libp2p/core/peer"
2423 "github.com/libp2p/go-libp2p/p2p/discovery/mdns"
2524 drouting "github.com/libp2p/go-libp2p/p2p/discovery/routing"
26- "github.com/libp2p/go-libp2p/p2p/net/conngater"
2725 "github.com/multiformats/go-multiaddr"
2826)
2927
@@ -90,88 +88,37 @@ func NewClient(config Config) (P2PClient, error) {
9088 logger .Infof ("Using custom announce addresses: %v" , config .AnnounceAddrs )
9189 }
9290
93- // define address factory to remove all private IPs from being broadcasted
94- addressFactory := func (addrs []multiaddr.Multiaddr ) []multiaddr.Multiaddr {
95- var publicAddrs []multiaddr.Multiaddr
96- for _ , addr := range addrs {
97- // if IP is not private, add it to the list
98- if ! isPrivateIP (addr ) || config .AllowPrivateIPs {
99- publicAddrs = append (publicAddrs , addr )
100- }
101- }
102- // If a user specified a broadcast IP append it here
103- if len (announceAddrs ) > 0 {
104- // here we're appending the external facing multiaddr we created above to the addressFactory so it will be broadcast out when I connect to a bootstrap node.
105- publicAddrs = append (publicAddrs , announceAddrs ... )
106- }
107-
108- // If we still don't have any advertisable addresses then attempt to grab it from `https://ifconfig.me/ip`
109- if len (publicAddrs ) == 0 {
110- // If no public addresses are set, let's attempt to grab it publicly
111- // Ignore errors because we don't care if we can't find it
112- ifconfig , err := GetPublicIP (context .Background ())
113- if err != nil {
114- logger .Infof ("Failed to get public IP address: %v" , err )
115- }
116- if len (ifconfig ) > 0 {
117- addr , err := multiaddr .NewMultiaddr (fmt .Sprintf ("/ip4/%s/tcp/%d" , ifconfig , config .Port ))
118- if err != nil {
119- logger .Infof ("Failed to create multiaddr from public IP: %v" , err )
120- }
121- if addr != nil {
122- publicAddrs = append (publicAddrs , addr )
123- }
124- }
91+ // Simple address factory to only use custom announce addresses if provided
92+ // Otherwise let libp2p/AutoNAT handle address detection automatically
93+ var addressFactory func ([]multiaddr.Multiaddr ) []multiaddr.Multiaddr
94+ if len (announceAddrs ) > 0 {
95+ addressFactory = func ([]multiaddr.Multiaddr ) []multiaddr.Multiaddr {
96+ return announceAddrs
12597 }
126-
127- return publicAddrs
98+ logger .Infof ("Using only custom announce addresses for advertising" )
12899 }
129100
130- // Create an IP filter to optionally block private network ranges from being dialed
131- ipFilter , err := conngater .NewBasicConnectionGater (nil )
132- if err != nil {
133- return nil , err
134- }
135-
136- // By default, filter private IPs
137- if ! config .AllowPrivateIPs {
138- // Add private IP blocks to be filtered out
139- for _ , cidr := range []string {
140- "10.0.0.0/8" , // Private network 10.0.0.0 to 10.255.255.255
141- "172.16.0.0/12" , // Private network 172.16.0.0 to 172.31.255.255
142- "192.168.0.0/16" , // Private network 192.168.0.0 to 192.168.255.255
143- "127.0.0.0/16" , // Local network
144- "100.64.0.0/10" , // Shared Address Space
145- "169.254.0.0/16" , // Link-local addresses
146- } {
147- var ipnet * net.IPNet
148- var err error
149- _ , ipnet , err = net .ParseCIDR (cidr )
150- if err != nil {
151- return nil , err
152- }
153- err = ipFilter .BlockSubnet (ipnet )
154- if err != nil {
155- continue
156- }
157- }
158- }
101+ // Get bootstrap peers from DHT library - these can act as relays
102+ bootstrapPeers := dht .GetDefaultBootstrapPeerAddrInfos ()
159103
160- // Create libp2p host
104+ // Create libp2p host with NAT traversal options
161105 hostOpts = append (hostOpts ,
162106 libp2p .ListenAddrStrings (
163107 fmt .Sprintf ("/ip4/0.0.0.0/tcp/%d" , config .Port ), // Listen on all interfaces
164108 fmt .Sprintf ("/ip6/::/tcp/%d" , config .Port ),
165109 ),
166- libp2p .NATPortMap (), // Try UPnP/NAT-PMP for automatic port forwarding
167- libp2p .EnableNATService (), // AutoNAT to detect if we're reachable
168- libp2p .EnableHolePunching (), // DCUtR protocol for NAT hole punching
169- libp2p .EnableRelay (), // Act as relay for others
170- libp2p .EnableAutoRelayWithStaticRelays ([]peer.AddrInfo {}), // Use relays if we're unreachable
171- libp2p .AddrsFactory (addressFactory ),
172- libp2p .ConnectionGater (ipFilter ),
110+ libp2p .NATPortMap (), // Try UPnP/NAT-PMP for automatic port forwarding
111+ libp2p .EnableNATService (), // AutoNAT to detect if we're reachable
112+ libp2p .EnableHolePunching (), // DCUtR protocol for NAT hole punching
113+ libp2p .EnableRelay (), // Act as relay for others
114+ libp2p .EnableAutoRelayWithStaticRelays (bootstrapPeers ), // Use bootstrap nodes as potential relays
173115 )
174116
117+ // Only apply address factory if custom announce addresses are provided
118+ if addressFactory != nil {
119+ hostOpts = append (hostOpts , libp2p .AddrsFactory (addressFactory ))
120+ }
121+
175122 h , err := libp2p .New (hostOpts ... )
176123 if err != nil {
177124 cancel ()
@@ -182,7 +129,6 @@ func NewClient(config Config) (P2PClient, error) {
182129 logger .Infof ("Listening on: %v" , h .Addrs ())
183130
184131 // Set up DHT with bootstrap peers
185- bootstrapPeers := dht .GetDefaultBootstrapPeerAddrInfos ()
186132 kadDHT , err := dht .New (ctx , h , dht .Mode (dht .ModeServer ), dht .BootstrapPeers (bootstrapPeers ... ))
187133 if err != nil {
188134 h .Close ()
@@ -756,32 +702,3 @@ func extractIPFromMultiaddr(addr multiaddr.Multiaddr) (string, error) {
756702 return addr .ValueForProtocol (multiaddr .P_IP6 )
757703}
758704
759- // GetPublicIP fetches the public IP address from ifconfig.me
760- func GetPublicIP (ctx context.Context ) (string , error ) {
761- transport := & http.Transport {
762- DialContext : func (ctx context.Context , _ , addr string ) (net.Conn , error ) {
763- // Force the use of IPv4 by specifying 'tcp4' as the network
764- return (& net.Dialer {}).DialContext (ctx , "tcp4" , addr )
765- },
766- TLSHandshakeTimeout : 10 * time .Second ,
767- }
768- client := & http.Client {
769- Transport : transport ,
770- }
771- req , err := http .NewRequestWithContext (ctx , "GET" , "https://ifconfig.me/ip" , nil )
772- if err != nil {
773- return "" , err
774- }
775-
776- resp , err := client .Do (req )
777- if err != nil {
778- return "" , err
779- }
780-
781- body , err := io .ReadAll (resp .Body )
782- if err != nil {
783- return "" , err
784- }
785-
786- return string (body ), resp .Body .Close ()
787- }
0 commit comments