mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-12 16:26:37 +00:00
lib/nat, lib/connections: Fix a few issues with NAT traversal
1. For the same internal port we ask for the same external port on all devices. This can be a problem if one device speaks over two protocols. 2. Always add a nil address even if we managed to get external address of the gateway, just because the gateway might be in DMZ behind another gateway. GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3196
This commit is contained in:
parent
4669ce0766
commit
87701339fe
@ -137,6 +137,15 @@ func (t *tcpListener) WANAddresses() []*url.URL {
|
|||||||
// Does net.JoinHostPort internally
|
// Does net.JoinHostPort internally
|
||||||
uri.Host = addr.String()
|
uri.Host = addr.String()
|
||||||
uris = append(uris, &uri)
|
uris = append(uris, &uri)
|
||||||
|
|
||||||
|
// For every address with a specified IP, add one without an IP,
|
||||||
|
// just in case the specified IP is still internal (router behind DMZ).
|
||||||
|
if len(addr.IP) != 0 && !addr.IP.IsUnspecified() {
|
||||||
|
uri = *t.uri
|
||||||
|
addr.IP = nil
|
||||||
|
uri.Host = addr.String()
|
||||||
|
uris = append(uris, &uri)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.mut.RUnlock()
|
t.mut.RUnlock()
|
||||||
|
@ -8,6 +8,7 @@ package nat
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash/fnv"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
stdsync "sync"
|
stdsync "sync"
|
||||||
@ -284,10 +285,10 @@ func (s *Service) tryNATDevice(natd Device, intPort, extPort int, leaseTime time
|
|||||||
var err error
|
var err error
|
||||||
var port int
|
var port int
|
||||||
|
|
||||||
// Generate a predictable random which is based on device ID + local port
|
// Generate a predictable random which is based on device ID + local port + hash of the device ID
|
||||||
// number so that the ports we'd try to acquire for the mapping would always
|
// number so that the ports we'd try to acquire for the mapping would always be the same for the
|
||||||
// be the same.
|
// same device trying to get the same internal port.
|
||||||
predictableRand := rand.New(rand.NewSource(int64(s.id.Short()) + int64(intPort)))
|
predictableRand := rand.New(rand.NewSource(int64(s.id.Short()) + int64(intPort) + hash(natd.ID())))
|
||||||
|
|
||||||
if extPort != 0 {
|
if extPort != 0 {
|
||||||
// First try renewing our existing mapping, if we have one.
|
// First try renewing our existing mapping, if we have one.
|
||||||
@ -325,3 +326,9 @@ findIP:
|
|||||||
Port: extPort,
|
Port: extPort,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hash(input string) int64 {
|
||||||
|
h := fnv.New64a()
|
||||||
|
h.Write([]byte(input))
|
||||||
|
return int64(h.Sum64())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user