@@ -3,67 +3,63 @@ package net
33import (
44 "fmt"
55 "net"
6+
7+ "github.com/stealthrocket/net/syscall"
68)
79
810func lookupAddr (context , network , address string ) (net.Addr , error ) {
11+ var hints syscall.AddrInfo
912 switch network {
1013 case "tcp" , "tcp4" , "tcp6" :
14+ hints .SocketType = syscall .SOCK_STREAM
15+ hints .Protocol = syscall .IPPROTO_TCP
1116 case "udp" , "udp4" , "udp6" :
17+ hints .SocketType = syscall .SOCK_DGRAM
18+ hints .Protocol = syscall .IPPROTO_UDP
1219 case "unix" , "unixgram" :
1320 return & net.UnixAddr {Name : address , Net : network }, nil
1421 default :
1522 return nil , fmt .Errorf ("not implemented: %s" , network )
1623 }
17- host , portstr , err := net .SplitHostPort (address )
18- if err != nil {
19- return nil , err
24+ switch network {
25+ case "tcp" , "udp" :
26+ hints .Family = syscall .AF_UNSPEC
27+ case "tcp4" , "udp4" :
28+ hints .Family = syscall .AF_INET
29+ case "tcp6" , "udp6" :
30+ hints .Family = syscall .AF_INET6
2031 }
21- port , err := net .LookupPort ( network , portstr )
32+ hostname , service , err := net .SplitHostPort ( address )
2233 if err != nil {
2334 return nil , err
2435 }
25- if host == "" {
26- if context == "listen" {
27- switch network {
28- case "tcp" , "tcp4" :
29- return & net.TCPAddr {IP : net .IPv4zero , Port : port }, nil
30- case "tcp6" :
31- return & net.TCPAddr {IP : net .IPv6zero , Port : port }, nil
32- }
33- }
34- return nil , fmt .Errorf ("invalid address %q for %s" , address , context )
36+ if context == "listen" && hostname == "" {
37+ hints .Flags |= syscall .AI_PASSIVE
3538 }
36- ips , err := net .LookupIP (host )
39+
40+ results := make ([]syscall.AddrInfo , 16 )
41+ n , err := syscall .Getaddrinfo (hostname , service , hints , results )
3742 if err != nil {
3843 return nil , err
3944 }
40- if network == "tcp" || network == "tcp4" {
41- for _ , ip := range ips {
42- if len (ip ) == net .IPv4len {
43- return & net.TCPAddr {IP : ip , Port : port }, nil
44- }
45+ results = results [:n ]
46+ for _ , r := range results {
47+ var ip net.IP
48+ var port int
49+ switch a := r .Address .(type ) {
50+ case * syscall.SockaddrInet4 :
51+ ip = a .Addr [:]
52+ port = a .Port
53+ case * syscall.SockaddrInet6 :
54+ ip = a .Addr [:]
55+ port = a .Port
4556 }
46- }
47- if network == "tcp" || network == "tcp6" {
48- for _ , ip := range ips {
49- if len (ip ) == net .IPv6len {
50- return & net.TCPAddr {IP : ip , Port : port }, nil
51- }
52- }
53- }
54- if network == "udp" || network == "udp4" {
55- for _ , ip := range ips {
56- if len (ip ) == net .IPv4len {
57- return & net.UDPAddr {IP : ip , Port : port }, nil
58- }
59- }
60- }
61- if network == "udp" || network == "udp6" {
62- for _ , ip := range ips {
63- if len (ip ) == net .IPv6len {
64- return & net.UDPAddr {IP : ip , Port : port }, nil
65- }
57+ switch network {
58+ case "tcp" , "tcp4" , "tcp6" :
59+ return & net.TCPAddr {IP : ip , Port : port }, nil
60+ case "udp" , "udp4" , "udp6" :
61+ return & net.UDPAddr {IP : ip , Port : port }, nil
6662 }
6763 }
68- return nil , fmt .Errorf ("cannot listen on %q" , host )
64+ return nil , fmt .Errorf ("lookup failed: %q" , address )
6965}
0 commit comments