mirror of
https://github.com/golang/go
synced 2024-11-15 03:40:29 -07:00
f00362b9ec
The unix and windows getaddrinfo calls return a zone with IPv6 addresses. IPv6 link-local addresses returned are only valid on the given zone. When the zone is dropped, connections to the address will fail. This patch replaces IP with IPAddr in several internal resolver functions, and plumbs through the zone. Change-Id: Ifea891654f586f15b76988464f82e04a42ccff6d Reviewed-on: https://go-review.googlesource.com/5851 Reviewed-by: Mikio Hara <mikioh.mikioh@gmail.com>
169 lines
3.6 KiB
Go
169 lines
3.6 KiB
Go
// Copyright 2011 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
|
|
package net
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
)
|
|
|
|
var onceReadProtocols sync.Once
|
|
|
|
// readProtocols loads contents of /etc/protocols into protocols map
|
|
// for quick access.
|
|
func readProtocols() {
|
|
if file, err := open("/etc/protocols"); err == nil {
|
|
for line, ok := file.readLine(); ok; line, ok = file.readLine() {
|
|
// tcp 6 TCP # transmission control protocol
|
|
if i := byteIndex(line, '#'); i >= 0 {
|
|
line = line[0:i]
|
|
}
|
|
f := getFields(line)
|
|
if len(f) < 2 {
|
|
continue
|
|
}
|
|
if proto, _, ok := dtoi(f[1], 0); ok {
|
|
if _, ok := protocols[f[0]]; !ok {
|
|
protocols[f[0]] = proto
|
|
}
|
|
for _, alias := range f[2:] {
|
|
if _, ok := protocols[alias]; !ok {
|
|
protocols[alias] = proto
|
|
}
|
|
}
|
|
}
|
|
}
|
|
file.close()
|
|
}
|
|
}
|
|
|
|
// lookupProtocol looks up IP protocol name in /etc/protocols and
|
|
// returns correspondent protocol number.
|
|
func lookupProtocol(name string) (proto int, err error) {
|
|
onceReadProtocols.Do(readProtocols)
|
|
proto, found := protocols[name]
|
|
if !found {
|
|
return 0, errors.New("unknown IP protocol specified: " + name)
|
|
}
|
|
return
|
|
}
|
|
|
|
func lookupHost(host string) (addrs []string, err error) {
|
|
addrs, err, ok := cgoLookupHost(host)
|
|
if !ok {
|
|
addrs, err = goLookupHost(host)
|
|
}
|
|
return
|
|
}
|
|
|
|
func lookupIP(host string) (addrs []IPAddr, err error) {
|
|
addrs, err, ok := cgoLookupIP(host)
|
|
if !ok {
|
|
addrs, err = goLookupIP(host)
|
|
}
|
|
return
|
|
}
|
|
|
|
func lookupPort(network, service string) (port int, err error) {
|
|
port, err, ok := cgoLookupPort(network, service)
|
|
if !ok {
|
|
port, err = goLookupPort(network, service)
|
|
}
|
|
return
|
|
}
|
|
|
|
func lookupCNAME(name string) (cname string, err error) {
|
|
cname, err, ok := cgoLookupCNAME(name)
|
|
if !ok {
|
|
cname, err = goLookupCNAME(name)
|
|
}
|
|
return
|
|
}
|
|
|
|
func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
|
|
var target string
|
|
if service == "" && proto == "" {
|
|
target = name
|
|
} else {
|
|
target = "_" + service + "._" + proto + "." + name
|
|
}
|
|
var records []dnsRR
|
|
cname, records, err = lookup(target, dnsTypeSRV)
|
|
if err != nil {
|
|
return
|
|
}
|
|
addrs = make([]*SRV, len(records))
|
|
for i, rr := range records {
|
|
r := rr.(*dnsRR_SRV)
|
|
addrs[i] = &SRV{r.Target, r.Port, r.Priority, r.Weight}
|
|
}
|
|
byPriorityWeight(addrs).sort()
|
|
return
|
|
}
|
|
|
|
func lookupMX(name string) (mx []*MX, err error) {
|
|
_, records, err := lookup(name, dnsTypeMX)
|
|
if err != nil {
|
|
return
|
|
}
|
|
mx = make([]*MX, len(records))
|
|
for i, rr := range records {
|
|
r := rr.(*dnsRR_MX)
|
|
mx[i] = &MX{r.Mx, r.Pref}
|
|
}
|
|
byPref(mx).sort()
|
|
return
|
|
}
|
|
|
|
func lookupNS(name string) (ns []*NS, err error) {
|
|
_, records, err := lookup(name, dnsTypeNS)
|
|
if err != nil {
|
|
return
|
|
}
|
|
ns = make([]*NS, len(records))
|
|
for i, r := range records {
|
|
r := r.(*dnsRR_NS)
|
|
ns[i] = &NS{r.Ns}
|
|
}
|
|
return
|
|
}
|
|
|
|
func lookupTXT(name string) (txt []string, err error) {
|
|
_, records, err := lookup(name, dnsTypeTXT)
|
|
if err != nil {
|
|
return
|
|
}
|
|
txt = make([]string, len(records))
|
|
for i, r := range records {
|
|
txt[i] = r.(*dnsRR_TXT).Txt
|
|
}
|
|
return
|
|
}
|
|
|
|
func lookupAddr(addr string) (name []string, err error) {
|
|
name = lookupStaticAddr(addr)
|
|
if len(name) > 0 {
|
|
return
|
|
}
|
|
var arpa string
|
|
arpa, err = reverseaddr(addr)
|
|
if err != nil {
|
|
return
|
|
}
|
|
var records []dnsRR
|
|
_, records, err = lookup(arpa, dnsTypePTR)
|
|
if err != nil {
|
|
return
|
|
}
|
|
name = make([]string, len(records))
|
|
for i := range records {
|
|
r := records[i].(*dnsRR_PTR)
|
|
name[i] = r.Ptr
|
|
}
|
|
return
|
|
}
|