diff --git a/src/core/link_tcp.go b/src/core/link_tcp.go index 41bb849f..9c3c3290 100644 --- a/src/core/link_tcp.go +++ b/src/core/link_tcp.go @@ -35,14 +35,14 @@ func (l *linkTCP) dial(url *url.URL, options linkOptions, sintf string) error { if err != nil { return err } - info := linkInfoFor("tcp", sintf, addr.String()) - if l.links.isConnectedTo(info) { - return nil - } dialer, err := l.dialerFor(addr, sintf) if err != nil { return err } + info := linkInfoFor("tcp", sintf, tcpIDFor(dialer.LocalAddr, addr)) + if l.links.isConnectedTo(info) { + return nil + } conn, err := dialer.DialContext(l.core.ctx, "tcp", addr.String()) if err != nil { return err @@ -82,10 +82,11 @@ func (l *linkTCP) listen(url *url.URL, sintf string) (*Listener, error) { cancel() break } - addr := conn.RemoteAddr().(*net.TCPAddr) - name := fmt.Sprintf("tcp://%s", addr) - info := linkInfoFor("tcp", sintf, addr.String()) - if err = l.handler(name, info, conn, linkOptionsForListener(url), true, addr.IP.IsLinkLocalUnicast()); err != nil { + laddr := conn.LocalAddr().(*net.TCPAddr) + raddr := conn.RemoteAddr().(*net.TCPAddr) + name := fmt.Sprintf("tcp://%s", raddr) + info := linkInfoFor("tcp", sintf, tcpIDFor(laddr, raddr)) + if err = l.handler(name, info, conn, linkOptionsForListener(url), true, raddr.IP.IsLinkLocalUnicast()); err != nil { l.core.log.Errorln("Failed to create inbound link:", err) } } @@ -179,3 +180,16 @@ func (l *linkTCP) dialerFor(dst *net.TCPAddr, sintf string) (*net.Dialer, error) } return dialer, nil } + +func tcpIDFor(local net.Addr, remoteAddr *net.TCPAddr) string { + if localAddr, ok := local.(*net.TCPAddr); ok && localAddr.IP.Equal(remoteAddr.IP) { + // Nodes running on the same host — include both the IP and port. + return remoteAddr.String() + } + if remoteAddr.IP.IsLinkLocalUnicast() { + // Nodes discovered via multicast — include the IP only. + return remoteAddr.IP.String() + } + // Nodes connected remotely — include both the IP and port. + return remoteAddr.String() +} diff --git a/src/core/link_tls.go b/src/core/link_tls.go index 7fa04371..4eeb8710 100644 --- a/src/core/link_tls.go +++ b/src/core/link_tls.go @@ -51,14 +51,14 @@ func (l *linkTLS) dial(url *url.URL, options linkOptions, sintf, sni string) err if err != nil { return err } - info := linkInfoFor("tls", sintf, addr.String()) - if l.links.isConnectedTo(info) { - return nil - } dialer, err := l.tcp.dialerFor(addr, sintf) if err != nil { return err } + info := linkInfoFor("tls", sintf, tcpIDFor(dialer.LocalAddr, addr)) + if l.links.isConnectedTo(info) { + return nil + } tlsconfig := l.config.Clone() tlsconfig.ServerName = sni tlsdialer := &tls.Dialer{ @@ -105,10 +105,11 @@ func (l *linkTLS) listen(url *url.URL, sintf string) (*Listener, error) { cancel() break } - addr := conn.RemoteAddr().(*net.TCPAddr) - name := fmt.Sprintf("tls://%s", addr) - info := linkInfoFor("tls", sintf, addr.String()) - if err = l.handler(name, info, conn, linkOptionsForListener(url), true, addr.IP.IsLinkLocalUnicast()); err != nil { + laddr := conn.LocalAddr().(*net.TCPAddr) + raddr := conn.RemoteAddr().(*net.TCPAddr) + name := fmt.Sprintf("tls://%s", raddr) + info := linkInfoFor("tls", sintf, tcpIDFor(laddr, raddr)) + if err = l.handler(name, info, conn, linkOptionsForListener(url), true, raddr.IP.IsLinkLocalUnicast()); err != nil { l.core.log.Errorln("Failed to create inbound link:", err) } } diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index 81e575f1..8d7fbb7d 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -78,7 +78,11 @@ func (m *Multicast) _start() error { if m._isOpen { return fmt.Errorf("multicast module is already started") } - if len(m.config._interfaces) == 0 { + var anyEnabled bool + for intf := range m.config._interfaces { + anyEnabled = anyEnabled || intf.Beacon || intf.Listen + } + if !anyEnabled { return nil } m.log.Debugln("Starting multicast module")