Skip to content

Commit

Permalink
huin#48: add local address to the response and apply following change…
Browse files Browse the repository at this point in the history
…s for the caller to get the value
  • Loading branch information
mh-cbon committed Mar 5, 2022
1 parent 730ab65 commit f5450a8
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 72 deletions.
18 changes: 9 additions & 9 deletions dcps/internetgateway1/internetgateway1.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func NewLANHostConfigManagement1ClientsByURL(loc *url.URL) ([]*LANHostConfigMana
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewLANHostConfigManagement1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*LANHostConfigManagement1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_LANHostConfigManagement_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_LANHostConfigManagement_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -835,7 +835,7 @@ func NewLayer3Forwarding1ClientsByURL(loc *url.URL) ([]*Layer3Forwarding1, error
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewLayer3Forwarding1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*Layer3Forwarding1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_Layer3Forwarding_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_Layer3Forwarding_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -966,7 +966,7 @@ func NewWANCableLinkConfig1ClientsByURL(loc *url.URL) ([]*WANCableLinkConfig1, e
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANCableLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANCableLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANCableLinkConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANCableLinkConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1384,7 +1384,7 @@ func NewWANCommonInterfaceConfig1ClientsByURL(loc *url.URL) ([]*WANCommonInterfa
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANCommonInterfaceConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANCommonInterfaceConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANCommonInterfaceConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1821,7 +1821,7 @@ func NewWANDSLLinkConfig1ClientsByURL(loc *url.URL) ([]*WANDSLLinkConfig1, error
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANDSLLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANDSLLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANDSLLinkConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANDSLLinkConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -2241,7 +2241,7 @@ func NewWANEthernetLinkConfig1ClientsByURL(loc *url.URL) ([]*WANEthernetLinkConf
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANEthernetLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANEthernetLinkConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANEthernetLinkConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -2339,7 +2339,7 @@ func NewWANIPConnection1ClientsByURL(loc *url.URL) ([]*WANIPConnection1, error)
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANIPConnection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANIPConnection_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANIPConnection_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -3185,7 +3185,7 @@ func NewWANPOTSLinkConfig1ClientsByURL(loc *url.URL) ([]*WANPOTSLinkConfig1, err
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANPOTSLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANPOTSLinkConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANPOTSLinkConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -3596,7 +3596,7 @@ func NewWANPPPConnection1ClientsByURL(loc *url.URL) ([]*WANPPPConnection1, error
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANPPPConnection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANPPPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANPPPConnection_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANPPPConnection_1)
if err != nil {
return nil, err
}
Expand Down
24 changes: 12 additions & 12 deletions dcps/internetgateway2/internetgateway2.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func NewDeviceProtection1ClientsByURL(loc *url.URL) ([]*DeviceProtection1, error
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewDeviceProtection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*DeviceProtection1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_DeviceProtection_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_DeviceProtection_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -709,7 +709,7 @@ func NewLANHostConfigManagement1ClientsByURL(loc *url.URL) ([]*LANHostConfigMana
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewLANHostConfigManagement1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*LANHostConfigManagement1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_LANHostConfigManagement_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_LANHostConfigManagement_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1458,7 +1458,7 @@ func NewLayer3Forwarding1ClientsByURL(loc *url.URL) ([]*Layer3Forwarding1, error
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewLayer3Forwarding1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*Layer3Forwarding1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_Layer3Forwarding_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_Layer3Forwarding_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1589,7 +1589,7 @@ func NewWANCableLinkConfig1ClientsByURL(loc *url.URL) ([]*WANCableLinkConfig1, e
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANCableLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANCableLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANCableLinkConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANCableLinkConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -2007,7 +2007,7 @@ func NewWANCommonInterfaceConfig1ClientsByURL(loc *url.URL) ([]*WANCommonInterfa
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANCommonInterfaceConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANCommonInterfaceConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANCommonInterfaceConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANCommonInterfaceConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -2444,7 +2444,7 @@ func NewWANDSLLinkConfig1ClientsByURL(loc *url.URL) ([]*WANDSLLinkConfig1, error
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANDSLLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANDSLLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANDSLLinkConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANDSLLinkConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -2864,7 +2864,7 @@ func NewWANEthernetLinkConfig1ClientsByURL(loc *url.URL) ([]*WANEthernetLinkConf
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANEthernetLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANEthernetLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANEthernetLinkConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANEthernetLinkConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -2962,7 +2962,7 @@ func NewWANIPConnection1ClientsByURL(loc *url.URL) ([]*WANIPConnection1, error)
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANIPConnection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANIPConnection_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANIPConnection_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -3808,7 +3808,7 @@ func NewWANIPConnection2ClientsByURL(loc *url.URL) ([]*WANIPConnection2, error)
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANIPConnection2ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPConnection2, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANIPConnection_2)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANIPConnection_2)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -4870,7 +4870,7 @@ func NewWANIPv6FirewallControl1ClientsByURL(loc *url.URL) ([]*WANIPv6FirewallCon
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANIPv6FirewallControl1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPv6FirewallControl1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANIPv6FirewallControl_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANIPv6FirewallControl_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -5280,7 +5280,7 @@ func NewWANPOTSLinkConfig1ClientsByURL(loc *url.URL) ([]*WANPOTSLinkConfig1, err
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANPOTSLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANPOTSLinkConfig1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANPOTSLinkConfig_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANPOTSLinkConfig_1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -5691,7 +5691,7 @@ func NewWANPPPConnection1ClientsByURL(loc *url.URL) ([]*WANPPPConnection1, error
// This is a typical entry calling point into this package when reusing an
// previously discovered root device.
func NewWANPPPConnection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANPPPConnection1, error) {
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANPPPConnection_1)
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, nil, URN_WANPPPConnection_1)
if err != nil {
return nil, err
}
Expand Down
8 changes: 1 addition & 7 deletions device.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"net/url"
"strings"

"github.com/huin/goupnp/scpd"
"github.com/huin/goupnp/soap"
Expand Down Expand Up @@ -179,12 +178,7 @@ type URLField struct {
}

func (uf *URLField) SetURLBase(urlBase *url.URL) {
str := uf.Str
if !strings.Contains(str, "://") && !strings.HasPrefix(str, "/") {
str = "/" + str
}

refUrl, err := url.Parse(str)
refUrl, err := url.Parse(uf.Str)
if err != nil {
uf.URL = url.URL{}
uf.Ok = false
Expand Down
9 changes: 7 additions & 2 deletions goupnp.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"encoding/xml"
"fmt"
"io"
"net"
"net/http"
"net/url"
"time"
Expand Down Expand Up @@ -63,6 +64,9 @@ type MaybeRootDevice struct {
// the discovery of a device, regardless of if there was an error probing it.
Location *url.URL

// LocalAddr returns the local network address associated with the request.
LocalAddr net.Addr

// Any error encountered probing a discovered device.
Err error
}
Expand All @@ -87,13 +91,14 @@ func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
results := make([]MaybeRootDevice, len(responses))
for i, response := range responses {
maybe := &results[i]
maybe.USN = response.Header.Get("USN")
loc, err := response.Location()
maybe.USN = response.Responses[0].Header.Get("USN")
loc, err := response.Responses[0].Location()
if err != nil {
maybe.Err = ContextError{"unexpected bad location from search", err}
continue
}
maybe.Location = loc
maybe.LocalAddr = response.LocalAddr
if root, err := DeviceByURL(loc); err != nil {
maybe.Err = err
} else {
Expand Down
14 changes: 12 additions & 2 deletions httpu/httpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ type ClientInterface interface {
req *http.Request,
timeout time.Duration,
numSends int,
) ([]*http.Response, error)
) ([]RequestResponses, error)
// LocalAddr returns the local network address.
LocalAddr() net.Addr
}

// HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical
Expand All @@ -33,7 +35,7 @@ type HTTPUClient struct {
conn net.PacketConn
}

var _ ClientInterface = &HTTPUClient{}
// var _ ClientInterface = &HTTPUClient{}

// NewHTTPUClient creates a new HTTPUClient, opening up a new UDP socket for the
// purpose.
Expand Down Expand Up @@ -67,6 +69,14 @@ func (httpu *HTTPUClient) Close() error {
return httpu.conn.Close()
}

// LocalAddr returns the local network address.
// The Addr returned is shared by all invocations of LocalAddr, so do not modify it..
func (httpu *HTTPUClient) LocalAddr() net.Addr {
httpu.connLock.Lock()
defer httpu.connLock.Unlock()
return httpu.conn.LocalAddr()
}

// Do implements ClientInterface.Do.
//
// Note that at present only one concurrent connection will happen per
Expand Down
29 changes: 19 additions & 10 deletions httpu/multiclient.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package httpu

import (
"net"
"net/http"
"time"

Expand All @@ -10,14 +11,14 @@ import (
// MultiClient dispatches requests out to all the delegated clients.
type MultiClient struct {
// The HTTPU clients to delegate to.
delegates []ClientInterface
delegates []*HTTPUClient
}

var _ ClientInterface = &MultiClient{}
// var _ ClientInterface = &MultiClient{}

// NewMultiClient creates a new MultiClient that delegates to all the given
// clients.
func NewMultiClient(delegates []ClientInterface) *MultiClient {
func NewMultiClient(delegates []*HTTPUClient) *MultiClient {
return &MultiClient{
delegates: delegates,
}
Expand All @@ -28,41 +29,49 @@ func (mc *MultiClient) Do(
req *http.Request,
timeout time.Duration,
numSends int,
) ([]*http.Response, error) {
) ([]RequestResponses, error) {
tasks := &errgroup.Group{}

results := make(chan []*http.Response)
results := make(chan RequestResponses)
tasks.Go(func() error {
defer close(results)
return mc.sendRequests(results, req, timeout, numSends)
})

var responses []*http.Response
var responses []RequestResponses
tasks.Go(func() error {
for rs := range results {
responses = append(responses, rs...)
responses = append(responses, rs)
}
return nil
})

return responses, tasks.Wait()
}

type RequestResponses struct {
Responses []*http.Response
LocalAddr net.Addr
}

func (mc *MultiClient) sendRequests(
results chan<-[]*http.Response,
results chan<- RequestResponses,
req *http.Request,
timeout time.Duration,
numSends int,
) error {
tasks := &errgroup.Group{}
for _, d := range mc.delegates {
d := d // copy for closure
d := d // copy for closure
tasks.Go(func() error {
responses, err := d.Do(req, timeout, numSends)
if err != nil {
return err
}
results <- responses
results <- RequestResponses{
Responses: responses,
LocalAddr: d.LocalAddr(),
}
return nil
})
}
Expand Down
4 changes: 2 additions & 2 deletions network.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import (
// httpuClient creates a HTTPU client that multiplexes to all multicast-capable
// IPv4 addresses on the host. Returns a function to clean up once the client is
// no longer required.
func httpuClient() (httpu.ClientInterface, func(), error) {
func httpuClient() (*httpu.MultiClient, func(), error) {
addrs, err := localIPv4MCastAddrs()
if err != nil {
return nil, nil, ctxError(err, "requesting host IPv4 addresses")
}

closers := make([]io.Closer, 0, len(addrs))
delegates := make([]httpu.ClientInterface, 0, len(addrs))
delegates := make([]*httpu.HTTPUClient, 0, len(addrs))
for _, addr := range addrs {
c, err := httpu.NewHTTPUClientAddr(addr)
if err != nil {
Expand Down
Loading

0 comments on commit f5450a8

Please sign in to comment.