// 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 }
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) }
func (i *IP2ASNClient) parseIP(IP string) (net.IP, error) { I := net.ParseIP(IP) if I == nil { return nil, net.InvalidAddrError(IP) } return I, nil }
// 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) }
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") }
// 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 }
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") } }
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) }
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 }
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") }
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") }