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:
parent
31336f9c11
commit
59cc5a197f
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user