LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 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 // IP sockets | 5 // IP sockets |
6 | 6 |
7 package net | 7 package net |
8 | 8 |
9 import ( | 9 import ( |
10 "os" | 10 "os" |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 if (laddr == nil || laddr.family() == syscall.AF_INET) && | 94 if (laddr == nil || laddr.family() == syscall.AF_INET) && |
95 (raddr == nil || raddr.family() == syscall.AF_INET) { | 95 (raddr == nil || raddr.family() == syscall.AF_INET) { |
96 return syscall.AF_INET | 96 return syscall.AF_INET |
97 } | 97 } |
98 return syscall.AF_INET6 | 98 return syscall.AF_INET6 |
99 } | 99 } |
100 | 100 |
101 func firstFavoriteAddr(filter func(IP) IP, addrs []string) (addr IP) { | |
102 if filter == anyaddr { | |
103 // We'll take any IP address, but since the dialing code | |
104 // does not yet try multiple addresses, prefer to use | |
105 // an IPv4 address if possible. This is especially relevant | |
106 // if localhost resolves to [ipv6-localhost, ipv4-localhost]. | |
107 // Too much code assumes localhost == ipv4-localhost. | |
108 addr = firstSupportedAddr(ipv4only, addrs) | |
109 if addr == nil { | |
110 addr = firstSupportedAddr(anyaddr, addrs) | |
111 } | |
112 } else { | |
113 addr = firstSupportedAddr(filter, addrs) | |
114 } | |
115 return | |
116 } | |
117 | |
118 func firstSupportedAddr(filter func(IP) IP, addrs []string) IP { | 101 func firstSupportedAddr(filter func(IP) IP, addrs []string) IP { |
119 for _, s := range addrs { | 102 for _, s := range addrs { |
120 if addr := filter(ParseIP(s)); addr != nil { | 103 if addr := filter(ParseIP(s)); addr != nil { |
121 return addr | 104 return addr |
122 } | 105 } |
123 } | 106 } |
124 return nil | 107 return nil |
125 } | 108 } |
126 | 109 |
127 func anyaddr(x IP) IP { | 110 func anyaddr(x IP) IP { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 } | 269 } |
287 if net != "" && net[len(net)-1] == '6' { | 270 if net != "" && net[len(net)-1] == '6' { |
288 filter = ipv6only | 271 filter = ipv6only |
289 } | 272 } |
290 // Not an IP address. Try as a DNS name. | 273 // Not an IP address. Try as a DNS name. |
291 addrs, err1 := LookupHost(host) | 274 addrs, err1 := LookupHost(host) |
292 if err1 != nil { | 275 if err1 != nil { |
293 err = err1 | 276 err = err1 |
294 goto Error | 277 goto Error |
295 } | 278 } |
296 » » » addr = firstFavoriteAddr(filter, addrs) | 279 » » » addr = firstSupportedAddr(filter, addrs) |
297 if addr == nil { | 280 if addr == nil { |
298 // should not happen | 281 // should not happen |
299 err = &AddrError{"LookupHost returned no suitabl
e address", addrs[0]} | 282 err = &AddrError{"LookupHost returned no suitabl
e address", addrs[0]} |
300 goto Error | 283 goto Error |
301 } | 284 } |
302 } | 285 } |
303 } | 286 } |
304 | 287 |
305 p, i, ok := dtoi(port, 0) | 288 p, i, ok := dtoi(port, 0) |
306 if !ok || i != len(port) { | 289 if !ok || i != len(port) { |
307 p, err = LookupPort(net, port) | 290 p, err = LookupPort(net, port) |
308 if err != nil { | 291 if err != nil { |
309 goto Error | 292 goto Error |
310 } | 293 } |
311 } | 294 } |
312 if p < 0 || p > 0xFFFF { | 295 if p < 0 || p > 0xFFFF { |
313 err = &AddrError{"invalid port", port} | 296 err = &AddrError{"invalid port", port} |
314 goto Error | 297 goto Error |
315 } | 298 } |
316 | 299 |
317 return addr, p, nil | 300 return addr, p, nil |
318 | 301 |
319 Error: | 302 Error: |
320 return nil, 0, err | 303 return nil, 0, err |
321 } | 304 } |
LEFT | RIGHT |