-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide an API to use specific ip addresses for discovery #59
Comments
I have sketched some changes here, to see.
Overall, in this form it is breaking the API. At some point i though that it probably should exist a(nother) Edit: looking further,
I dont share the sketch because it contains lots of useless dup code that would not exist if i had used a fork directly, i worked around. Although, here is the resulting equivalent invocation of the API, to figure how different that would be
|
I ended up crafting many things. there is a new discovery client like client := goupnp.Discovery{
Client: goupnp.AutoDiscover("0.0.0.0"),
} A new kind to lookup services and provide concrete implementations such as svcTable := lookup.ServiceTable{
internetgateway2.URN_WANIPConnection_1: func(services goupnp.MultiServiceClient) (out lookup.ServiceImplementations) {
for _, v := range internetgateway2.NewWANIPConnection1MultiClients(services) {
out = append(out, v)
}
return
}, Then it is possible to resolve services to implementation with a call like searchTargets := svcTable.Targets() // internetgateway2.URN_WANIPConnection_1, internetgateway2.URN_WANIPConnection_2 etc....
services, _, err := client.NewServiceClientsCtx(context.Background(), searchTargets...)
if err != nil {
return err
}
// do some filterings...
// hostwhatever := services.Filter(goupnp.ServiceHost("192..."))
impls := svcTable.Implement(services)
// impls is interface []lookup.ServiceImplementation, which in turn is one of ` internetgateway2.NewWANIPConnection1MultiClients` , ` internetgateway2.NewWANIPConnection2MultiClients` etc...
for _, impl := range impls {
fmt.Printf("%T\n", impl)
// need type assert
// impl.(portmapping.PortMapper).AddPortMapping()
} The Template is modified to instantiate DCP client for a func NewDeviceProtection1MultiClients(mutiClients goupnp.MultiServiceClient) []*DeviceProtection1 {
services := mutiClients.Filter(goupnp.ServiceType(URN_DeviceProtection_1)) // The service clients are filtered to keep only those that corresponds to the related service definition
clients := make([]*DeviceProtection1, len(services))
for i := range services {
clients[i] = &DeviceProtection1{services[i]}
}
return clients
} The Doing so, i was able to define an appropriate IGW service table var IGW = lookup.ServiceTable{
internetgateway1.URN_WANIPConnection_1: func(services goupnp.MultiServiceClient) (out lookup.ServiceImplementations) {
for _, v := range internetgateway1.NewWANIPConnection1MultiClients(services) {
out = append(out, v)
}
return
},
internetgateway2.URN_WANIPConnection_2: func(services goupnp.MultiServiceClient) (out lookup.ServiceImplementations) {
for _, v := range internetgateway2.NewWANIPConnection2MultiClients(services) {
out = append(out, v)
}
return
},
} And its accompanying var out []PortMapperClient
searchTargets := IGW.Targets()
services, _, err := client.NewServiceClientsCtx(context.Background(), searchTargets...)
if err != nil {
return out, err
}
impls := IGW.ExpandAnyAddr(services)
for _, impl := range impls {
switch x := impl.(type) {
case lookup.AnyAddrServiceImplementation:
out = append(out, PortMapperClient{
PortMapper: x.ServiceImplementation.(PortMapper),
ServiceImplementation: impl,
})
case PortMapper:
out = append(out, PortMapperClient{
PortMapper: x,
ServiceImplementation: impl,
})
default:
log.Printf("not a port mapper %T", x)
}
} in the end it can fetch all clients, resolve the virtual address thing and get the right local address to use for the call to for _, impl := range impls {
switch x := impl.(type) {
case lookup.AnyAddrServiceImplementation:
fmt.Printf("%v should port map using %v\n", x.ServiceImplementation.LocalAddr(), impl.LocalAddr())
}
_, ok := impl.(portmapping.PortMapper)
fmt.Printf("%T PortMapper=%v\n", impl, ok)
printService(*impl.GetServiceClient())
} anyway.. Much.... much changes ! |
Sorry for the slow reply, I tend to only deal with this repo on weekends. A few questions/comments:
|
hi, no worries for the late reply, thanks for the inputs. About functional options, it surely could do few things, although, this is still breaking the API signature. I dont think this is right for someone that built up some APIs that relies on interfaces, or functions type def. About About About
Although, this is definitely an intentional major shift in regard to the current API design. Overall, besides the specific implementation details change, like the dedup mechanism, which could be made configurable, one way or another, it is a lot of changes, despite my attempts at being conservative (i tried = ). I feel mixed about it regarding the shift in the design api. Maybe i kept that away and for an eventual V2 this is considered. |
Hi !
I need to test upnp connectivity over virtual "any addresses" IE
0.0.0.0
.The current API auto detects and auto selects the IPs based on the output of
net.Interface
which does not include those.For consistency this line might be an issue
goupnp/httpu/httpu.go
Line 147 in 8c07ff7
Indeed, when listening upon v4AnyAddr, here at least, it returns AnyAddrV6, ie
[::]
.... I am not looking forward for ipv6 support.The text was updated successfully, but these errors were encountered: