]> Cypherpunks repositories - gostls13.git/commitdiff
net: fix parsing literal IPv6 address with zone identifier when using cgo
authorMikio Hara <mikioh.mikioh@gmail.com>
Fri, 27 Nov 2015 03:06:11 +0000 (12:06 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Fri, 4 Dec 2015 02:50:00 +0000 (02:50 +0000)
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>
src/net/cgo_socknew.go
src/net/cgo_sockold.go
src/net/cgo_unix.go
src/net/lookup_test.go
src/net/testdata/hosts

index b5082840fba8d358fabc7a4c4ac0daa790338b8d..3b13926107ac7c141b09cd3af12367be5582f346 100644 (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))
 }
index 522e8e588017763cdcc4a03d364882fa663e1552..e629a09f9cd5f8d7dd2b091310ba4ab3a6a695b8 100644 (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))
 }
index d53c00308e7834bd6e47c57f8611429b211c4be2..c14f08547a4f51c933c21c6e9231f0d71b2090f2 100644 (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
 }
index 630c8a417faa9defb13fcdff37382dcbea610525..4a8e631027e65046d97b6199e66cdbe0c3f0d131 100644 (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
 }{
index b601763898b7e27ded621cc207effa4a403cecc0..3ed83ff8a83ea2e2eebbf7f03bdd0a49b4aed374 100644 (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