mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 23:00:58 +00:00
Restart port sequence when UPnP renewal fails
This commit is contained in:
parent
870e3ca893
commit
7cc9921615
@ -83,6 +83,7 @@ var (
|
|||||||
lockConn *net.TCPListener
|
lockConn *net.TCPListener
|
||||||
lockPort int
|
lockPort int
|
||||||
externalPort int
|
externalPort int
|
||||||
|
cert tls.Certificate
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -249,7 +250,7 @@ func main() {
|
|||||||
// Ensure that our home directory exists and that we have a certificate and key.
|
// Ensure that our home directory exists and that we have a certificate and key.
|
||||||
|
|
||||||
ensureDir(confDir, 0700)
|
ensureDir(confDir, 0700)
|
||||||
cert, err := loadCert(confDir, "")
|
cert, err = loadCert(confDir, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
newCertificate(confDir, "")
|
newCertificate(confDir, "")
|
||||||
cert, err = loadCert(confDir, "")
|
cert, err = loadCert(confDir, "")
|
||||||
@ -472,9 +473,7 @@ nextRepo:
|
|||||||
// UPnP
|
// UPnP
|
||||||
|
|
||||||
if cfg.Options.UPnPEnabled {
|
if cfg.Options.UPnPEnabled {
|
||||||
// We seed the random number generator with the node ID to get a
|
setupUPnP()
|
||||||
// repeatable sequence of random external ports.
|
|
||||||
setupUPnP(rand.NewSource(certSeed(cert.Certificate[0])))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine to connect out to configured nodes
|
// Routine to connect out to configured nodes
|
||||||
@ -561,7 +560,7 @@ func waitForParentExit() {
|
|||||||
l.Infoln("Continuing")
|
l.Infoln("Continuing")
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupUPnP(rnd rand.Source) {
|
func setupUPnP() {
|
||||||
if len(cfg.Options.ListenAddress) == 1 {
|
if len(cfg.Options.ListenAddress) == 1 {
|
||||||
_, portStr, err := net.SplitHostPort(cfg.Options.ListenAddress[0])
|
_, portStr, err := net.SplitHostPort(cfg.Options.ListenAddress[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -571,17 +570,11 @@ func setupUPnP(rnd rand.Source) {
|
|||||||
port, _ := strconv.Atoi(portStr)
|
port, _ := strconv.Atoi(portStr)
|
||||||
igd, err := upnp.Discover()
|
igd, err := upnp.Discover()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for i := 0; i < 10; i++ {
|
externalPort = setupExternalPort(igd, port)
|
||||||
r := 1024 + int(rnd.Int63()%(65535-1024))
|
|
||||||
err := igd.AddPortMapping(upnp.TCP, r, port, "syncthing", cfg.Options.UPnPLease*60)
|
|
||||||
if err == nil {
|
|
||||||
externalPort = r
|
|
||||||
l.Infoln("Created UPnP port mapping - external port", externalPort)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if externalPort == 0 {
|
if externalPort == 0 {
|
||||||
l.Warnln("Failed to create UPnP port mapping")
|
l.Warnln("Failed to create UPnP port mapping")
|
||||||
|
} else {
|
||||||
|
l.Infoln("Created UPnP port mapping - external port", externalPort)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
l.Infof("No UPnP gateway detected")
|
l.Infof("No UPnP gateway detected")
|
||||||
@ -590,7 +583,7 @@ func setupUPnP(rnd rand.Source) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cfg.Options.UPnPRenewal > 0 {
|
if cfg.Options.UPnPRenewal > 0 {
|
||||||
go renewUPnP(rnd, port)
|
go renewUPnP(port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -598,7 +591,21 @@ func setupUPnP(rnd rand.Source) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renewUPnP(rnd rand.Source, port int) {
|
func setupExternalPort(igd *upnp.IGD, port int) int {
|
||||||
|
// We seed the random number generator with the node ID to get a
|
||||||
|
// repeatable sequence of random external ports.
|
||||||
|
rnd := rand.NewSource(certSeed(cert.Certificate[0]))
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
r := 1024 + int(rnd.Int63()%(65535-1024))
|
||||||
|
err := igd.AddPortMapping(upnp.TCP, r, port, "syncthing", cfg.Options.UPnPLease*60)
|
||||||
|
if err == nil {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func renewUPnP(port int) {
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Duration(cfg.Options.UPnPRenewal) * time.Minute)
|
time.Sleep(time.Duration(cfg.Options.UPnPRenewal) * time.Minute)
|
||||||
|
|
||||||
@ -607,21 +614,23 @@ func renewUPnP(rnd rand.Source, port int) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Just renew the same port that we already have
|
||||||
err = igd.AddPortMapping(upnp.TCP, externalPort, port, "syncthing", cfg.Options.UPnPLease*60)
|
err = igd.AddPortMapping(upnp.TCP, externalPort, port, "syncthing", cfg.Options.UPnPLease*60)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
l.Infoln("Renewed UPnP port mapping - external port", externalPort)
|
l.Infoln("Renewed UPnP port mapping - external port", externalPort)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
r := 1024 + int(rnd.Int63()%(65535-1024))
|
// Something strange has happened. Perhaps the gateway has changed?
|
||||||
err = igd.AddPortMapping(upnp.TCP, r, port, "syncthing", cfg.Options.UPnPLease*60)
|
// Retry the same port sequence from the beginning.
|
||||||
if err == nil {
|
r := setupExternalPort(igd, port)
|
||||||
l.Infoln("Updated UPnP port mapping - external port", externalPort)
|
if r != 0 {
|
||||||
externalPort = r
|
externalPort = r
|
||||||
|
l.Infoln("Updated UPnP port mapping - external port", externalPort)
|
||||||
discoverer.StartGlobal(cfg.Options.GlobalAnnServer, uint16(r))
|
discoverer.StartGlobal(cfg.Options.GlobalAnnServer, uint16(r))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
l.Warnln("Failed to update UPnP port mapping - externalPort", externalPort)
|
l.Warnln("Failed to update UPnP port mapping - external port", externalPort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user