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:
committed by
Audrius Butkevicius
parent
4e151d380c
commit
1bae4b7f50
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user