Skip to content

Commit

Permalink
syscall: fix parsing ipv6 address prefix on dragonfly
Browse files Browse the repository at this point in the history
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 golang#10041.

Change-Id: I2480ba273929e859896697382d1a75b01a116b98
Reviewed-on: https://go-review.googlesource.com/6391
Reviewed-by: Brad Fitzpatrick <[email protected]>
  • Loading branch information
cixtor committed Mar 3, 2015
1 parent 31336f9 commit 59cc5a1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
6 changes: 0 additions & 6 deletions src/net/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
14 changes: 12 additions & 2 deletions src/syscall/route_bsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,25 @@ 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])
} else {
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 {
Expand Down
30 changes: 29 additions & 1 deletion src/syscall/route_bsd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 59cc5a1

Please sign in to comment.