upnp

package module
v0.0.0-...-11da932 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 2, 2021 License: MIT Imports: 9 Imported by: 44

README

upnp

package upnp provides a simple and opinionated interface to UPnP-enabled routers, allowing users to forward ports and discover their external IP address. Specific quirks:

  • When attempting to discover UPnP-enabled routers on the network, only the first such router is returned. If you have multiple routers, this may cause some trouble.

  • Forwarded ports are always symmetric, e.g. the router's port 9980 will be mapped to the client's port 9980. This will be unacceptable for some purposes, but symmetric mappings are the desired behavior 99% of the time, and they simplify the API.

  • TCP and UDP protocols are forwarded together.

  • Ports are forwarded permanently. Some other implementations lease a port mapping for a set duration, and then renew it periodically. This is nice, because it means mappings won't stick around after they've served their purpose. Unfortunately, some routers only support permanent mappings, so this package has chosen to support the lowest common denominator. To un-forward a port, you must use the Clear function (or do it manually).

Once you've discovered your router, you can retrieve its address by calling its Location method. This address can be supplied to Load to connect to the router directly, which is much faster than calling Discover.

See the godoc for full documentation.

example

import (
	"log"
	"gitlab.com/NebulousLabs/go-upnp"
)

func main() {
    // connect to router
    d, err := upnp.Discover()
    if err != nil {
        log.Fatal(err)
    }

    // discover external IP
    ip, err := d.ExternalIP()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Your external IP is:", ip)

    // forward a port
    err = d.Forward(9001, "upnp test")
    if err != nil {
        log.Fatal(err)
    }

    // un-forward a port
    err = d.Clear(9001)
    if err != nil {
        log.Fatal(err)
    }

    // record router's location
    loc := d.Location()

    // connect to router directly
    d, err = upnp.Load(loc)
    if err != nil {
        log.Fatal(err)
    }
}

motivation

Port forwarding and external IP discovery are two of the most common tasks required when creating a P2P network. This requires talking to your local router, usually via the UPnP protocol. There are a number of existing packages that provide this functionality, but I found all of them lacking in some respect. The most robust implementation I found was huin's goupnp, but its interface was clunky and required more boilerplate than I felt was necessary. So this package is really just a wrapper around the goupnp library, specifically tailored to the use cases listed above.

This makes the name a bit of a misnomer, I know; UPnP is much broader than port forwarding. But upnp is much more search-friendly than igdman (Internet Gateway Device Manager). If you think of something better, I'd love to hear it.

Documentation

Overview

Package upnp provides a simple and opinionated interface to UPnP-enabled routers, allowing users to forward ports and discover their external IP address. Specific quirks:

- When attempting to discover UPnP-enabled routers on the network, only the first such router is returned. If you have multiple routers, this may cause some trouble. But why would you do that?

- Forwarded ports are always symmetric, e.g. the router's port 9980 will be mapped to the client's port 9980. This will be unacceptable for some purposes, but too bad. Symmetric mappings are the desired behavior 99% of the time, and they save a function argument.

- TCP and UDP protocols are forwarded together.

- Ports are forwarded permanently. Some other implementations lease a port mapping for a set duration, and then renew it periodically. This is nice, because it means mappings won't stick around after they've served their purpose. Unfortunately, some routers only support permanent mappings, so this package has chosen to support the lowest common denominator. To un-forward a port, you must use the Clear function (or do it manually).

Once you've discovered your router, you can retrieve its address by calling its Location method. This address can be supplied to Load to connect to the router directly, which is much faster than calling Discover.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type IGD

type IGD struct {
	// contains filtered or unexported fields
}

An IGD provides an interface to the most commonly used functions of an Internet Gateway Device: discovering the external IP, and forwarding ports.

func Discover

func Discover() (*IGD, error)

Discover is deprecated; use DiscoverCtx instead.

func DiscoverCtx

func DiscoverCtx(ctx context.Context) (*IGD, error)

DiscoverCtx scans the local network for routers and returns the first UPnP-enabled router it encounters. It will try up to 3 times to find a router, sleeping a random duration between each attempt. This is to mitigate a race condition with many callers attempting to discover simultaneously.

func Load

func Load(rawurl string) (*IGD, error)

Load connects to the router service specified by rawurl. This is much faster than Discover. Generally, Load should only be called with values returned by the IGD's Location method.

func (*IGD) Clear

func (d *IGD) Clear(port uint16) error

Clear un-forwards a port, removing it from the router's port mapping table.

func (*IGD) ExternalIP

func (d *IGD) ExternalIP() (string, error)

ExternalIP returns the router's external IP.

func (*IGD) Forward

func (d *IGD) Forward(port uint16, desc string) error

Forward forwards the specified port, and adds its description to the router's port mapping table.

func (*IGD) ForwardTCP

func (d *IGD) ForwardTCP(port uint16, desc string) error

ForwardTCP forwards the specified TCP port, and adds its description to the router's port mapping table.

func (*IGD) ForwardUDP

func (d *IGD) ForwardUDP(port uint16, desc string) error

ForwardUDP forwards the specified UDP port, and adds its description to the router's port mapping table.

func (*IGD) IsForwardedTCP

func (d *IGD) IsForwardedTCP(port uint16) (bool, error)

IsForwardedTCP checks whether a specific TCP port is forwarded to this host

func (*IGD) IsForwardedUDP

func (d *IGD) IsForwardedUDP(port uint16) (bool, error)

IsForwardedUDP checks whether a specific UDP port is forwarded to this host

func (*IGD) Location

func (d *IGD) Location() string

Location returns the URL of the router, for future lookups (see Load).

Directories

Path Synopsis
goupnp is an implementation of a client for various UPnP services.
goupnp is an implementation of a client for various UPnP services.
dcps/internetgateway1
Client for UPnP Device Control Protocol Internet Gateway Device v1.
Client for UPnP Device Control Protocol Internet Gateway Device v1.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL