1
0
mirror of https://github.com/golang/go synced 2024-11-23 18:10:04 -07:00

net: fix parsing literal IPv6 address with zone identifier when using cgo

Parsing literal IPv6 address with zone identifier is already supported
when not using cgo. This change enables it when using cgo too.

Fixes #12241.

Change-Id: I3ed78c9e750e75eff0dae76ba8608df39503cf85
Reviewed-on: https://go-review.googlesource.com/17215
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Mikio Hara 2015-11-27 12:06:11 +09:00
parent d41d47306a
commit 8854bdbd76
5 changed files with 37 additions and 10 deletions

View File

@ -26,8 +26,8 @@ func cgoSockaddrInet4(ip IP) *C.struct_sockaddr {
return (*C.struct_sockaddr)(unsafe.Pointer(&sa)) return (*C.struct_sockaddr)(unsafe.Pointer(&sa))
} }
func cgoSockaddrInet6(ip IP) *C.struct_sockaddr { func cgoSockaddrInet6(ip IP, zone int) *C.struct_sockaddr {
sa := syscall.RawSockaddrInet6{Family: syscall.AF_INET6} sa := syscall.RawSockaddrInet6{Family: syscall.AF_INET6, Scope_id: uint32(zone)}
copy(sa.Addr[:], ip) copy(sa.Addr[:], ip)
return (*C.struct_sockaddr)(unsafe.Pointer(&sa)) return (*C.struct_sockaddr)(unsafe.Pointer(&sa))
} }

View File

@ -26,8 +26,8 @@ func cgoSockaddrInet4(ip IP) *C.struct_sockaddr {
return (*C.struct_sockaddr)(unsafe.Pointer(&sa)) return (*C.struct_sockaddr)(unsafe.Pointer(&sa))
} }
func cgoSockaddrInet6(ip IP) *C.struct_sockaddr { func cgoSockaddrInet6(ip IP, zone int) *C.struct_sockaddr {
sa := syscall.RawSockaddrInet6{Len: syscall.SizeofSockaddrInet6, Family: syscall.AF_INET6} sa := syscall.RawSockaddrInet6{Len: syscall.SizeofSockaddrInet6, Family: syscall.AF_INET6, Scope_id: uint32(zone)}
copy(sa.Addr[:], ip) copy(sa.Addr[:], ip)
return (*C.struct_sockaddr)(unsafe.Pointer(&sa)) return (*C.struct_sockaddr)(unsafe.Pointer(&sa))
} }

View File

@ -186,11 +186,15 @@ func cgoLookupPTR(addr string) ([]string, error, bool) {
acquireThread() acquireThread()
defer releaseThread() defer releaseThread()
ip := ParseIP(addr) var zone string
ip := parseIPv4(addr)
if ip == nil {
ip, zone = parseIPv6(addr, true)
}
if ip == nil { if ip == nil {
return nil, &DNSError{Err: "invalid address", Name: addr}, true return nil, &DNSError{Err: "invalid address", Name: addr}, true
} }
sa, salen := cgoSockaddr(ip) sa, salen := cgoSockaddr(ip, zone)
if sa == nil { if sa == nil {
return nil, &DNSError{Err: "invalid address " + ip.String(), Name: addr}, true return nil, &DNSError{Err: "invalid address " + ip.String(), Name: addr}, true
} }
@ -225,12 +229,12 @@ func cgoLookupPTR(addr string) ([]string, error, bool) {
return []string{absDomainName(b)}, nil, true return []string{absDomainName(b)}, nil, true
} }
func cgoSockaddr(ip IP) (*C.struct_sockaddr, C.socklen_t) { func cgoSockaddr(ip IP, zone string) (*C.struct_sockaddr, C.socklen_t) {
if ip4 := ip.To4(); ip4 != nil { if ip4 := ip.To4(); ip4 != nil {
return cgoSockaddrInet4(ip4), C.socklen_t(syscall.SizeofSockaddrInet4) return cgoSockaddrInet4(ip4), C.socklen_t(syscall.SizeofSockaddrInet4)
} }
if ip6 := ip.To16(); ip6 != nil { if ip6 := ip.To16(); ip6 != nil {
return cgoSockaddrInet6(ip6), C.socklen_t(syscall.SizeofSockaddrInet6) return cgoSockaddrInet6(ip6, zoneToInt(zone)), C.socklen_t(syscall.SizeofSockaddrInet6)
} }
return nil, 0 return nil, 0
} }

View File

@ -209,6 +209,30 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) {
} }
} }
func TestLookupIPv6LinkLocalAddr(t *testing.T) {
if !supportsIPv6 {
t.Skip("IPv6 is required")
}
addrs, err := LookupHost("localhost")
if err != nil {
t.Fatal(err)
}
found := false
for _, addr := range addrs {
if addr == "fe80::1%lo0" {
found = true
break
}
}
if !found {
t.Skipf("not supported on %s", runtime.GOOS)
}
if _, err := LookupAddr("fe80::1%lo0"); err != nil {
t.Error(err)
}
}
var lookupIANACNAMETests = []struct { var lookupIANACNAMETests = []struct {
name, cname string name, cname string
}{ }{

View File

@ -5,8 +5,7 @@
127.1.1.1 thor 127.1.1.1 thor
# aliases # aliases
127.1.1.2 ullr ullrhost 127.1.1.2 ullr ullrhost
fe80::1%lo0 localhost
# Bogus entries that must be ignored. # Bogus entries that must be ignored.
123.123.123 loki 123.123.123 loki
321.321.321.321 321.321.321.321
# TODO(yvesj): Should we be able to parse this? From a Darwin system.
fe80::1%lo0 localhost