@@ -11,6 +11,7 @@ import (
1111 "errors"
1212 "fmt"
1313 "io"
14+ "net"
1415 "os"
1516 "slices"
1617 "strings"
@@ -28,6 +29,7 @@ import (
2829 "github.com/libp2p/go-libp2p/p2p/discovery/mdns"
2930 drouting "github.com/libp2p/go-libp2p/p2p/discovery/routing"
3031 "github.com/multiformats/go-multiaddr"
32+ manet "github.com/multiformats/go-multiaddr/net"
3133
3234 ds "github.com/ipfs/go-datastore"
3335 dssync "github.com/ipfs/go-datastore/sync"
@@ -114,12 +116,17 @@ func NewClient(config Config) (Client, error) {
114116 return nil , fmt .Errorf ("failed to create pubsub: %w" , err )
115117 }
116118
117- // Set up mDNS discovery
118- mdnsService := mdns .NewMdnsService (h , "" , & discoveryNotifee {h : h , ctx : ctx , logger : clientLogger })
119- if err := mdnsService .Start (); err != nil {
120- clientLogger .Errorf ("mDNS failed to start: %v" , err )
119+ // Set up mDNS discovery (only if explicitly enabled)
120+ var mdnsService mdns.Service
121+ if config .EnableMDNS {
122+ mdnsService = mdns .NewMdnsService (h , "" , & discoveryNotifee {h : h , ctx : ctx , logger : clientLogger })
123+ if err := mdnsService .Start (); err != nil {
124+ clientLogger .Errorf ("mDNS failed to start: %v" , err )
125+ } else {
126+ clientLogger .Infof ("mDNS discovery started" )
127+ }
121128 } else {
122- clientLogger .Infof ("mDNS discovery started " )
129+ clientLogger .Infof ("mDNS discovery disabled (production safe default) " )
123130 }
124131
125132 c := & client {
@@ -623,6 +630,15 @@ func (c *client) connectToDiscoveredPeer(ctx context.Context, peerInfo peer.Addr
623630 return
624631 }
625632
633+ // Filter private IPs unless explicitly allowed (default: filter for production safety)
634+ if ! c .config .AllowPrivateIPs {
635+ peerInfo .Addrs = filterPrivateAddrs (peerInfo .Addrs )
636+ if len (peerInfo .Addrs ) == 0 {
637+ // All addresses were private, skip this peer
638+ return
639+ }
640+ }
641+
626642 if err := c .host .Connect (ctx , peerInfo ); err != nil {
627643 if c .shouldLogConnectionError (err ) {
628644 c .logger .Debugf ("Failed to connect to discovered peer %s: %v" , peerInfo .ID .String (), err )
@@ -913,3 +929,79 @@ func PrivateKeyFromHex(keyHex string) (crypto.PrivKey, error) {
913929
914930 return priv , nil
915931}
932+
933+ // filterPrivateAddrs filters out private/local IP addresses from a list of multiaddrs.
934+ // Returns only public routable addresses suitable for cloud/shared hosting environments.
935+ func filterPrivateAddrs (addrs []multiaddr.Multiaddr ) []multiaddr.Multiaddr {
936+ filtered := make ([]multiaddr.Multiaddr , 0 , len (addrs ))
937+
938+ for _ , addr := range addrs {
939+ // Convert multiaddr to net.Addr to check if it's private
940+ netAddr , err := manet .ToNetAddr (addr )
941+ if err != nil {
942+ // If we can't parse it, skip it
943+ continue
944+ }
945+
946+ // Extract IP address
947+ var ip net.IP
948+ switch v := netAddr .(type ) {
949+ case * net.TCPAddr :
950+ ip = v .IP
951+ case * net.UDPAddr :
952+ ip = v .IP
953+ default :
954+ // Unknown address type, skip it
955+ continue
956+ }
957+
958+ // Filter out private/local addresses
959+ if isPrivateIP (ip ) {
960+ continue
961+ }
962+
963+ filtered = append (filtered , addr )
964+ }
965+
966+ return filtered
967+ }
968+
969+ // isPrivateIP checks if an IP address is private or local.
970+ // Returns true for:
971+ // - RFC1918 private networks (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
972+ // - Link-local addresses (169.254.0.0/16)
973+ // - Loopback addresses (127.0.0.0/8)
974+ // - IPv6 unique local addresses (fc00::/7)
975+ // - IPv6 link-local addresses (fe80::/10)
976+ func isPrivateIP (ip net.IP ) bool {
977+ if ip .IsLoopback () || ip .IsLinkLocalUnicast () || ip .IsLinkLocalMulticast () {
978+ return true
979+ }
980+
981+ // Check for private IPv4 ranges
982+ if ip4 := ip .To4 (); ip4 != nil {
983+ // 10.0.0.0/8
984+ if ip4 [0 ] == 10 {
985+ return true
986+ }
987+ // 172.16.0.0/12
988+ if ip4 [0 ] == 172 && ip4 [1 ] >= 16 && ip4 [1 ] <= 31 {
989+ return true
990+ }
991+ // 192.168.0.0/16
992+ if ip4 [0 ] == 192 && ip4 [1 ] == 168 {
993+ return true
994+ }
995+ // 169.254.0.0/16 (link-local)
996+ if ip4 [0 ] == 169 && ip4 [1 ] == 254 {
997+ return true
998+ }
999+ }
1000+
1001+ // Check for IPv6 unique local addresses (fc00::/7)
1002+ if len (ip ) == net .IPv6len && ip [0 ]& 0xfe == 0xfc {
1003+ return true
1004+ }
1005+
1006+ return false
1007+ }
0 commit comments