示例#1
0
// Creates a port mapping. The mapping process is continually attempted and
// maintained in the background, but the Mapping interface is returned
// immediately without blocking.
//
// As the mapping is attempted asynchronously in the background, the mapping
// will not be active when this function returns. Use the Mapping interface
// returned to determine when the mapping becomes active.
//
// A successful mapping is not guaranteed.
//
// See the Config struct and the Mapping interface for more information.
func New(cfg Config) (Mapping, error) {
	if IsGloballyRoutable() {
		return nil, ErrGlobalIP
	}

	gwa, err := gateway.GetIPs()
	if err != nil {
		return nil, err
	}

	if cfg.Lifetime == 0 {
		cfg.Lifetime = DefaultLifetime
	}

	m := &mapping{
		cfg:        cfg,
		abortChan:  make(chan struct{}),
		notifyChan: make(chan struct{}, 1),
	}

	ssdp.Start()
	go m.portMappingLoop(gwa)

	return m, nil
}
示例#2
0
// Attempt to obtain the external IP address from the default gateway.
//
// If the host has a globally routable IP, returns that IP.
//
// Currently this only tries NAT-PMP and does not attempt to learn the external
// IP address via UPnP.
//
// This function is not very useful because the IP address returned may still
// be an RFC1918 address, due to the possibility of a double NAT setup. There
// are better solutions for obtaining one's public IP address, such as STUN.
func ExternalAddr() (net.IP, error) {
	if gr, ip := isGloballyRoutable(); gr {
		return ip, nil
	}

	gwa, err := gateway.GetIPs()
	if err != nil {
		return nil, err
	}

	var extaddr net.IP
	for _, gw := range gwa {
		extaddr, err = natpmp.GetExternalAddr(gw)
		if err == nil {
			return extaddr, nil
		}
	}

	return nil, err
}