1
0
mirror of https://github.com/golang/go synced 2024-11-19 04:44:41 -07:00

syscall: fix parsing ipv6 address prefix on dragonfly

This change fixes a missing case that a routing address contains an
invalid address family label but it holds a valid length of address
structure.

Also makes test robust.

Fixes #10041.

Change-Id: I2480ba273929e859896697382d1a75b01a116b98
Reviewed-on: https://go-review.googlesource.com/6391
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Mikio Hara 2015-03-01 23:58:28 +09:00
parent 31336f9c11
commit 59cc5a197f
3 changed files with 41 additions and 9 deletions

View File

@ -48,9 +48,6 @@ func ipv6LinkLocalUnicastAddr(ifi *Interface) string {
}
func TestInterfaces(t *testing.T) {
if runtime.GOOS == "dragonfly" {
t.Skip("fail on dragonfly - issue 10041")
}
ift, err := Interfaces()
if err != nil {
t.Fatal(err)
@ -108,9 +105,6 @@ func TestInterfaces(t *testing.T) {
}
func TestInterfaceAddrs(t *testing.T) {
if runtime.GOOS == "dragonfly" {
t.Skip("fail on dragonfly - issue 10041")
}
ift, err := Interfaces()
if err != nil {
t.Fatal(err)

View File

@ -140,8 +140,14 @@ func parseNetworkLayerAddr(b []byte, family byte) (Sockaddr, error) {
if len(b) < l {
return nil, EINVAL
}
switch family {
case AF_INET6:
// Don't reorder case expressions.
// The case expressions for IPv6 must come first.
switch {
case b[0] == SizeofSockaddrInet6:
sa := &SockaddrInet6{}
copy(sa.Addr[:], b[offsetofInet6:])
return sa, nil
case family == AF_INET6:
sa := &SockaddrInet6{}
if l-1 < offsetofInet6 {
copy(sa.Addr[:], b[1:l])
@ -149,6 +155,10 @@ func parseNetworkLayerAddr(b []byte, family byte) (Sockaddr, error) {
copy(sa.Addr[:], b[l-offsetofInet6:l])
}
return sa, nil
case b[0] == SizeofSockaddrInet4:
sa := &SockaddrInet4{}
copy(sa.Addr[:], b[offsetofInet4:])
return sa, nil
default: // an old fashion, AF_UNSPEC or unknown means AF_INET
sa := &SockaddrInet4{}
if l-1 < offsetofInet4 {

View File

@ -18,7 +18,18 @@ import (
func TestRouteRIB(t *testing.T) {
for _, facility := range []int{syscall.NET_RT_DUMP, syscall.NET_RT_IFLIST} {
for _, param := range []int{syscall.AF_UNSPEC, syscall.AF_INET, syscall.AF_INET6} {
b, err := syscall.RouteRIB(facility, param)
var err error
var b []byte
// The VM allocator wrapper functions can
// return ENOMEM easily.
for i := 0; i < 3; i++ {
b, err = syscall.RouteRIB(facility, param)
if err != nil {
time.Sleep(5 * time.Millisecond)
continue
}
break
}
if err != nil {
t.Error(facility, param, err)
continue
@ -185,10 +196,27 @@ func (sas sockaddrs) String() string {
func (sas sockaddrs) match(flags addrFlags) error {
var f addrFlags
family := syscall.AF_UNSPEC
for i := range sas {
if sas[i] != nil {
f |= 1 << uint(i)
}
switch sas[i].(type) {
case *syscall.SockaddrInet4:
if family == syscall.AF_UNSPEC {
family = syscall.AF_INET
}
if family != syscall.AF_INET {
return fmt.Errorf("got %v; want %v", sockaddrs(sas), family)
}
case *syscall.SockaddrInet6:
if family == syscall.AF_UNSPEC {
family = syscall.AF_INET6
}
if family != syscall.AF_INET6 {
return fmt.Errorf("got %v; want %v", sockaddrs(sas), family)
}
}
}
if f != flags {
return fmt.Errorf("got %v; want %v", f, flags)