Make UPnP timeout configurable

This commit is contained in:
Audrius Butkevicius 2015-04-16 00:34:27 +01:00
parent 45cbcaca6d
commit d148cd8ccc
5 changed files with 12 additions and 8 deletions

View File

@ -727,7 +727,7 @@ func setupUPnP() {
} else {
// Set up incoming port forwarding, if necessary and possible
port, _ := strconv.Atoi(portStr)
igds := upnp.Discover()
igds := upnp.Discover(time.Duration(cfg.Options().UPnPTimeoutS) * time.Second)
if len(igds) > 0 {
// Configure the first discovered IGD only. This is a work-around until we have a better mechanism
// for handling multiple IGDs, which will require changes to the global discovery service
@ -769,13 +769,15 @@ func renewUPnP(port int) {
for {
opts := cfg.Options()
time.Sleep(time.Duration(opts.UPnPRenewal) * time.Minute)
// Some values might have changed while we were sleeping
opts = cfg.Options()
// Make sure our IGD reference isn't nil
if igd == nil {
if debugNet {
l.Debugln("Undefined IGD during UPnP port renewal. Re-discovering...")
}
igds := upnp.Discover()
igds := upnp.Discover(time.Duration(opts.UPnPTimeoutS) * time.Second)
if len(igds) > 0 {
// Configure the first discovered IGD only. This is a work-around until we have a better mechanism
// for handling multiple IGDs, which will require changes to the global discovery service

View File

@ -229,6 +229,7 @@ type OptionsConfiguration struct {
UPnPEnabled bool `xml:"upnpEnabled" json:"upnpEnabled" default:"true"`
UPnPLease int `xml:"upnpLeaseMinutes" json:"upnpLeaseMinutes" default:"0"`
UPnPRenewal int `xml:"upnpRenewalMinutes" json:"upnpRenewalMinutes" default:"30"`
UPnPTimeoutS int `xml:"upnpTimeoutSeconds" json:"upnpTimeoutSeconds" default:"3"`
URAccepted int `xml:"urAccepted" json:"urAccepted"` // Accepted usage reporting version; 0 for off (undecided), -1 for off (permanently)
URUniqueID string `xml:"urUniqueID" json:"urUniqueId"` // Unique ID for reporting purposes, regenerated when UR is turned on.
RestartOnWakeup bool `xml:"restartOnWakeup" json:"restartOnWakeup" default:"true"`

View File

@ -44,6 +44,7 @@ func TestDefaultValues(t *testing.T) {
UPnPEnabled: true,
UPnPLease: 0,
UPnPRenewal: 30,
UPnPTimeoutS: 3,
RestartOnWakeup: true,
AutoUpgradeIntervalH: 12,
KeepTemporariesH: 24,
@ -149,6 +150,7 @@ func TestOverriddenValues(t *testing.T) {
UPnPEnabled: false,
UPnPLease: 60,
UPnPRenewal: 15,
UPnPTimeoutS: 15,
RestartOnWakeup: false,
AutoUpgradeIntervalH: 24,
KeepTemporariesH: 48,

View File

@ -15,6 +15,7 @@
<upnpEnabled>false</upnpEnabled>
<upnpLeaseMinutes>60</upnpLeaseMinutes>
<upnpRenewalMinutes>15</upnpRenewalMinutes>
<upnpTimeoutSeconds>15</upnpTimeoutSeconds>
<restartOnWakeup>false</restartOnWakeup>
<autoUpgradeIntervalH>24</autoUpgradeIntervalH>
<keepTemporariesH>48</keepTemporariesH>

View File

@ -92,12 +92,10 @@ type upnpRoot struct {
// Discover discovers UPnP InternetGatewayDevices.
// The order in which the devices appear in the result list is not deterministic.
func Discover() []IGD {
func Discover(timeout time.Duration) []IGD {
var result []IGD
l.Infoln("Starting UPnP discovery...")
timeout := 3
// Search for InternetGatewayDevice:2 devices
result = append(result, discover("urn:schemas-upnp-org:device:InternetGatewayDevice:2", timeout, result)...)
@ -128,7 +126,7 @@ func Discover() []IGD {
// Search for UPnP InternetGatewayDevices for <timeout> seconds, ignoring responses from any devices listed in knownDevices.
// The order in which the devices appear in the result list is not deterministic
func discover(deviceType string, timeout int, knownDevices []IGD) []IGD {
func discover(deviceType string, timeout time.Duration, knownDevices []IGD) []IGD {
ssdp := &net.UDPAddr{IP: []byte{239, 255, 255, 250}, Port: 1900}
tpl := `M-SEARCH * HTTP/1.1
@ -138,7 +136,7 @@ Man: "ssdp:discover"
Mx: %d
`
searchStr := fmt.Sprintf(tpl, deviceType, timeout)
searchStr := fmt.Sprintf(tpl, deviceType, timeout/time.Second)
search := []byte(strings.Replace(searchStr, "\n", "\r\n", -1))
@ -156,7 +154,7 @@ Mx: %d
}
defer socket.Close() // Make sure our socket gets closed
err = socket.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
err = socket.SetDeadline(time.Now().Add(timeout))
if err != nil {
l.Infoln(err)
return results