This commit is contained in:
@@ -170,7 +170,10 @@ func (t *quicListener) WANAddresses() []*url.URL {
|
||||
}
|
||||
|
||||
func (t *quicListener) LANAddresses() []*url.URL {
|
||||
return []*url.URL{t.uri}
|
||||
addrs := []*url.URL{t.uri}
|
||||
network := strings.Replace(t.uri.Scheme, "quic", "udp", -1)
|
||||
addrs = append(addrs, getURLsForAllAdaptersIfUnspecified(network, t.uri)...)
|
||||
return addrs
|
||||
}
|
||||
|
||||
func (t *quicListener) String() string {
|
||||
|
||||
@@ -675,6 +675,9 @@ func (s *service) AllAddresses() []string {
|
||||
}
|
||||
|
||||
func (s *service) ExternalAddresses() []string {
|
||||
if s.cfg.Options().AnnounceLANAddresses {
|
||||
return s.AllAddresses()
|
||||
}
|
||||
s.listenersMut.RLock()
|
||||
var addrs []string
|
||||
for _, listener := range s.listeners {
|
||||
|
||||
@@ -179,7 +179,9 @@ func (t *tcpListener) WANAddresses() []*url.URL {
|
||||
}
|
||||
|
||||
func (t *tcpListener) LANAddresses() []*url.URL {
|
||||
return []*url.URL{t.uri}
|
||||
addrs := []*url.URL{t.uri}
|
||||
addrs = append(addrs, getURLsForAllAdaptersIfUnspecified(t.uri.Scheme, t.uri)...)
|
||||
return addrs
|
||||
}
|
||||
|
||||
func (t *tcpListener) String() string {
|
||||
|
||||
@@ -11,6 +11,8 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/osutil"
|
||||
)
|
||||
|
||||
func fixupPort(uri *url.URL, defaultPort int) *url.URL {
|
||||
@@ -32,3 +34,86 @@ func fixupPort(uri *url.URL, defaultPort int) *url.URL {
|
||||
|
||||
return ©URI
|
||||
}
|
||||
|
||||
func getURLsForAllAdaptersIfUnspecified(network string, uri *url.URL) []*url.URL {
|
||||
ip, port, err := resolve(network, uri.Host)
|
||||
// Failed to resolve
|
||||
if err != nil || port == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Not an unspecified address, so no point of substituting with local
|
||||
// interface addresses as it's listening on a specific adapter anyway.
|
||||
if len(ip) != 0 && !ip.IsUnspecified() {
|
||||
return nil
|
||||
}
|
||||
|
||||
hostPorts := getHostPortsForAllAdapters(port)
|
||||
addrs := make([]*url.URL, 0, len(hostPorts))
|
||||
for _, hostPort := range hostPorts {
|
||||
newUri := *uri
|
||||
newUri.Host = hostPort
|
||||
addrs = append(addrs, &newUri)
|
||||
}
|
||||
|
||||
return addrs
|
||||
}
|
||||
|
||||
func getHostPortsForAllAdapters(port int) []string {
|
||||
nets, err := osutil.GetLans()
|
||||
if err != nil {
|
||||
// Ignore failure.
|
||||
return nil
|
||||
}
|
||||
|
||||
hostPorts := make([]string, 0, len(nets))
|
||||
|
||||
portStr := strconv.Itoa(port)
|
||||
|
||||
for _, network := range nets {
|
||||
// Only IPv4 addresses, as v6 link local require an interface identifiers to work correctly
|
||||
// And non link local in theory are globally routable anyway.
|
||||
if network.IP.To4() == nil {
|
||||
continue
|
||||
}
|
||||
if network.IP.IsLinkLocalUnicast() || (isV4Local(network.IP) && network.IP.IsGlobalUnicast()) {
|
||||
hostPorts = append(hostPorts, net.JoinHostPort(network.IP.String(), portStr))
|
||||
}
|
||||
}
|
||||
return hostPorts
|
||||
}
|
||||
|
||||
func resolve(network, hostPort string) (net.IP, int, error) {
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
if addr, err := net.ResolveTCPAddr(network, hostPort); err != nil {
|
||||
return net.IPv4zero, 0, err
|
||||
} else {
|
||||
return addr.IP, addr.Port, nil
|
||||
}
|
||||
case "udp", "udp4", "udp6":
|
||||
if addr, err := net.ResolveUDPAddr(network, hostPort); err != nil {
|
||||
return net.IPv4zero, 0, err
|
||||
} else {
|
||||
return addr.IP, addr.Port, nil
|
||||
}
|
||||
case "ip", "ip4", "ip6":
|
||||
if addr, err := net.ResolveIPAddr(network, hostPort); err != nil {
|
||||
return net.IPv4zero, 0, err
|
||||
} else {
|
||||
return addr.IP, 0, nil
|
||||
}
|
||||
}
|
||||
return net.IPv4zero, 0, net.UnknownNetworkError(network)
|
||||
}
|
||||
|
||||
func isV4Local(ip net.IP) bool {
|
||||
// See https://go-review.googlesource.com/c/go/+/162998/
|
||||
// We only take the V4 part of that.
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
return ip4[0] == 10 ||
|
||||
(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
|
||||
(ip4[0] == 192 && ip4[1] == 168)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user