Add a guide for using internet gateway clients.
This attempts to help with #36.
This commit is contained in:
parent
49508fba00
commit
86667cb88e
133
GUIDE.md
Normal file
133
GUIDE.md
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
# Guide
|
||||||
|
|
||||||
|
This is a quick guide with example code for common use cases that might be
|
||||||
|
helpful for people wanting a quick guide to common ways that people would
|
||||||
|
want to use this library.
|
||||||
|
|
||||||
|
## Internet Gateways
|
||||||
|
|
||||||
|
`goupnp/dcps/internetgateway1` and `goupnp/dcps/internetgateway2` implement
|
||||||
|
different version standards that allow clients to interact with devices like
|
||||||
|
home consumer routers, but you can probably get by with just
|
||||||
|
`internetgateway2`. Some very common use cases to talk to such devices are:
|
||||||
|
|
||||||
|
- Requesting the external Internet-facing IP address.
|
||||||
|
- Requesting a port be forwarded from the external (Internet-facing) interface
|
||||||
|
to a port on the LAN.
|
||||||
|
|
||||||
|
Different routers implement different standards, so you may have to request
|
||||||
|
multiple clients to find the one that your router needs. The most useful ones
|
||||||
|
for the purpose above can be requested with the following functions:
|
||||||
|
|
||||||
|
- `internetgateway2.NewWANIPConnection1Clients()`
|
||||||
|
- `internetgateway2.NewWANIPConnection2Clients()`
|
||||||
|
- `internetgateway2.NewWANPPPConnection1Clients()`
|
||||||
|
|
||||||
|
Fortunately, each of the clients returned by these functions provide the same
|
||||||
|
method signatures for the purposes listed above. So you could request multiple
|
||||||
|
clients, and whichever one you find, and return it from a function in a variable
|
||||||
|
of the common interface, e.g:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RouterClient interface {
|
||||||
|
AddPortMapping(
|
||||||
|
NewRemoteHost string,
|
||||||
|
NewExternalPort uint16,
|
||||||
|
NewProtocol string,
|
||||||
|
NewInternalPort uint16,
|
||||||
|
NewInternalClient string,
|
||||||
|
NewEnabled bool,
|
||||||
|
NewPortMappingDescription string,
|
||||||
|
NewLeaseDuration uint32,
|
||||||
|
) (err error)
|
||||||
|
|
||||||
|
GetExternalIPAddress() (
|
||||||
|
NewExternalIPAddress string,
|
||||||
|
err error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PickRouterClient(ctx context.Context) (RouterClient, error) {
|
||||||
|
tasks, _ := errgroup.WithContext(ctx)
|
||||||
|
// Request each type of client in parallel, and return what is found.
|
||||||
|
var ip1Clients []*internetgateway2.WANIPConnection1
|
||||||
|
tasks.Go(func() error {
|
||||||
|
var err error
|
||||||
|
ip1Clients, _, err = internetgateway2.NewWANIPConnection1Clients()
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
var ip2Clients []*internetgateway2.WANIPConnection2
|
||||||
|
tasks.Go(func() error {
|
||||||
|
var err error
|
||||||
|
ip2Clients, _, err = internetgateway2.NewWANIPConnection2Clients()
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
var ppp1Clients []*internetgateway2.WANPPPConnection1
|
||||||
|
tasks.Go(func() error {
|
||||||
|
var err error
|
||||||
|
ppp1Clients, _, err = internetgateway2.NewWANPPPConnection1Clients()
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := tasks.Wait(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trivial handling for where we find exactly one device to talk to, you
|
||||||
|
// might want to provide more flexible handling than this if multiple
|
||||||
|
// devices are found.
|
||||||
|
switch {
|
||||||
|
case len(ip2Clients) == 1:
|
||||||
|
return ip2Clients[0], nil
|
||||||
|
case len(ip1Clients) == 1:
|
||||||
|
return ip1Clients[0], nil
|
||||||
|
case len(ppp1Clients) == 1:
|
||||||
|
return ppp1Clients[0], nil
|
||||||
|
default:
|
||||||
|
return nil, errors.New("multiple or no services found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You could then use this function to create a client, and both request the
|
||||||
|
external IP address and forward it to a port on your local network, e.g:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetIPAndForwardPort(ctx context.Context) error {
|
||||||
|
client, err := PickRouterClient(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
externalIP, err := client.GetExternalIPAddress()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("Our external IP address is: ", externalIP)
|
||||||
|
|
||||||
|
return client.AddPortMapping(
|
||||||
|
"",
|
||||||
|
// External port number to expose to Internet:
|
||||||
|
1234,
|
||||||
|
// Forward TCP (this could be "UDP" if we wanted that instead).
|
||||||
|
"TCP",
|
||||||
|
// Internal port number on the LAN to forward to.
|
||||||
|
// Some routers might not support this being different to the external
|
||||||
|
// port number.
|
||||||
|
1234,
|
||||||
|
// Internal address on the LAN we want to forward to.
|
||||||
|
"192.168.1.6",
|
||||||
|
// Enabled:
|
||||||
|
true,
|
||||||
|
// Informational description for the client requesting the port forwarding.
|
||||||
|
"MyProgramName",
|
||||||
|
// How long should the port forward last for in seconds.
|
||||||
|
// If you want to keep it open for longer and potentially across router
|
||||||
|
// resets, you might want to periodically request before this elapses.
|
||||||
|
3600,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The code above is of course just a relatively trivial example that you can
|
||||||
|
tailor to your own use case.
|
34
README.md
34
README.md
@ -1,40 +1,38 @@
|
|||||||
goupnp is a UPnP client library for Go
|
goupnp is a UPnP client library for Go
|
||||||
|
|
||||||
Installation
|
## Installation
|
||||||
------------
|
|
||||||
|
|
||||||
Run `go get -u github.com/huin/goupnp`.
|
Run `go get -u github.com/huin/goupnp`.
|
||||||
|
|
||||||
Documentation
|
## Documentation
|
||||||
-------------
|
|
||||||
|
See [GUIDE.md](GUIDE.md) for a quick start on the most common use case for this
|
||||||
|
library.
|
||||||
|
|
||||||
Supported DCPs (you probably want to start with one of these):
|
Supported DCPs (you probably want to start with one of these):
|
||||||
|
|
||||||
* [ av1](https://godoc.org/github.com/huin/goupnp/dcps/av1) - Client for UPnP Device Control Protocol MediaServer v1 and MediaRenderer v1.
|
- [ av1](https://godoc.org/github.com/huin/goupnp/dcps/av1) - Client for UPnP Device Control Protocol MediaServer v1 and MediaRenderer v1.
|
||||||
* [ internetgateway1](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway1) - Client for UPnP Device Control Protocol Internet Gateway Device v1.
|
- [ internetgateway1](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway1) - Client for UPnP Device Control Protocol Internet Gateway Device v1.
|
||||||
* [ internetgateway2](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway2) - Client for UPnP Device Control Protocol Internet Gateway Device v2.
|
- [ internetgateway2](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway2) - Client for UPnP Device Control Protocol Internet Gateway Device v2.
|
||||||
|
|
||||||
Core components:
|
Core components:
|
||||||
|
|
||||||
* [ (goupnp)](https://godoc.org/github.com/huin/goupnp) core library - contains datastructures and utilities typically used by the implemented DCPs.
|
- [ (goupnp)](https://godoc.org/github.com/huin/goupnp) core library - contains datastructures and utilities typically used by the implemented DCPs.
|
||||||
* [ httpu](https://godoc.org/github.com/huin/goupnp/httpu) HTTPU implementation, underlies SSDP.
|
- [ httpu](https://godoc.org/github.com/huin/goupnp/httpu) HTTPU implementation, underlies SSDP.
|
||||||
* [ ssdp](https://godoc.org/github.com/huin/goupnp/ssdp) SSDP client implementation (simple service discovery protocol) - used to discover UPnP services on a network.
|
- [ ssdp](https://godoc.org/github.com/huin/goupnp/ssdp) SSDP client implementation (simple service discovery protocol) - used to discover UPnP services on a network.
|
||||||
* [ soap](https://godoc.org/github.com/huin/goupnp/soap) SOAP client implementation (simple object access protocol) - used to communicate with discovered services.
|
- [ soap](https://godoc.org/github.com/huin/goupnp/soap) SOAP client implementation (simple object access protocol) - used to communicate with discovered services.
|
||||||
|
|
||||||
|
## Regenerating dcps generated source code:
|
||||||
Regenerating dcps generated source code:
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
1. Build code generator:
|
1. Build code generator:
|
||||||
|
|
||||||
`go get -u github.com/huin/goupnp/cmd/goupnpdcpgen`
|
`go get -u github.com/huin/goupnp/cmd/goupnpdcpgen`
|
||||||
|
|
||||||
2. Regenerate the code:
|
2. Regenerate the code:
|
||||||
|
|
||||||
`go generate ./...`
|
`go generate ./...`
|
||||||
|
|
||||||
Supporting additional UPnP devices and services:
|
## Supporting additional UPnP devices and services:
|
||||||
------------------------------------------------
|
|
||||||
|
|
||||||
Supporting additional services is, in the trivial case, simply a matter of
|
Supporting additional services is, in the trivial case, simply a matter of
|
||||||
adding the service to the `dcpMetadata` whitelist in `cmd/goupnpdcpgen/metadata.go`,
|
adding the service to the `dcpMetadata` whitelist in `cmd/goupnpdcpgen/metadata.go`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user