diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index ca58573fb..4f4a115ba 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -577,7 +577,9 @@ func setupUPnP(rnd rand.Source) { if err == nil { externalPort = r l.Infoln("Created UPnP port mapping - external port", externalPort) - go renewUPnP(igd, rnd, port) + if cfg.Options.UPnPRenewal > 0 { + go renewUPnP(igd, rnd, port) + } break } } @@ -597,10 +599,6 @@ func setupUPnP(rnd rand.Source) { } func renewUPnP(igd *upnp.IGD, rnd rand.Source, port int) { - if cfg.Options.UPnPRenewal < 1 { - return - } - for { time.Sleep(time.Duration(cfg.Options.UPnPRenewal) * time.Minute) @@ -615,6 +613,7 @@ func renewUPnP(igd *upnp.IGD, rnd rand.Source, port int) { if err == nil { l.Infoln("Updated UPnP port mapping - external port", externalPort) externalPort = r + discoverer.StartGlobal(cfg.Options.GlobalAnnServer, uint16(r)) continue } l.Warnln("Failed to update UPnP port mapping - externalPort", externalPort) diff --git a/discover/discover.go b/discover/discover.go index 6e051a4e4..314458313 100644 --- a/discover/discover.go +++ b/discover/discover.go @@ -33,6 +33,7 @@ type Discoverer struct { forcedBcastTick chan time.Time extAnnounceOK bool extAnnounceOKmut sync.Mutex + globalBcastStop chan bool } var ( @@ -70,6 +71,11 @@ func (d *Discoverer) StartLocal() { } func (d *Discoverer) StartGlobal(server string, extPort uint16) { + if d.globalBcastStop != nil { + d.globalBcastStop <- true + } else { + d.globalBcastStop = make(chan bool) + } d.extServer = server d.extPort = extPort go d.sendExternalAnnouncements() @@ -230,7 +236,17 @@ func (d *Discoverer) sendExternalAnnouncements() { d.extAnnounceOKmut.Unlock() if ok { - time.Sleep(d.globalBcastIntv) + // Don't do a long sleep, listen for a stop signal, just incase + // the UPnP mapping has changed, and a new routine should be started. + for i := time.Duration(0); i < d.globalBcastIntv; i += time.Duration(1) { + select { + case <-d.globalBcastStop: + return + default: + time.Sleep(1 * time.Second) + } + } + } else { time.Sleep(errorRetryIntv) }