Add UPnP renewal

This commit is contained in:
Audrius Butkevicius 2014-08-11 22:58:32 +01:00
parent 97dda6a4bb
commit 8976e53998
2 changed files with 42 additions and 16 deletions

View File

@ -73,15 +73,16 @@ func init() {
}
var (
cfg config.Configuration
myID protocol.NodeID
confDir string
logFlags int = log.Ltime
rateBucket *ratelimit.Bucket
stop = make(chan bool)
discoverer *discover.Discoverer
lockConn *net.TCPListener
lockPort int
cfg config.Configuration
myID protocol.NodeID
confDir string
logFlags int = log.Ltime
rateBucket *ratelimit.Bucket
stop = make(chan bool)
discoverer *discover.Discoverer
lockConn *net.TCPListener
lockPort int
externalPort int
)
const (
@ -470,11 +471,10 @@ nextRepo:
// UPnP
var externalPort = 0
if cfg.Options.UPnPEnabled {
// We seed the random number generator with the node ID to get a
// repeatable sequence of random external ports.
externalPort = setupUPnP(rand.NewSource(certSeed(cert.Certificate[0])))
setupUPnP(rand.NewSource(certSeed(cert.Certificate[0])))
}
// Routine to connect out to configured nodes
@ -561,8 +561,7 @@ func waitForParentExit() {
l.Infoln("Continuing")
}
func setupUPnP(r rand.Source) int {
var externalPort = 0
func setupUPnP(rnd rand.Source) {
if len(cfg.Options.ListenAddress) == 1 {
_, portStr, err := net.SplitHostPort(cfg.Options.ListenAddress[0])
if err != nil {
@ -573,11 +572,12 @@ func setupUPnP(r rand.Source) int {
igd, err := upnp.Discover()
if err == nil {
for i := 0; i < 10; i++ {
r := 1024 + int(r.Int63()%(65535-1024))
err := igd.AddPortMapping(upnp.TCP, r, port, "syncthing", 0)
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)
go renewUPnP(igd, rnd, port)
break
}
}
@ -594,7 +594,31 @@ func setupUPnP(r rand.Source) int {
} else {
l.Warnln("Multiple listening addresses; not attempting UPnP port mapping")
}
return externalPort
}
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)
err := igd.AddPortMapping(upnp.TCP, externalPort, port, "syncthing", cfg.Options.UPnPLease*60)
if err == nil {
l.Infoln("Renewed UPnP port mapping - external port", externalPort)
continue
}
r := 1024 + int(rnd.Int63()%(65535-1024))
err = igd.AddPortMapping(upnp.TCP, r, port, "syncthing", cfg.Options.UPnPLease*60)
if err == nil {
l.Infoln("Updated UPnP port mapping - external port", externalPort)
externalPort = r
continue
}
l.Warnln("Failed to update UPnP port mapping - externalPort", externalPort)
}
}
func resetRepositories() {

View File

@ -113,6 +113,8 @@ type OptionsConfiguration struct {
MaxChangeKbps int `xml:"maxChangeKbps" default:"10000"`
StartBrowser bool `xml:"startBrowser" default:"true"`
UPnPEnabled bool `xml:"upnpEnabled" default:"true"`
UPnPLease int `xml:"upnpLeaseMinutes" default:"0"`
UPnPRenewal int `xml:"upnpRenewalMinutes" default:"0"`
URAccepted int `xml:"urAccepted"` // Accepted usage reporting version; 0 for off (undecided), -1 for off (permanently)
Deprecated_UREnabled bool `xml:"urEnabled,omitempty" json:"-"`