1
0
mirror of https://github.com/golang/go synced 2024-11-15 03:40:29 -07:00
go/src/net/lookup_unix.go
Andrew Pilloud f00362b9ec net: LookupHost and Resolve{TCP,UDP,IP}Addr should use zone from getaddrinfo
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>
2015-03-08 09:58:11 +00:00

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
}