Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2118)

Delta Between Two Patch Sets: src/pkg/net/cgo_unix.go

Issue 4437053: code review 4437053: net: use C library resolver on FreeBSD, Linux, OS X / a... (Closed)
Left Patch Set: diff -r c1b858bc04cd https://go.googlecode.com/hg Created 13 years, 11 months ago
Right Patch Set: diff -r 85760a02b1dd https://go.googlecode.com/hg Created 13 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/net/cgo_stub.go ('k') | src/pkg/net/dial.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package net 5 package net
6 6
7 /* 7 /*
8 #include <sys/types.h> 8 #include <sys/types.h>
9 #include <sys/socket.h> 9 #include <sys/socket.h>
10 #include <netinet/in.h> 10 #include <netinet/in.h>
(...skipping 14 matching lines...) Expand all
25 ip, err, completed := cgoLookupIP(name) 25 ip, err, completed := cgoLookupIP(name)
26 for _, p := range ip { 26 for _, p := range ip {
27 addrs = append(addrs, p.String()) 27 addrs = append(addrs, p.String())
28 } 28 }
29 return 29 return
30 } 30 }
31 31
32 func cgoLookupPort(net, service string) (port int, err os.Error, completed bool) { 32 func cgoLookupPort(net, service string) (port int, err os.Error, completed bool) {
33 var res *C.struct_addrinfo 33 var res *C.struct_addrinfo
34 var hints C.struct_addrinfo 34 var hints C.struct_addrinfo
35 » 35
36 switch net { 36 switch net {
37 case "": 37 case "":
38 // no hints 38 // no hints
39 case "tcp", "tcp4", "tcp6": 39 case "tcp", "tcp4", "tcp6":
40 hints.ai_socktype = C.SOCK_STREAM 40 hints.ai_socktype = C.SOCK_STREAM
41 hints.ai_protocol = C.IPPROTO_TCP 41 hints.ai_protocol = C.IPPROTO_TCP
42 case "udp", "udp4", "udp6": 42 case "udp", "udp4", "udp6":
43 hints.ai_socktype = C.SOCK_DGRAM 43 hints.ai_socktype = C.SOCK_DGRAM
44 hints.ai_protocol = C.IPPROTO_UDP 44 hints.ai_protocol = C.IPPROTO_UDP
45 default: 45 default:
46 return 0, UnknownNetworkError(net), true 46 return 0, UnknownNetworkError(net), true
47 } 47 }
48 if len(net) >= 4 { 48 if len(net) >= 4 {
49 switch net[3] { 49 switch net[3] {
50 case '4': 50 case '4':
51 hints.ai_family = C.AF_INET 51 hints.ai_family = C.AF_INET
52 case '6': 52 case '6':
53 hints.ai_family = C.AF_INET6 53 hints.ai_family = C.AF_INET6
54 } 54 }
55 } 55 }
56 » 56
57 s := C.CString(service) 57 s := C.CString(service)
58 defer C.free(unsafe.Pointer(s)) 58 defer C.free(unsafe.Pointer(s))
59 if C.getaddrinfo(nil, s, &hints, &res) == 0 { 59 if C.getaddrinfo(nil, s, &hints, &res) == 0 {
60 defer C.freeaddrinfo(res) 60 defer C.freeaddrinfo(res)
61 for r := res; r != nil; r = r.ai_next { 61 for r := res; r != nil; r = r.ai_next {
62 switch r.ai_family { 62 switch r.ai_family {
63 default: 63 default:
64 continue 64 continue
65 case C.AF_INET: 65 case C.AF_INET:
66 sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer (r.ai_addr)) 66 sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer (r.ai_addr))
67 p := (*[2]byte)(unsafe.Pointer(&sa.Port)) 67 p := (*[2]byte)(unsafe.Pointer(&sa.Port))
68 return int(p[0])<<8 | int(p[1]), nil, true 68 return int(p[0])<<8 | int(p[1]), nil, true
69 case C.AF_INET6: 69 case C.AF_INET6:
70 sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer (r.ai_addr)) 70 sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer (r.ai_addr))
71 p := (*[2]byte)(unsafe.Pointer(&sa.Port)) 71 p := (*[2]byte)(unsafe.Pointer(&sa.Port))
72 return int(p[0])<<8 | int(p[1]), nil, true 72 return int(p[0])<<8 | int(p[1]), nil, true
73 } 73 }
74 } 74 }
75 } 75 }
76 return 0, &AddrError{"unknown port", net + "/" + service}, true 76 return 0, &AddrError{"unknown port", net + "/" + service}, true
77 } 77 }
78 78
79 func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err os.Error, comp leted bool) { 79 func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err os.Error, comp leted bool) {
80 var res *C.struct_addrinfo 80 var res *C.struct_addrinfo
81 var hints C.struct_addrinfo 81 var hints C.struct_addrinfo
82 82
83 » hints.ai_flags = C.AI_CANONNAME | C.AI_ALL | C.AI_V4MAPPED | C.AI_ADDRCO NFIG 83 » // NOTE(rsc): In theory there are approximately balanced
84 » // arguments for and against including AI_ADDRCONFIG
85 » // in the flags (it includes IPv4 results only on IPv4 systems,
86 » // and similarly for IPv6), but in practice setting it causes
87 » // getaddrinfo to return the wrong canonical name on Linux.
88 » // So definitely leave it out.
89 » hints.ai_flags = C.AI_ALL | C.AI_V4MAPPED | C.AI_CANONNAME
84 90
85 h := C.CString(name) 91 h := C.CString(name)
86 defer C.free(unsafe.Pointer(h)) 92 defer C.free(unsafe.Pointer(h))
87 » gerrno := C.getaddrinfo(h, nil, &hints, &res) 93 » gerrno, err := C.getaddrinfo(h, nil, &hints, &res)
88 if gerrno != 0 { 94 if gerrno != 0 {
89 var str string 95 var str string
90 if gerrno == C.EAI_NONAME { 96 if gerrno == C.EAI_NONAME {
91 str = noSuchHost 97 str = noSuchHost
98 } else if gerrno == C.EAI_SYSTEM {
99 str = err.String()
92 } else { 100 } else {
93 str = C.GoString(C.gai_strerror(gerrno)) 101 str = C.GoString(C.gai_strerror(gerrno))
94 } 102 }
95 return nil, "", &DNSError{Error: str, Name: name}, true 103 return nil, "", &DNSError{Error: str, Name: name}, true
96 } 104 }
97 defer C.freeaddrinfo(res) 105 defer C.freeaddrinfo(res)
98 if res != nil { 106 if res != nil {
99 cname = C.GoString(res.ai_canonname) 107 cname = C.GoString(res.ai_canonname)
100 if cname == "" { 108 if cname == "" {
101 cname = name 109 cname = name
102 } 110 }
103 if len(cname) > 0 && cname[len(cname)-1] != '.' { 111 if len(cname) > 0 && cname[len(cname)-1] != '.' {
104 cname += "." 112 cname += "."
105 } 113 }
106 } 114 }
107 for r := res; r != nil; r = r.ai_next { 115 for r := res; r != nil; r = r.ai_next {
116 // Everything comes back twice, once for UDP and once for TCP.
117 if r.ai_socktype != C.SOCK_STREAM {
118 continue
119 }
108 switch r.ai_family { 120 switch r.ai_family {
109 default: 121 default:
110 continue 122 continue
111 case C.AF_INET: 123 case C.AF_INET:
112 sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_ad dr)) 124 sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_ad dr))
113 addrs = append(addrs, copyIP(sa.Addr[:])) 125 addrs = append(addrs, copyIP(sa.Addr[:]))
114 case C.AF_INET6: 126 case C.AF_INET6:
115 sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_ad dr)) 127 sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_ad dr))
116 addrs = append(addrs, copyIP(sa.Addr[:])) 128 addrs = append(addrs, copyIP(sa.Addr[:]))
117 } 129 }
118 } 130 }
119 return addrs, cname, nil, true 131 return addrs, cname, nil, true
120 } 132 }
121 133
122 func cgoLookupIP(name string) (addrs []IP, err os.Error, completed bool) { 134 func cgoLookupIP(name string) (addrs []IP, err os.Error, completed bool) {
123 addrs, _, err, completed = cgoLookupIPCNAME(name) 135 addrs, _, err, completed = cgoLookupIPCNAME(name)
124 return 136 return
125 } 137 }
126 138
127 func cgoLookupCNAME(name string) (cname string, err os.Error, completed bool) { 139 func cgoLookupCNAME(name string) (cname string, err os.Error, completed bool) {
128 _, cname, err, completed = cgoLookupIPCNAME(name) 140 _, cname, err, completed = cgoLookupIPCNAME(name)
129 return 141 return
130 } 142 }
131 143
132 func copyIP(x IP) IP { 144 func copyIP(x IP) IP {
133 y := make(IP, len(x)) 145 y := make(IP, len(x))
134 copy(y, x) 146 copy(y, x)
135 return y 147 return y
136 } 148 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b