// Resolve an address string into a net.TCPAddr. We are a bit more strict than
// net.ResolveTCPAddr; we don't allow an empty host or port, and the host part
// must be a literal IP address.
func resolveAddr(addrStr string) (*net.TCPAddr, error) {
	ipStr, portStr, err := net.SplitHostPort(addrStr)
	if err != nil {
		// Before the fixing of bug #7011, tor doesn't put brackets around IPv6
		// addresses. Split after the last colon, assuming it is a port
		// separator, and try adding the brackets.
		parts := strings.Split(addrStr, ":")
		if len(parts) <= 2 {
			return nil, err
		}
		addrStr := "[" + strings.Join(parts[:len(parts)-1], ":") + "]:" + parts[len(parts)-1]
		ipStr, portStr, err = net.SplitHostPort(addrStr)
	}
	if err != nil {
		return nil, err
	}
	if ipStr == "" {
		return nil, net.InvalidAddrError(fmt.Sprintf("address string %q lacks a host part", addrStr))
	}
	if portStr == "" {
		return nil, net.InvalidAddrError(fmt.Sprintf("address string %q lacks a port part", addrStr))
	}
	ip := net.ParseIP(ipStr)
	if ip == nil {
		return nil, net.InvalidAddrError(fmt.Sprintf("not an IP string: %q", ipStr))
	}
	port, err := parsePort(portStr)
	if err != nil {
		return nil, err
	}
	return &net.TCPAddr{IP: ip, Port: port}, nil
}
Beispiel #2
0
func (d *Dailer) Dial(network, address string) (net.Conn, error) {
	switch network {
	case "tcp", "tcp4", "tcp6":
		if d.DNSCache != nil {
			if addr, ok := d.DNSCache.Get(address); ok {
				address = addr.(string)
			} else {
				if host, port, err := net.SplitHostPort(address); err == nil {
					if ips, err := net.LookupIP(host); err == nil && len(ips) > 0 {
						ip := ips[0].String()
						if _, ok := d.LoopbackAddrs[ip]; ok {
							return nil, net.InvalidAddrError(fmt.Sprintf("Invaid DNS Record: %s(%s)", host, ip))
						}
						addr := net.JoinHostPort(ip, port)
						d.DNSCache.Set(address, addr, time.Now().Add(d.DNSCacheExpires))
						glog.V(3).Infof("direct Dial cache dns %#v=%#v", address, addr)
						address = addr
					}
				}
			}
		}
	default:
		break
	}
	return d.Dialer.Dial(network, address)
}
Beispiel #3
0
func (i *IP2ASNClient) parseIP(IP string) (net.IP, error) {
	I := net.ParseIP(IP)
	if I == nil {
		return nil, net.InvalidAddrError(IP)
	}
	return I, nil
}
Beispiel #4
0
// ParseControlPortString parses a string representation of a control port
// address into a network/address string pair suitable for use with "dial".
//
// Valid string representations are:
//  * tcp://address:port
//  * unix://path
//  * port (Translates to tcp://127.0.0.1:port)
func ParseControlPortString(raw string) (network, addr string, err error) {
	// Try parsing it as a naked port.
	if _, err = strconv.ParseUint(raw, 10, 16); err == nil {
		raw = "tcp://127.0.0.1:" + raw
	}

	// Ok, parse/validate the URI.
	uri, err := url.Parse(raw)
	if err != nil {
		return "", "", err
	}
	if uri.Opaque != "" || uri.RawQuery != "" || uri.Fragment != "" {
		return "", "", net.InvalidAddrError("uri has Opaque/Query/Fragment")
	}
	switch uri.Scheme {
	case "tcp":
		if uri.Path != "" {
			return "", "", net.InvalidAddrError("tcp uri has a path")
		}
		tcpAddr, err := net.ResolveTCPAddr(uri.Scheme, uri.Host)
		if err != nil {
			return "", "", err
		}
		if tcpAddr.Port == 0 {
			return "", "", net.InvalidAddrError("tcp uri is missing a port")
		}
		return uri.Scheme, uri.Host, nil
	case "unix":
		if uri.Host != "" {
			return "", "", net.InvalidAddrError("unix uri has a host")
		}
		_, err := net.ResolveUnixAddr(uri.Scheme, uri.Path)
		if err != nil {
			return "", "", err
		}
		return uri.Scheme, uri.Path, nil
	}
	return "", "", net.InvalidAddrError("unknown scheme: " + uri.Scheme)
}
Beispiel #5
0
func ipToSocksAddr(family int, ip net.IP, port int, zone string) (unix.Sockaddr, error) {
	switch family {
	case unix.AF_INET:
		if len(ip) == 0 {
			ip = net.IPv4zero
		}
		if ip = ip.To4(); ip == nil {
			return nil, net.InvalidAddrError("non-IPv4 address")
		}
		sa := new(unix.SockaddrInet4)
		for i := 0; i < net.IPv4len; i++ {
			sa.Addr[i] = ip[i]
		}
		sa.Port = port
		return sa, nil
	case unix.AF_INET6:
		if len(ip) == 0 {
			ip = net.IPv6zero
		}
		// IPv4 callers use 0.0.0.0 to mean "announce on any available address".
		// In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0",
		// which it refuses to do.  Rewrite to the IPv6 unspecified address.
		if ip.Equal(net.IPv4zero) {
			ip = net.IPv6zero
		}
		if ip = ip.To16(); ip == nil {
			return nil, net.InvalidAddrError("non-IPv6 address")
		}
		sa := new(unix.SockaddrInet6)
		for i := 0; i < net.IPv6len; i++ {
			sa.Addr[i] = ip[i]
		}
		sa.Port = port
		sa.ZoneId = uint32(zoneToInt(zone))
		return sa, nil
	}
	return nil, net.InvalidAddrError("unexpected socket family")
}
Beispiel #6
0
// Sigh, pt.resolveAddr() isn't exported.  Include our own getto version that
// doesn't work around #7011, because we don't work with pre-0.2.5.x tor, and
// all we care about is validation anyway.
func resolveAddrStr(addrStr string) (*net.TCPAddr, error) {
	ipStr, portStr, err := net.SplitHostPort(addrStr)
	if err != nil {
		return nil, err
	}

	if ipStr == "" {
		return nil, net.InvalidAddrError(fmt.Sprintf("address string %q lacks a host part", addrStr))
	}
	if portStr == "" {
		return nil, net.InvalidAddrError(fmt.Sprintf("address string %q lacks a port part", addrStr))
	}
	ip := net.ParseIP(ipStr)
	if ip == nil {
		return nil, net.InvalidAddrError(fmt.Sprintf("not an IP string: %q", ipStr))
	}
	port, err := strconv.ParseUint(portStr, 10, 16)
	if err != nil {
		return nil, net.InvalidAddrError(fmt.Sprintf("not a Port string: %q", portStr))
	}

	return &net.TCPAddr{IP: ip, Port: int(port), Zone: ""}, nil
}
Beispiel #7
0
func sockaddr(family int, address string) (syscall.Sockaddr, error) {
	switch family {
	case syscall.AF_INET:
		a, err := net.ResolveIPAddr("ip4", address)
		if err != nil {
			return nil, err
		}
		if len(a.IP) == 0 {
			a.IP = net.IPv4zero
		}
		if a.IP = a.IP.To4(); a.IP == nil {
			return nil, net.InvalidAddrError("non-ipv4 address")
		}
		sa := &syscall.SockaddrInet4{}
		copy(sa.Addr[:], a.IP)
		return sa, nil
	case syscall.AF_INET6:
		a, err := net.ResolveIPAddr("ip6", address)
		if err != nil {
			return nil, err
		}
		if len(a.IP) == 0 {
			a.IP = net.IPv6unspecified
		}
		if a.IP.Equal(net.IPv4zero) {
			a.IP = net.IPv6unspecified
		}
		if a.IP = a.IP.To16(); a.IP == nil || a.IP.To4() != nil {
			return nil, net.InvalidAddrError("non-ipv6 address")
		}
		sa := &syscall.SockaddrInet6{ZoneId: zoneToUint32(a.Zone)}
		copy(sa.Addr[:], a.IP)
		return sa, nil
	default:
		return nil, net.InvalidAddrError("unexpected family")
	}
}
Beispiel #8
0
func (d *Dialer) Dial(network, address string) (conn net.Conn, err error) {
	glog.V(3).Infof("Dail(%#v, %#v)", network, address)

	switch network {
	case "tcp", "tcp4", "tcp6":
		if d.Resolver != nil {
			if host, port, err := net.SplitHostPort(address); err == nil {
				if ips, err := d.Resolver.LookupIP(host); err == nil {
					if len(ips) == 0 {
						return nil, net.InvalidAddrError(fmt.Sprintf("Invaid DNS Record: %s", address))
					}
					return d.dialMulti(network, address, ips, port)
				}
			}
		}
	}

	return d.Dialer.Dial(network, address)
}
Beispiel #9
0
func (s *UTPSocket) Connect(addr *UTPAddr) (int, error) {
	// func (s *UTPSocket) Connect(to *syscall.RawSockaddr, tolen int) int {

	if addr == nil {
		return 0, net.InvalidAddrError("No address given.")
	}

	sa, err := addr.Sockaddr()
	if err != nil {
		return 0, err
	}

	rsa, err := sockaddr.NewRawSockaddr(&sa)
	if err != nil {
		return 0, err
	}

	ptr := (*C.struct_sockaddr)(unsafe.Pointer(&rsa.Raw))
	ret := int(C.utp_connect(s.raw, ptr, C.socklen_t(rsa.Len)))
	return ret, nil
}
Beispiel #10
0
func tcpAddrToSockaddr(addr string) (sa unix.Sockaddr, err error) {
	if len(addr) > 0 && addr[0] == ':' {
		addr = "0.0.0.0" + addr
	}
	tcpAddr, err := net.ResolveTCPAddr("tcp", addr)

	if err != nil {
		return
	}
	if ip := tcpAddr.IP.To4(); ip != nil {
		sa := new(unix.SockaddrInet4)
		sa.Port = tcpAddr.Port
		copy(sa.Addr[:], ip)
		return sa, nil
	} else if ip := tcpAddr.IP.To16(); ip != nil {
		sa := new(unix.SockaddrInet6)
		sa.Port = tcpAddr.Port
		copy(sa.Addr[:], ip)
		sa.ZoneId = uint32(zoneToInt(tcpAddr.Zone))
		return sa, nil
	}
	return nil, net.InvalidAddrError("unknown address")
}
Beispiel #11
0
func (d *Dialer) Dial(network, address string) (conn net.Conn, err error) {
	glog.V(3).Infof("Dail(%#v, %#v)", network, address)

	switch network {
	case "tcp", "tcp4", "tcp6":
		if d.DNSCache != nil {
			if addr, ok := d.DNSCache.Get(address); ok {
				address = addr.(string)
			} else {
				if host, port, err := net.SplitHostPort(address); err == nil {
					if ips, err := net.LookupIP(host); err == nil && len(ips) > 0 {
						ip := ips[0].String()
						if d.LoopbackAddrs != nil {
							if _, ok := d.LoopbackAddrs[ip]; ok {
								return nil, net.InvalidAddrError(fmt.Sprintf("Invaid DNS Record: %s(%s)", host, ip))
							}
						}
						addr := net.JoinHostPort(ip, port)
						expiry := d.DNSCacheExpiry
						if expiry == 0 {
							expiry = DefaultDNSCacheExpiry
						}
						d.DNSCache.Set(address, addr, time.Now().Add(expiry))
						glog.V(3).Infof("direct Dial cache dns %#v=%#v", address, addr)
						address = addr
					}
				}
			}
		}
	default:
		break
	}

	if d.Level <= 1 {
		retry := d.RetryTimes
		if retry == 0 {
			retry = DefaultRetryTimes
		}

		for i := 0; i < retry; i++ {
			conn, err = d.Dialer.Dial(network, address)
			if err == nil || i == retry-1 {
				break
			}
			retryDelay := d.RetryDelay
			if retryDelay == 0 {
				retryDelay = DefaultRetryDelay
			}
			time.Sleep(retryDelay)
		}
		return conn, err
	} else {
		type racer struct {
			c net.Conn
			e error
		}

		lane := make(chan racer, d.Level)
		retry := (d.RetryTimes + d.Level - 1) / d.Level
		for i := 0; i < retry; i++ {
			for j := 0; j < d.Level; j++ {
				go func(addr string, c chan<- racer) {
					conn, err := d.Dialer.Dial(network, addr)
					lane <- racer{conn, err}
				}(address, lane)
			}

			var r racer
			for k := 0; k < d.Level; k++ {
				r = <-lane
				if r.e == nil {
					go func(count int) {
						var r1 racer
						for ; count > 0; count-- {
							r1 = <-lane
							if r1.c != nil {
								r1.c.Close()
							}
						}
					}(d.Level - 1 - k)
					return r.c, nil
				}
			}

			if i == retry-1 {
				return nil, r.e
			}
		}
	}

	return nil, net.UnknownNetworkError("Unkown transport/direct error")
}