Example #1
0
// createPortMapping creates a NAT port mapping, or nil if none requested or found.
func CreatePortMapping(flags *TorrentFlags) (nat NAT, err error) {
	if flags.UseUPnP && flags.UseNATPMP {
		err = fmt.Errorf("Cannot specify both -useUPnP and -useNATPMP")
		return
	}
	if flags.UseUPnP {
		log.Println("Using UPnP to open port.")
		nat, err = Discover()
	}
	if flags.UseNATPMP {
		var gatewayIP net.IP
		if flags.Gateway == "" {
			log.Printf("useNATPMP but gateway not provided, trying discovery")
			gatewayIP, err = gateway.DiscoverGateway()
			if err != nil {
				return
			}
			log.Printf("...discovered gateway IP: %s", gatewayIP)
		} else {
			gatewayIP = net.ParseIP(flags.Gateway)
		}
		log.Println("Using NAT-PMP to open port.")
		if gatewayIP == nil {
			err = fmt.Errorf("Could not parse gateway %q", flags.Gateway)
		}
		nat = NewNatPMP(gatewayIP)
	}
	return
}
Example #2
0
// TODO: improve this. We currently assume that (on most networks)
// the router is X.X.X.1 in a local LAN range.
func potentialGateways() (gws []net.IP) {
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil
	}

	for _, iface := range ifaces {
		if iface.Flags == net.FlagLoopback {
			continue
		}
		ifaddrs, err := iface.Addrs()
		if err != nil {
			return gws
		}
		for _, addr := range ifaddrs {
			switch x := addr.(type) {
			case *net.IPNet:
				if lan10.Contains(x.IP) || lan176.Contains(x.IP) || lan192.Contains(x.IP) {
					ip := x.IP.Mask(x.Mask).To4()
					if ip != nil {
						ip[3] = ip[3] | 0x01
						gws = append(gws, ip)
					}
				}
			}
		}
	}
	wip, err := gateway.DiscoverGateway()
	if err == nil {
		gws = append(gws, wip)
	}
	return gws
}
Example #3
0
// Create a NAT-PMP client for the NAT-PMP server at the default gateway.
func NewClientForDefaultGateway(timeout time.Duration) (nat *Client, err error) {
	var g net.IP
	g, err = gateway.DiscoverGateway()
	if err != nil {
		return
	}
	nat = NewClient(g, timeout)
	return
}
Example #4
0
// Create a NAT-PMP client for the NAT-PMP server at the default gateway.
func NewClientForDefaultGateway() (nat *Client, err error) {
	var g net.IP
	g, err = gateway.DiscoverGateway()
	if err != nil {
		return
	}
	nat = NewClient(g)
	return
}
Example #5
0
func discoverNATPMP() <-chan NAT {
	res := make(chan NAT, 1)

	ip, err := gateway.DiscoverGateway()
	if err == nil {
		go discoverNATPMPWithAddr(res, ip)
	}

	return res
}
Example #6
0
func Discover(renewal, timeout time.Duration) []nat.Device {
	ip, err := gateway.DiscoverGateway()
	if err != nil {
		l.Debugln("Failed to discover gateway", err)
		return nil
	}
	if ip == nil || ip.IsUnspecified() {
		return nil
	}

	l.Debugln("Discovered gateway at", ip)

	c := natpmp.NewClient(ip, timeout)
	// Try contacting the gateway, if it does not respond, assume it does not
	// speak NAT-PMP.
	_, err = c.GetExternalAddress()
	if err != nil && strings.Contains(err.Error(), "Timed out") {
		l.Debugln("Timeout trying to get external address, assume no NAT-PMP available")
		return nil
	}

	var localIP net.IP
	// Port comes from the natpmp package
	conn, err := net.DialTimeout("udp", net.JoinHostPort(ip.String(), "5351"), timeout)
	if err == nil {
		conn.Close()
		localIPAddress, _, err := net.SplitHostPort(conn.LocalAddr().String())
		if err == nil {
			localIP = net.ParseIP(localIPAddress)
		} else {
			l.Debugln("Failed to lookup local IP", err)
		}
	}

	return []nat.Device{&wrapper{
		renewal:   renewal,
		localIP:   localIP,
		gatewayIP: ip,
		client:    c,
	}}
}