Skip to content

Commit

Permalink
feat: support ipv6 link-local address for mdns
Browse files Browse the repository at this point in the history
  • Loading branch information
jclab-joseph committed Dec 6, 2023
1 parent 97b4ca0 commit b805866
Showing 1 changed file with 35 additions and 5 deletions.
40 changes: 35 additions & 5 deletions p2p/discovery/mdns/mdns.go
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"io"
"math/rand"
"net"
"strings"
"sync"

Expand Down Expand Up @@ -124,6 +125,10 @@ func (s *mdnsService) startServer() error {
var txts []string
for _, addr := range addrs {
if manet.IsThinWaist(addr) { // don't announce circuit addresses
if manet.IsIP6LinkLocal(addr) {
_, addr = ma.SplitFirst(addr)
}

txts = append(txts, dnsaddrPrefix+addr.String())
}
}
Expand Down Expand Up @@ -159,21 +164,26 @@ func (s *mdnsService) startResolver(ctx context.Context) {
// We only care about the TXT records.
// Ignore A, AAAA and PTR.
addrs := make([]ma.Multiaddr, 0, len(entry.Text)) // assume that all TXT records are dnsaddrs
for _, s := range entry.Text {
if !strings.HasPrefix(s, dnsaddrPrefix) {
for _, txt := range entry.Text {
if !strings.HasPrefix(txt, dnsaddrPrefix) {
log.Debug("missing dnsaddr prefix")
continue
}
addr, err := ma.NewMultiaddr(s[len(dnsaddrPrefix):])
addr, err := ma.NewMultiaddr(txt[len(dnsaddrPrefix):])
if err != nil {
log.Debugf("failed to parse multiaddr: %s", err)
log.Debugf("failed to parse multiaddr: %txt", err)
continue
}
if manet.IsIP6LinkLocal(addr) {
ifaces, _ := net.Interfaces()
addr = s.fixIP6LinkLocalAddress(entry.ReceivedIfIndex, entry.ReceivedSrc, addr)
_ = ifaces
}
addrs = append(addrs, addr)
}
infos, err := peer.AddrInfosFromP2pAddrs(addrs...)
if err != nil {
log.Debugf("failed to get peer info: %s", err)
log.Debugf("failed to get peer info: %txt", err)
continue
}
for _, info := range infos {
Expand All @@ -192,6 +202,26 @@ func (s *mdnsService) startResolver(ctx context.Context) {
}()
}

func (s *mdnsService) fixIP6LinkLocalAddress(ifIndex int, src net.Addr, addr ma.Multiaddr) ma.Multiaddr {
var ifName string
udpAddr, ok := src.(*net.UDPAddr)
if ok && len(udpAddr.Zone) > 0 {
ifName = udpAddr.Zone
} else if ifIndex > 0 {
iface, err := net.InterfaceByIndex(ifIndex)
if err == nil {
ifName = iface.Name
}
}
if len(ifName) > 0 {
prefix, err := ma.NewMultiaddr("/ip6zone/" + ifName)
if err == nil {
return prefix.Encapsulate(addr)
}
}
return addr
}

func randomString(l int) string {
const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789"
s := make([]byte, 0, l)
Expand Down

0 comments on commit b805866

Please sign in to comment.