all: Use context in lib/dialer (#6177)

* all: Use context in lib/dialer

* a bit slimmer

* https://github.com/syncthing/syncthing/pull/5753

* bot

* missed adding debug.go

* errors.Cause

* simultaneous dialing

* anti-leak
This commit is contained in:
Simon Frei
2019-11-26 08:39:51 +01:00
committed by Audrius Butkevicius
parent 4e151d380c
commit 1bae4b7f50
24 changed files with 175 additions and 204 deletions

View File

@@ -35,8 +35,8 @@ package upnp
import (
"bufio"
"bytes"
"context"
"encoding/xml"
"errors"
"fmt"
"io/ioutil"
"net"
@@ -47,6 +47,8 @@ import (
"sync"
"time"
"github.com/pkg/errors"
"github.com/syncthing/syncthing/lib/dialer"
"github.com/syncthing/syncthing/lib/nat"
)
@@ -83,7 +85,7 @@ func (e UnsupportedDeviceTypeError) Error() string {
// Discover discovers UPnP InternetGatewayDevices.
// The order in which the devices appear in the results list is not deterministic.
func Discover(renewal, timeout time.Duration) []nat.Device {
func Discover(ctx context.Context, renewal, timeout time.Duration) []nat.Device {
var results []nat.Device
interfaces, err := net.Interfaces()
@@ -105,7 +107,7 @@ func Discover(renewal, timeout time.Duration) []nat.Device {
for _, deviceType := range []string{"urn:schemas-upnp-org:device:InternetGatewayDevice:1", "urn:schemas-upnp-org:device:InternetGatewayDevice:2"} {
wg.Add(1)
go func(intf net.Interface, deviceType string) {
discover(&intf, deviceType, timeout, resultChan)
discover(ctx, &intf, deviceType, timeout, resultChan)
wg.Done()
}(intf, deviceType)
}
@@ -135,7 +137,7 @@ nextResult:
// Search for UPnP InternetGatewayDevices for <timeout> seconds.
// The order in which the devices appear in the result list is not deterministic
func discover(intf *net.Interface, deviceType string, timeout time.Duration, results chan<- nat.Device) {
func discover(ctx context.Context, intf *net.Interface, deviceType string, timeout time.Duration, results chan<- nat.Device) {
ssdp := &net.UDPAddr{IP: []byte{239, 255, 255, 250}, Port: 1900}
tpl := `M-SEARCH * HTTP/1.1
@@ -187,13 +189,15 @@ USER-AGENT: syncthing/1.0
}
break
}
igds, err := parseResponse(deviceType, resp[:n])
igds, err := parseResponse(ctx, deviceType, resp[:n])
if err != nil {
switch err.(type) {
case *UnsupportedDeviceTypeError:
l.Debugln(err.Error())
default:
l.Infoln("UPnP parse:", err)
if errors.Cause(err) != context.Canceled {
l.Infoln("UPnP parse:", err)
}
}
continue
}
@@ -205,7 +209,7 @@ USER-AGENT: syncthing/1.0
l.Debugln("Discovery for device type", deviceType, "on", intf.Name, "finished.")
}
func parseResponse(deviceType string, resp []byte) ([]IGDService, error) {
func parseResponse(ctx context.Context, deviceType string, resp []byte) ([]IGDService, error) {
l.Debugln("Handling UPnP response:\n\n" + string(resp))
reader := bufio.NewReader(bytes.NewBuffer(resp))
@@ -257,7 +261,7 @@ func parseResponse(deviceType string, resp []byte) ([]IGDService, error) {
// We do this in a fairly roundabout way by connecting to the IGD and
// checking the address of the local end of the socket. I'm open to
// suggestions on a better way to do this...
localIPAddress, err := localIP(deviceDescriptionURL)
localIPAddress, err := localIP(ctx, deviceDescriptionURL)
if err != nil {
return nil, err
}
@@ -270,8 +274,10 @@ func parseResponse(deviceType string, resp []byte) ([]IGDService, error) {
return services, nil
}
func localIP(url *url.URL) (net.IP, error) {
conn, err := dialer.DialTimeout("tcp", url.Host, time.Second)
func localIP(ctx context.Context, url *url.URL) (net.IP, error) {
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
conn, err := dialer.DialContext(timeoutCtx, "tcp", url.Host)
if err != nil {
return nil, err
}