#48: Add local address information

This commit is contained in:
mhhcbon 2022-03-21 14:54:05 +01:00 committed by Huin
parent ca81a64b42
commit e739c716b4
3 changed files with 33 additions and 1 deletions

View File

@ -18,10 +18,12 @@ import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"io" "io"
"net"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
"github.com/huin/goupnp/httpu"
"github.com/huin/goupnp/ssdp" "github.com/huin/goupnp/ssdp"
) )
@ -63,6 +65,9 @@ type MaybeRootDevice struct {
// the discovery of a device, regardless of if there was an error probing it. // the discovery of a device, regardless of if there was an error probing it.
Location *url.URL Location *url.URL
// The address from which the device was discovered (if known - otherwise nil).
LocalAddr net.IP
// Any error encountered probing a discovered device. // Any error encountered probing a discovered device.
Err error Err error
} }
@ -99,6 +104,9 @@ func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
} else { } else {
maybe.Root = root maybe.Root = root
} }
if i := response.Header.Get(httpu.LocalAddressHeader); len(i) > 0 {
maybe.LocalAddr = net.ParseIP(i)
}
} }
return results, nil return results, nil

View File

@ -143,9 +143,16 @@ func (httpu *HTTPUClient) Do(
continue continue
} }
// Set the related local address used to discover the device.
if a, ok := httpu.conn.LocalAddr().(*net.UDPAddr); ok {
response.Header.Add(LocalAddressHeader, a.IP.String())
}
responses = append(responses, response) responses = append(responses, response)
} }
// Timeout reached - return discovered responses. // Timeout reached - return discovered responses.
return responses, nil return responses, nil
} }
const LocalAddressHeader = "goupnp-local-address"

View File

@ -2,6 +2,7 @@ package goupnp
import ( import (
"fmt" "fmt"
"net"
"net/url" "net/url"
"github.com/huin/goupnp/soap" "github.com/huin/goupnp/soap"
@ -17,6 +18,7 @@ type ServiceClient struct {
RootDevice *RootDevice RootDevice *RootDevice
Location *url.URL Location *url.URL
Service *Service Service *Service
localAddr net.IP
} }
// NewServiceClients discovers services, and returns clients for them. err will // NewServiceClients discovers services, and returns clients for them. err will
@ -36,7 +38,7 @@ func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []e
continue continue
} }
deviceClients, err := NewServiceClientsFromRootDevice(maybeRootDevice.Root, maybeRootDevice.Location, searchTarget) deviceClients, err := newServiceClientsFromRootDevice(maybeRootDevice.Root, maybeRootDevice.Location, searchTarget, maybeRootDevice.LocalAddr)
if err != nil { if err != nil {
errors = append(errors, err) errors = append(errors, err)
continue continue
@ -61,6 +63,15 @@ func NewServiceClientsByURL(loc *url.URL, searchTarget string) ([]ServiceClient,
// a given root device. The loc parameter is simply assigned to the // a given root device. The loc parameter is simply assigned to the
// Location attribute of the returned ServiceClient(s). // Location attribute of the returned ServiceClient(s).
func NewServiceClientsFromRootDevice(rootDevice *RootDevice, loc *url.URL, searchTarget string) ([]ServiceClient, error) { func NewServiceClientsFromRootDevice(rootDevice *RootDevice, loc *url.URL, searchTarget string) ([]ServiceClient, error) {
return newServiceClientsFromRootDevice(rootDevice, loc, searchTarget, nil)
}
func newServiceClientsFromRootDevice(
rootDevice *RootDevice,
loc *url.URL,
searchTarget string,
lAddr net.IP,
) ([]ServiceClient, error) {
device := &rootDevice.Device device := &rootDevice.Device
srvs := device.FindService(searchTarget) srvs := device.FindService(searchTarget)
if len(srvs) == 0 { if len(srvs) == 0 {
@ -75,6 +86,7 @@ func NewServiceClientsFromRootDevice(rootDevice *RootDevice, loc *url.URL, searc
RootDevice: rootDevice, RootDevice: rootDevice,
Location: loc, Location: loc,
Service: srv, Service: srv,
localAddr: lAddr,
}) })
} }
return clients, nil return clients, nil
@ -86,3 +98,8 @@ func NewServiceClientsFromRootDevice(rootDevice *RootDevice, loc *url.URL, searc
func (client *ServiceClient) GetServiceClient() *ServiceClient { func (client *ServiceClient) GetServiceClient() *ServiceClient {
return client return client
} }
// LocalAddr returns the address from which the device was discovered (if known - otherwise empty).
func (client *ServiceClient) LocalAddr() net.IP {
return client.localAddr
}