func newLookupPort(network, service string) (port int, err error) { acquireThread() defer releaseThread() var stype int32 switch network { case "tcp4", "tcp6": stype = syscall.SOCK_STREAM case "udp4", "udp6": stype = syscall.SOCK_DGRAM } hints := syscall.AddrinfoW{ Family: syscall.AF_UNSPEC, Socktype: stype, Protocol: syscall.IPPROTO_IP, } var result *syscall.AddrinfoW e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result) if e != nil { return 0, os.NewSyscallError("GetAddrInfoW", e) } defer syscall.FreeAddrInfoW(result) if result == nil { return 0, os.NewSyscallError("LookupPort", syscall.EINVAL) } addr := unsafe.Pointer(result.Addr) switch result.Family { case syscall.AF_INET: a := (*syscall.RawSockaddrInet4)(addr) return int(syscall.Ntohs(a.Port)), nil case syscall.AF_INET6: a := (*syscall.RawSockaddrInet6)(addr) return int(syscall.Ntohs(a.Port)), nil } return 0, os.NewSyscallError("LookupPort", syscall.EINVAL) }
func newLookupIP(name string) (addrs []IP, err error) { acquireThread() defer releaseThread() hints := syscall.AddrinfoW{ Family: syscall.AF_UNSPEC, Socktype: syscall.SOCK_STREAM, Protocol: syscall.IPPROTO_IP, } var result *syscall.AddrinfoW e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result) if e != nil { return nil, os.NewSyscallError("GetAddrInfoW", e) } defer syscall.FreeAddrInfoW(result) addrs = make([]IP, 0, 5) for ; result != nil; result = result.Next { addr := unsafe.Pointer(result.Addr) switch result.Family { case syscall.AF_INET: a := (*syscall.RawSockaddrInet4)(addr).Addr addrs = append(addrs, IPv4(a[0], a[1], a[2], a[3])) case syscall.AF_INET6: a := (*syscall.RawSockaddrInet6)(addr).Addr addrs = append(addrs, IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]}) default: return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS) } } return addrs, nil }
func lookup(name string, family int32) ([]net.IPAddr, error) { hints := syscall.AddrinfoW{ Family: family, Socktype: syscall.SOCK_STREAM, Protocol: syscall.IPPROTO_IP, } var result *syscall.AddrinfoW e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result) if e != nil { return nil, &net.DNSError{Err: os.NewSyscallError("getaddrinfow", e).Error(), Name: name} } defer syscall.FreeAddrInfoW(result) addrs := make([]net.IPAddr, 0, 5) for ; result != nil; result = result.Next { addr := unsafe.Pointer(result.Addr) switch result.Family { case syscall.AF_INET: a := (*syscall.RawSockaddrInet4)(addr).Addr addrs = append(addrs, net.IPAddr{IP: net.IPv4(a[0], a[1], a[2], a[3])}) case syscall.AF_INET6: a := (*syscall.RawSockaddrInet6)(addr).Addr // FIXME: expose zoneToString ? // zone := zoneToString(int((*syscall.RawSockaddrInet6)(addr).Scope_id)) zone := "" addrs = append(addrs, net.IPAddr{IP: net.IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]}, Zone: zone}) default: return nil, &net.DNSError{Err: syscall.EWINDOWS.Error(), Name: name} } } return addrs, nil }
func (r *Resolver) lookupIP(ctx context.Context, name string) ([]IPAddr, error) { // TODO(bradfitz,brainman): use ctx more. See TODO below. type ret struct { addrs []IPAddr err error } ch := make(chan ret, 1) go func() { acquireThread() defer releaseThread() hints := syscall.AddrinfoW{ Family: syscall.AF_UNSPEC, Socktype: syscall.SOCK_STREAM, Protocol: syscall.IPPROTO_IP, } var result *syscall.AddrinfoW e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result) if e != nil { ch <- ret{err: &DNSError{Err: winError("getaddrinfow", e).Error(), Name: name}} } defer syscall.FreeAddrInfoW(result) addrs := make([]IPAddr, 0, 5) for ; result != nil; result = result.Next { addr := unsafe.Pointer(result.Addr) switch result.Family { case syscall.AF_INET: a := (*syscall.RawSockaddrInet4)(addr).Addr addrs = append(addrs, IPAddr{IP: IPv4(a[0], a[1], a[2], a[3])}) case syscall.AF_INET6: a := (*syscall.RawSockaddrInet6)(addr).Addr zone := zoneToString(int((*syscall.RawSockaddrInet6)(addr).Scope_id)) addrs = append(addrs, IPAddr{IP: IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]}, Zone: zone}) default: ch <- ret{err: &DNSError{Err: syscall.EWINDOWS.Error(), Name: name}} } } ch <- ret{addrs: addrs} }() select { case r := <-ch: return r.addrs, r.err case <-ctx.Done(): // TODO(bradfitz,brainman): cancel the ongoing // GetAddrInfoW? It would require conditionally using // GetAddrInfoEx with lpOverlapped, which requires // Windows 8 or newer. I guess we'll need oldLookupIP, // newLookupIP, and newerLookUP. // // For now we just let it finish and write to the // buffered channel. return nil, &DNSError{ Name: name, Err: ctx.Err().Error(), IsTimeout: ctx.Err() == context.DeadlineExceeded, } } }
func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int, error) { if r.PreferGo { return lookupPortMap(network, service) } // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this. acquireThread() defer releaseThread() var stype int32 switch network { case "tcp4", "tcp6": stype = syscall.SOCK_STREAM case "udp4", "udp6": stype = syscall.SOCK_DGRAM } hints := syscall.AddrinfoW{ Family: syscall.AF_UNSPEC, Socktype: stype, Protocol: syscall.IPPROTO_IP, } var result *syscall.AddrinfoW e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result) if e != nil { if port, err := lookupPortMap(network, service); err == nil { return port, nil } return 0, &DNSError{Err: winError("getaddrinfow", e).Error(), Name: network + "/" + service} } defer syscall.FreeAddrInfoW(result) if result == nil { return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service} } addr := unsafe.Pointer(result.Addr) switch result.Family { case syscall.AF_INET: a := (*syscall.RawSockaddrInet4)(addr) return int(syscall.Ntohs(a.Port)), nil case syscall.AF_INET6: a := (*syscall.RawSockaddrInet6)(addr) return int(syscall.Ntohs(a.Port)), nil } return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service} }