lib/upnp: Exit quicker (#6339)

During NAT discovery we block for 10s (NatTimeoutS) before returning.
This is mostly noticeable when Ctrl-C:ing a Syncthing directly after
startup as we wait for those ten seconds before shutting down. This
makes it check the context a little bit more frequently.
This commit is contained in:
Jakob Borg 2020-02-13 15:39:36 +01:00 committed by GitHub
parent 6a840a040b
commit 71de6fe290
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -160,12 +160,6 @@ USER-AGENT: syncthing/1.0
} }
defer socket.Close() // Make sure our socket gets closed defer socket.Close() // Make sure our socket gets closed
err = socket.SetDeadline(time.Now().Add(timeout))
if err != nil {
l.Debugln("UPnP discovery: setting socket deadline:", err)
return
}
l.Debugln("Sending search request for device type", deviceType, "on", intf.Name) l.Debugln("Sending search request for device type", deviceType, "on", intf.Name)
_, err = socket.WriteTo(search, ssdp) _, err = socket.WriteTo(search, ssdp)
@ -178,16 +172,33 @@ USER-AGENT: syncthing/1.0
l.Debugln("Listening for UPnP response for device type", deviceType, "on", intf.Name) l.Debugln("Listening for UPnP response for device type", deviceType, "on", intf.Name)
// Listen for responses until a timeout is reached ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
// Listen for responses until a timeout is reached or the context is
// cancelled
resp := make([]byte, 65536)
loop:
for { for {
resp := make([]byte, 65536) if err := socket.SetDeadline(time.Now().Add(250 * time.Millisecond)); err != nil {
n, _, err := socket.ReadFrom(resp) l.Infoln("UPnP socket:", err)
if err != nil {
if e, ok := err.(net.Error); !ok || !e.Timeout() {
l.Infoln("UPnP read:", err) //legitimate error, not a timeout.
}
break break
} }
n, _, err := socket.ReadFrom(resp)
if err != nil {
select {
case <-ctx.Done():
break loop
default:
}
if e, ok := err.(net.Error); ok && e.Timeout() {
continue // continue reading
}
l.Infoln("UPnP read:", err) //legitimate error, not a timeout.
break
}
igds, err := parseResponse(ctx, deviceType, resp[:n]) igds, err := parseResponse(ctx, deviceType, resp[:n])
if err != nil { if err != nil {
switch err.(type) { switch err.(type) {