1
0
mirror of https://github.com/golang/go synced 2024-11-23 16:30:06 -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))
}
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))
}

View File

@ -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))
}

View File

@ -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
}

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 {
name, cname string
}{

View File

@ -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