Skip to content

Commit

Permalink
feat: support ipv6 link-local address
Browse files Browse the repository at this point in the history
  • Loading branch information
jclab-joseph committed Dec 6, 2023
1 parent 97b4ca0 commit 1f421f9
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 8 deletions.
13 changes: 9 additions & 4 deletions p2p/host/basic/basic_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,22 +782,27 @@ func (h *BasicHost) Addrs() []ma.Multiaddr {

// Copy addrs slice since we'll be modifying it.
addrsOld := addrs
addrs = make([]ma.Multiaddr, len(addrsOld))
copy(addrs, addrsOld)
addrs = make([]ma.Multiaddr, 0, len(addrsOld))

for i, addr := range addrs {
for _, addr := range addrsOld {
if ok, n := libp2pwebtransport.IsWebtransportMultiaddr(addr); ok && n == 0 {
t := s.TransportForListening(addr)
tpt, ok := t.(addCertHasher)
if !ok {
addrs = append(addrs, addr)
continue
}
addrWithCerthash, added := tpt.AddCertHashes(addr)
if !added {
addrs = append(addrs, addr)
log.Debug("Couldn't add certhashes to webtransport multiaddr because we aren't listening on webtransport")
continue
}
addrs[i] = addrWithCerthash
addrs = append(addrs, addrWithCerthash)
} else if manet.IsIP6LinkLocal(addr) {
continue
} else {
addrs = append(addrs, addr)
}
}
return addrs
Expand Down
2 changes: 1 addition & 1 deletion p2p/net/reuseport/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (d *dialer) DialContext(ctx context.Context, network, addr string) (net.Con
return nil, err
}
ip := tcpAddr.IP
if !ip.IsLoopback() && !ip.IsGlobalUnicast() {
if !ip.IsLoopback() && !ip.IsGlobalUnicast() && !ip.IsLinkLocalUnicast() {
return nil, fmt.Errorf("undialable IP: %s", ip)
}

Expand Down
2 changes: 0 additions & 2 deletions p2p/net/swarm/swarm_dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,6 @@ func (s *Swarm) filterKnownUndialables(p peer.ID, addrs []ma.Multiaddr) (goodAdd
}
return true
},
// TODO: Consider allowing link-local addresses
func(addr ma.Multiaddr) bool { return !manet.IsIP6LinkLocal(addr) },
func(addr ma.Multiaddr) bool {
if s.gater != nil && !s.gater.InterceptAddrDial(p, addr) {
addrErrs = append(addrErrs, TransportError{Address: addr, Cause: ErrGaterDisallowedConnection})
Expand Down
5 changes: 4 additions & 1 deletion p2p/transport/tcp/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ func NewTCPTransport(upgrader transport.Upgrader, rcmgr network.ResourceManager,
return tr, nil
}

var dialMatcher = mafmt.And(mafmt.IP, mafmt.Base(ma.P_TCP))
var dialMatcher = mafmt.Or(
mafmt.And(mafmt.IP, mafmt.Base(ma.P_TCP)),
mafmt.And(mafmt.Base(ma.P_IP6ZONE), mafmt.IP, mafmt.Base(ma.P_TCP)),
)

// CanDial returns true if this transport believes it can dial the given
// multiaddr.
Expand Down
64 changes: 64 additions & 0 deletions p2p/transport/tcp/tcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package tcp
import (
"context"
"errors"
"net"
"testing"

"github.com/libp2p/go-libp2p/core/crypto"
Expand Down Expand Up @@ -46,6 +47,69 @@ func TestTcpTransport(t *testing.T) {
envReuseportVal = true
}

func TestTcpTransportCanDialToLinkLocalAddress(t *testing.T) {
addr := ma.StringCast("/ip6zone/eth0/ip6/fe80::fc54:ff:fe43:e553/tcp/1234")

var u transport.Upgrader
tpt, err := NewTCPTransport(u, nil)
require.NoError(t, err)

if !tpt.CanDial(addr) {
t.Fatal("should be able to dial ip6zone")
}
}

func TestTcpTransportWithLinkLocalAddress(t *testing.T) {
ifaces, err := net.Interfaces()
if err != nil {
t.Error(err)
return
}

var targetAddr ma.Multiaddr

findInterface:
for _, iface := range ifaces {
addrs, err := iface.Addrs()
if err == nil {
for _, a := range addrs {
addr, err := manet.FromNetAddr(a)
if err == nil {
if manet.IsIP6LinkLocal(addr) {
targetAddr = ma.StringCast("/ip6zone/" + iface.Name + addr.String())
break findInterface
}
}
}
}
}

if targetAddr == nil {
t.Fail()
return
}

for i := 0; i < 2; i++ {
peerA, ia := makeInsecureMuxer(t)
_, ib := makeInsecureMuxer(t)

ua, err := tptu.New(ia, muxers, nil, nil, nil)
require.NoError(t, err)
ta, err := NewTCPTransport(ua, nil)
require.NoError(t, err)
ub, err := tptu.New(ib, muxers, nil, nil, nil)
require.NoError(t, err)
tb, err := NewTCPTransport(ub, nil)
require.NoError(t, err)

zero := targetAddr.String() + "/tcp/0"
ttransport.SubtestTransport(t, ta, tb, zero, peerA)

envReuseportVal = false
}
envReuseportVal = true
}

func TestTcpTransportWithMetrics(t *testing.T) {
peerA, ia := makeInsecureMuxer(t)
_, ib := makeInsecureMuxer(t)
Expand Down

0 comments on commit 1f421f9

Please sign in to comment.