Commit 8854bdbd authored by Mikio Hara's avatar Mikio Hara

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: default avatarMatthew Dempsky <mdempsky@google.com>
parent d41d4730
......@@ -26,8 +26,8 @@ func cgoSockaddrInet4(ip IP) *C.struct_sockaddr {
return (*C.struct_sockaddr)(unsafe.Pointer(&sa))
}
func cgoSockaddrInet6(ip IP) *C.struct_sockaddr {
sa := syscall.RawSockaddrInet6{Family: syscall.AF_INET6}
func cgoSockaddrInet6(ip IP, zone int) *C.struct_sockaddr {
sa := syscall.RawSockaddrInet6{Family: syscall.AF_INET6, Scope_id: uint32(zone)}
copy(sa.Addr[:], ip)
return (*C.struct_sockaddr)(unsafe.Pointer(&sa))
}
......@@ -26,8 +26,8 @@ func cgoSockaddrInet4(ip IP) *C.struct_sockaddr {
return (*C.struct_sockaddr)(unsafe.Pointer(&sa))
}
func cgoSockaddrInet6(ip IP) *C.struct_sockaddr {
sa := syscall.RawSockaddrInet6{Len: syscall.SizeofSockaddrInet6, Family: syscall.AF_INET6}
func cgoSockaddrInet6(ip IP, zone int) *C.struct_sockaddr {
sa := syscall.RawSockaddrInet6{Len: syscall.SizeofSockaddrInet6, Family: syscall.AF_INET6, Scope_id: uint32(zone)}
copy(sa.Addr[:], ip)
return (*C.struct_sockaddr)(unsafe.Pointer(&sa))
}
......@@ -186,11 +186,15 @@ func cgoLookupPTR(addr string) ([]string, error, bool) {
acquireThread()
defer releaseThread()
ip := ParseIP(addr)
var zone string
ip := parseIPv4(addr)
if ip == nil {
ip, zone = parseIPv6(addr, true)
}
if ip == nil {
return nil, &DNSError{Err: "invalid address", Name: addr}, true
}
sa, salen := cgoSockaddr(ip)
sa, salen := cgoSockaddr(ip, zone)
if sa == nil {
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
}
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 {
return cgoSockaddrInet4(ip4), C.socklen_t(syscall.SizeofSockaddrInet4)
}
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
}
......
......@@ -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 {
name, cname string
}{
......
......@@ -5,8 +5,7 @@
127.1.1.1 thor
# aliases
127.1.1.2 ullr ullrhost
fe80::1%lo0 localhost
# Bogus entries that must be ignored.
123.123.123 loki
321.321.321.321
# TODO(yvesj): Should we be able to parse this? From a Darwin system.
fe80::1%lo0 localhost
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment