Update dependencies
This commit is contained in:
1
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control.go
generated
vendored
1
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control.go
generated
vendored
@@ -12,7 +12,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
errNotSupported = errors.New("not supported")
|
||||
errMissingAddress = errors.New("missing address")
|
||||
errInvalidConnType = errors.New("invalid conn type")
|
||||
errNoSuchInterface = errors.New("no such interface")
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
@@ -47,23 +49,23 @@ func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
l += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
if opt.isset(FlagHopLimit) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_2292HOPLIMIT
|
||||
m.Type = sysSockopt2292HopLimit
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_2292PKTINFO
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
|
||||
off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
m.Type = sysSockopt2292PacketInfo
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
|
||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -83,12 +85,12 @@ func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
continue
|
||||
}
|
||||
switch m.Header.Type {
|
||||
case syscall.IPV6_2292HOPLIMIT:
|
||||
case sysSockopt2292HopLimit:
|
||||
cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case syscall.IPV6_2292PKTINFO:
|
||||
pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.IfIndex = int(pi.Ifindex)
|
||||
cm.Dst = pi.Addr[:]
|
||||
case sysSockopt2292PacketInfo:
|
||||
pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.IfIndex = int(pi.IfIndex)
|
||||
cm.Dst = pi.IP[:]
|
||||
}
|
||||
}
|
||||
return cm, nil
|
||||
@@ -105,7 +107,7 @@ func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
pion := false
|
||||
if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
|
||||
pion = true
|
||||
l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
l += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
@@ -115,7 +117,7 @@ func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
if cm.HopLimit > 0 {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_2292HOPLIMIT
|
||||
m.Type = sysSockopt2292HopLimit
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
data := oob[off+syscall.CmsgLen(0):]
|
||||
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
|
||||
@@ -124,26 +126,24 @@ func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
if pion {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_2292PKTINFO
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
|
||||
pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
m.Type = sysSockopt2292PacketInfo
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
|
||||
pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
|
||||
copy(pi.Addr[:], ip)
|
||||
copy(pi.IP[:], ip)
|
||||
}
|
||||
if cm.IfIndex != 0 {
|
||||
pi.Ifindex = uint32(cm.IfIndex)
|
||||
pi.IfIndex = uint32(cm.IfIndex)
|
||||
}
|
||||
off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_2292NEXTHOP
|
||||
m.Type = sysSockopt2292NextHop
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
|
||||
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
sa.Len = syscall.SizeofSockaddrInet6
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], cm.NextHop)
|
||||
setSockaddr(sa, cm.NextHop, cm.IfIndex)
|
||||
off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
}
|
||||
}
|
||||
217
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_linux.go
generated
vendored
217
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_linux.go
generated
vendored
@@ -1,217 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// See /usr/include/linux/in6.h.
|
||||
syscall_IPV6_RECVPATHMTU = syscall.IPV6_DSTOPTS + 1 + iota
|
||||
syscall_IPV6_PATHMTU
|
||||
syscall_IPV6_DONTFRAG
|
||||
)
|
||||
|
||||
const pktinfo = FlagDst | FlagInterface
|
||||
|
||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
if cf&FlagTrafficClass != 0 {
|
||||
if err := setIPv6ReceiveTrafficClass(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagTrafficClass)
|
||||
} else {
|
||||
opt.clear(FlagTrafficClass)
|
||||
}
|
||||
}
|
||||
if cf&FlagHopLimit != 0 {
|
||||
if err := setIPv6ReceiveHopLimit(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagHopLimit)
|
||||
} else {
|
||||
opt.clear(FlagHopLimit)
|
||||
}
|
||||
}
|
||||
if cf&pktinfo != 0 {
|
||||
if err := setIPv6ReceivePacketInfo(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(cf & pktinfo)
|
||||
} else {
|
||||
opt.clear(cf & pktinfo)
|
||||
}
|
||||
}
|
||||
if cf&FlagPathMTU != 0 {
|
||||
if err := setIPv6ReceivePathMTU(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagPathMTU)
|
||||
} else {
|
||||
opt.clear(FlagPathMTU)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
l, off := 0, 0
|
||||
if opt.isset(FlagTrafficClass) {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(FlagHopLimit) {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
}
|
||||
if opt.isset(FlagPathMTU) {
|
||||
l += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
if opt.isset(FlagTrafficClass) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_RECVTCLASS
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(FlagHopLimit) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_RECVHOPLIMIT
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_RECVPKTINFO
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
|
||||
off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
}
|
||||
if opt.isset(FlagPathMTU) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall_IPV6_RECVPATHMTU
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofIPv6MTUInfo))
|
||||
off += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
cmsgs, err := syscall.ParseSocketControlMessage(b)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("parse socket control message", err)
|
||||
}
|
||||
cm := &ControlMessage{}
|
||||
for _, m := range cmsgs {
|
||||
if m.Header.Level != ianaProtocolIPv6 {
|
||||
continue
|
||||
}
|
||||
switch m.Header.Type {
|
||||
case syscall.IPV6_TCLASS:
|
||||
cm.TrafficClass = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case syscall.IPV6_HOPLIMIT:
|
||||
cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case syscall.IPV6_PKTINFO:
|
||||
pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.Dst = pi.Addr[:]
|
||||
cm.IfIndex = int(pi.Ifindex)
|
||||
case syscall_IPV6_PATHMTU:
|
||||
mi := (*syscall.IPv6MTUInfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.Dst = mi.Addr.Addr[:]
|
||||
cm.IfIndex = int(mi.Addr.Scope_id)
|
||||
cm.MTU = int(mi.Mtu)
|
||||
}
|
||||
}
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
if cm == nil {
|
||||
return
|
||||
}
|
||||
l, off := 0, 0
|
||||
if cm.TrafficClass > 0 {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
if cm.HopLimit > 0 {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
pion := false
|
||||
if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
|
||||
pion = true
|
||||
l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
if cm.TrafficClass > 0 {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_TCLASS
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
data := oob[off+syscall.CmsgLen(0):]
|
||||
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.TrafficClass)
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if cm.HopLimit > 0 {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_HOPLIMIT
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
data := oob[off+syscall.CmsgLen(0):]
|
||||
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if pion {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_PKTINFO
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
|
||||
pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
|
||||
copy(pi.Addr[:], ip)
|
||||
}
|
||||
if cm.IfIndex != 0 {
|
||||
pi.Ifindex = uint32(cm.IfIndex)
|
||||
}
|
||||
off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_NEXTHOP
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
|
||||
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], cm.NextHop)
|
||||
sa.Scope_id = uint32(cm.IfIndex)
|
||||
off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -2,13 +2,13 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
import "syscall"
|
||||
package ipv6
|
||||
|
||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
@@ -18,7 +18,7 @@ func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
|
||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil, syscall.EPLAN9
|
||||
return nil, errOpNoSupport
|
||||
}
|
||||
|
||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build freebsd netbsd openbsd
|
||||
// +build freebsd linux netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
@@ -72,40 +72,40 @@ func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
l += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if opt.isset(FlagPathMTU) {
|
||||
l += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
|
||||
l += syscall.CmsgSpace(sysSizeofMTUInfo)
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
if opt.isset(FlagTrafficClass) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_RECVTCLASS
|
||||
m.Type = sysSockoptReceiveTrafficClass
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(FlagHopLimit) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_RECVHOPLIMIT
|
||||
m.Type = sysSockoptReceiveHopLimit
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_RECVPKTINFO
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
|
||||
off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
m.Type = sysSockoptReceivePacketInfo
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
|
||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if opt.isset(FlagPathMTU) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_RECVPATHMTU
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofIPv6MTUInfo))
|
||||
off += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
|
||||
m.Type = sysSockoptReceivePathMTU
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofMTUInfo))
|
||||
off += syscall.CmsgSpace(sysSizeofMTUInfo)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -125,19 +125,19 @@ func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
continue
|
||||
}
|
||||
switch m.Header.Type {
|
||||
case syscall.IPV6_TCLASS:
|
||||
case sysSockoptTrafficClass:
|
||||
cm.TrafficClass = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case syscall.IPV6_HOPLIMIT:
|
||||
case sysSockoptHopLimit:
|
||||
cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case syscall.IPV6_PKTINFO:
|
||||
pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.Dst = pi.Addr[:]
|
||||
cm.IfIndex = int(pi.Ifindex)
|
||||
case syscall.IPV6_PATHMTU:
|
||||
mi := (*syscall.IPv6MTUInfo)(unsafe.Pointer(&m.Data[0]))
|
||||
case sysSockoptPacketInfo:
|
||||
pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.Dst = pi.IP[:]
|
||||
cm.IfIndex = int(pi.IfIndex)
|
||||
case sysSockoptPathMTU:
|
||||
mi := (*sysMTUInfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.Dst = mi.Addr.Addr[:]
|
||||
cm.IfIndex = int(mi.Addr.Scope_id)
|
||||
cm.MTU = int(mi.Mtu)
|
||||
cm.MTU = int(mi.MTU)
|
||||
}
|
||||
}
|
||||
return cm, nil
|
||||
@@ -157,7 +157,7 @@ func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
pion := false
|
||||
if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
|
||||
pion = true
|
||||
l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
l += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
@@ -167,7 +167,7 @@ func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
if cm.TrafficClass > 0 {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_TCLASS
|
||||
m.Type = sysSockoptTrafficClass
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
data := oob[off+syscall.CmsgLen(0):]
|
||||
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.TrafficClass)
|
||||
@@ -176,7 +176,7 @@ func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
if cm.HopLimit > 0 {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_HOPLIMIT
|
||||
m.Type = sysSockoptHopLimit
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
data := oob[off+syscall.CmsgLen(0):]
|
||||
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
|
||||
@@ -185,27 +185,24 @@ func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
if pion {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_PKTINFO
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
|
||||
pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
m.Type = sysSockoptPacketInfo
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
|
||||
pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
|
||||
copy(pi.Addr[:], ip)
|
||||
copy(pi.IP[:], ip)
|
||||
}
|
||||
if cm.IfIndex != 0 {
|
||||
pi.Ifindex = uint32(cm.IfIndex)
|
||||
pi.IfIndex = uint32(cm.IfIndex)
|
||||
}
|
||||
off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
|
||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = syscall.IPV6_NEXTHOP
|
||||
m.Type = sysSockoptNextHop
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
|
||||
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
sa.Len = syscall.SizeofSockaddrInet6
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], cm.NextHop)
|
||||
sa.Scope_id = uint32(cm.IfIndex)
|
||||
setSockaddr(sa, cm.NextHop, cm.IfIndex)
|
||||
off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
}
|
||||
}
|
||||
42
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_test.go
generated
vendored
42
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_test.go
generated
vendored
@@ -1,42 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestControlFlags(t *testing.T) {
|
||||
tf := FlagInterface | FlagPathMTU
|
||||
opt := rawOpt{cflags: tf | FlagHopLimit}
|
||||
|
||||
// This loop runs methods of raw.Opt concurrently for testing
|
||||
// concurrent access to the rawOpt. The first entry shold be
|
||||
// opt.set and the last entry should be opt.clear.
|
||||
tfns := []func(ControlFlags){opt.set, opt.clear, opt.clear}
|
||||
ch := make(chan bool)
|
||||
var wg sync.WaitGroup
|
||||
for i, fn := range tfns {
|
||||
wg.Add(1)
|
||||
go func(i int, fn func(ControlFlags)) {
|
||||
defer wg.Done()
|
||||
switch i {
|
||||
case 0:
|
||||
close(ch)
|
||||
case len(tfns) - 1:
|
||||
<-ch
|
||||
}
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
fn(tf)
|
||||
}(i, fn)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
if opt.isset(tf) {
|
||||
t.Fatalf("got %#x; expected %#x", opt.cflags, FlagHopLimit)
|
||||
}
|
||||
}
|
||||
@@ -2,53 +2,52 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
import "net"
|
||||
|
||||
// MulticastHopLimit returns the hop limit field value for outgoing
|
||||
// multicast packets.
|
||||
func (c *dgramOpt) MulticastHopLimit() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, syscall.EPLAN9
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetMulticastHopLimit sets the hop limit field value for future
|
||||
// outgoing multicast packets.
|
||||
func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// MulticastInterface returns the default interface for multicast
|
||||
// packet transmissions.
|
||||
func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil, syscall.EPLAN9
|
||||
return nil, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetMulticastInterface sets the default interface for future
|
||||
// multicast packet transmissions.
|
||||
func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// MulticastLoopback reports whether transmitted multicast packets
|
||||
// should be copied and send back to the originator.
|
||||
func (c *dgramOpt) MulticastLoopback() (bool, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return false, syscall.EPLAN9
|
||||
return false, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetMulticastLoopback sets whether transmitted multicast packets
|
||||
// should be copied and send back to the originator.
|
||||
func (c *dgramOpt) SetMulticastLoopback(on bool) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// JoinGroup joins the group address group on the interface ifi.
|
||||
@@ -57,13 +56,13 @@ func (c *dgramOpt) SetMulticastLoopback(on bool) error {
|
||||
// platforms and sometimes it might require routing configuration.
|
||||
func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// LeaveGroup leaves the group address group on the interface ifi.
|
||||
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// Checksum reports whether the kernel will compute, store or verify a
|
||||
@@ -72,7 +71,7 @@ func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
|
||||
// field is located.
|
||||
func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
|
||||
// TODO(mikio): Implement this
|
||||
return false, 0, syscall.EPLAN9
|
||||
return false, 0, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetChecksum enables the kernel checksum processing. If on is ture,
|
||||
@@ -80,17 +79,17 @@ func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
|
||||
// checksum field is located.
|
||||
func (c *dgramOpt) SetChecksum(on bool, offset int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// ICMPFilter returns an ICMP filter.
|
||||
func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil, syscall.EPLAN9
|
||||
return nil, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetICMPFilter deploys the ICMP filter.
|
||||
func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
@@ -2,33 +2,33 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
import "syscall"
|
||||
package ipv6
|
||||
|
||||
// TrafficClass returns the traffic class field value for outgoing
|
||||
// packets.
|
||||
func (c *genericOpt) TrafficClass() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, syscall.EPLAN9
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetTrafficClass sets the traffic class field value for future
|
||||
// outgoing packets.
|
||||
func (c *genericOpt) SetTrafficClass(tclass int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// HopLimit returns the hop limit field value for outgoing packets.
|
||||
func (c *genericOpt) HopLimit() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, syscall.EPLAN9
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetHopLimit sets the hop limit field value for future outgoing
|
||||
// packets.
|
||||
func (c *genericOpt) SetHopLimit(hoplim int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EPLAN9
|
||||
return errOpNoSupport
|
||||
}
|
||||
7
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper.go
generated
vendored
7
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper.go
generated
vendored
@@ -4,7 +4,12 @@
|
||||
|
||||
package ipv6
|
||||
|
||||
import "net"
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
var errOpNoSupport = errors.New("operation not supported")
|
||||
|
||||
func boolint(b bool) int {
|
||||
if b {
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
import "syscall"
|
||||
package ipv6
|
||||
|
||||
func (c *genericOpt) sysfd() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, syscall.EPLAN9
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
func (c *dgramOpt) sysfd() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, syscall.EPLAN9
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
func (c *payloadHandler) sysfd() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, syscall.EPLAN9
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
11
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp.go
generated
vendored
11
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp.go
generated
vendored
@@ -21,26 +21,27 @@ func (typ ICMPType) String() string {
|
||||
// packets.
|
||||
type ICMPFilter struct {
|
||||
mu sync.RWMutex
|
||||
rawICMPFilter
|
||||
sysICMPFilter
|
||||
}
|
||||
|
||||
// Set sets the ICMP type and filter action to the filter.
|
||||
func (f *ICMPFilter) Set(typ ICMPType, block bool) {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
f.set(typ, block)
|
||||
f.mu.Unlock()
|
||||
}
|
||||
|
||||
// SetAll sets the filter action to the filter.
|
||||
func (f *ICMPFilter) SetAll(block bool) {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
f.setAll(block)
|
||||
f.mu.Unlock()
|
||||
}
|
||||
|
||||
// WillBlock reports whether the ICMP type will be blocked.
|
||||
func (f *ICMPFilter) WillBlock(typ ICMPType) bool {
|
||||
f.mu.RLock()
|
||||
defer f.mu.RUnlock()
|
||||
return f.willBlock(typ)
|
||||
ok := f.willBlock(typ)
|
||||
f.mu.RUnlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
12
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_bsd.go
generated
vendored
12
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_bsd.go
generated
vendored
@@ -6,13 +6,11 @@
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
type rawICMPFilter struct {
|
||||
syscall.ICMPv6Filter
|
||||
type sysICMPFilter struct {
|
||||
Filt [8]uint32
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) set(typ ICMPType, block bool) {
|
||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
||||
if block {
|
||||
f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
|
||||
} else {
|
||||
@@ -20,7 +18,7 @@ func (f *rawICMPFilter) set(typ ICMPType, block bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) setAll(block bool) {
|
||||
func (f *sysICMPFilter) setAll(block bool) {
|
||||
for i := range f.Filt {
|
||||
if block {
|
||||
f.Filt[i] = 0
|
||||
@@ -30,6 +28,6 @@ func (f *rawICMPFilter) setAll(block bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) willBlock(typ ICMPType) bool {
|
||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
||||
return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
|
||||
}
|
||||
|
||||
12
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_linux.go
generated
vendored
12
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_linux.go
generated
vendored
@@ -4,13 +4,11 @@
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
type rawICMPFilter struct {
|
||||
syscall.ICMPv6Filter
|
||||
type sysICMPFilter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) set(typ ICMPType, block bool) {
|
||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
||||
if block {
|
||||
f.Data[typ>>5] |= 1 << (uint32(typ) & 31)
|
||||
} else {
|
||||
@@ -18,7 +16,7 @@ func (f *rawICMPFilter) set(typ ICMPType, block bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) setAll(block bool) {
|
||||
func (f *sysICMPFilter) setAll(block bool) {
|
||||
for i := range f.Data {
|
||||
if block {
|
||||
f.Data[i] = 1<<32 - 1
|
||||
@@ -28,6 +26,6 @@ func (f *rawICMPFilter) setAll(block bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) willBlock(typ ICMPType) bool {
|
||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
||||
return f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0
|
||||
}
|
||||
|
||||
@@ -2,21 +2,23 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
package ipv6
|
||||
|
||||
type rawICMPFilter struct {
|
||||
type sysICMPFilter struct {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) set(typ ICMPType, block bool) {
|
||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) setAll(block bool) {
|
||||
func (f *sysICMPFilter) setAll(block bool) {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) willBlock(typ ICMPType) bool {
|
||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
||||
// TODO(mikio): Implement this
|
||||
return false
|
||||
}
|
||||
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_test.go
generated
vendored
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_test.go
generated
vendored
@@ -14,9 +14,27 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var icmpStringTests = []struct {
|
||||
in ipv6.ICMPType
|
||||
out string
|
||||
}{
|
||||
{ipv6.ICMPTypeDestinationUnreachable, "destination unreachable"},
|
||||
|
||||
{256, "<nil>"},
|
||||
}
|
||||
|
||||
func TestICMPString(t *testing.T) {
|
||||
for _, tt := range icmpStringTests {
|
||||
s := tt.in.String()
|
||||
if s != tt.out {
|
||||
t.Errorf("got %s; expected %s", s, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestICMPFilter(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
|
||||
@@ -49,7 +67,7 @@ func TestICMPFilter(t *testing.T) {
|
||||
|
||||
func TestSetICMPFilter(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
||||
8
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_windows.go
generated
vendored
8
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_windows.go
generated
vendored
@@ -4,19 +4,19 @@
|
||||
|
||||
package ipv6
|
||||
|
||||
type rawICMPFilter struct {
|
||||
type sysICMPFilter struct {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) set(typ ICMPType, block bool) {
|
||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) setAll(block bool) {
|
||||
func (f *sysICMPFilter) setAll(block bool) {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *rawICMPFilter) willBlock(typ ICMPType) bool {
|
||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
||||
// TODO(mikio): Implement this
|
||||
return false
|
||||
}
|
||||
|
||||
30
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mockicmp_test.go
generated
vendored
30
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mockicmp_test.go
generated
vendored
@@ -7,8 +7,22 @@ package ipv6_test
|
||||
import (
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
const (
|
||||
ipv6PseudoHeaderLen = 2*net.IPv6len + 8
|
||||
ianaProtocolIPv6ICMP = 58
|
||||
)
|
||||
|
||||
func ipv6PseudoHeader(src, dst net.IP, nextHeader int) []byte {
|
||||
b := make([]byte, ipv6PseudoHeaderLen)
|
||||
copy(b[:net.IPv6len], src)
|
||||
copy(b[net.IPv6len:], dst)
|
||||
b[len(b)-1] = byte(nextHeader)
|
||||
return b
|
||||
}
|
||||
|
||||
// icmpMessage represents an ICMP message.
|
||||
type icmpMessage struct {
|
||||
Type ipv6.ICMPType // type
|
||||
@@ -25,8 +39,11 @@ type icmpMessageBody interface {
|
||||
|
||||
// Marshal returns the binary enconding of the ICMP echo request or
|
||||
// reply message m.
|
||||
func (m *icmpMessage) Marshal() ([]byte, error) {
|
||||
func (m *icmpMessage) Marshal(psh []byte) ([]byte, error) {
|
||||
b := []byte{byte(m.Type), byte(m.Code), 0, 0}
|
||||
if psh != nil {
|
||||
b = append(psh, b...)
|
||||
}
|
||||
if m.Body != nil && m.Body.Len() != 0 {
|
||||
mb, err := m.Body.Marshal()
|
||||
if err != nil {
|
||||
@@ -34,10 +51,11 @@ func (m *icmpMessage) Marshal() ([]byte, error) {
|
||||
}
|
||||
b = append(b, mb...)
|
||||
}
|
||||
switch m.Type {
|
||||
case ipv6.ICMPTypeEchoRequest, ipv6.ICMPTypeEchoReply:
|
||||
if psh == nil {
|
||||
return b, nil
|
||||
}
|
||||
off, l := 2*net.IPv6len, len(b)-len(psh)
|
||||
b[off], b[off+1], b[off+2], b[off+3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
|
||||
csumcv := len(b) - 1 // checksum coverage
|
||||
s := uint32(0)
|
||||
for i := 0; i < csumcv; i += 2 {
|
||||
@@ -50,9 +68,9 @@ func (m *icmpMessage) Marshal() ([]byte, error) {
|
||||
s = s + s>>16
|
||||
// Place checksum back in header; using ^= avoids the
|
||||
// assumption the checksum bytes are zero.
|
||||
b[2] ^= byte(^s)
|
||||
b[3] ^= byte(^s >> 8)
|
||||
return b, nil
|
||||
b[len(psh)+2] ^= byte(^s)
|
||||
b[len(psh)+3] ^= byte(^s >> 8)
|
||||
return b[len(psh):], nil
|
||||
}
|
||||
|
||||
// parseICMPMessage parses b as an ICMP message.
|
||||
|
||||
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mocktransponder_test.go
generated
vendored
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mocktransponder_test.go
generated
vendored
@@ -86,25 +86,3 @@ func acceptor(t *testing.T, ln net.Listener, done chan<- bool) {
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
|
||||
func transponder(t *testing.T, ln net.Listener, done chan<- bool) {
|
||||
defer func() { done <- true }()
|
||||
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
t.Errorf("net.Listener.Accept failed: %v", err)
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
b := make([]byte, 128)
|
||||
n, err := c.Read(b)
|
||||
if err != nil {
|
||||
t.Errorf("net.Conn.Read failed: %v", err)
|
||||
return
|
||||
}
|
||||
if _, err := c.Write(b[:n]); err != nil {
|
||||
t.Errorf("net.Conn.Write failed: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
76
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicast_test.go
generated
vendored
76
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicast_test.go
generated
vendored
@@ -5,11 +5,13 @@
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
||||
@@ -17,7 +19,7 @@ func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
||||
case "freebsd": // due to a bug on loopback marking
|
||||
// See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -44,33 +46,49 @@ func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
||||
}
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
if err := p.JoinGroup(ifi, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
if err := p.SetMulticastInterface(ifi); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastInterface failed: %v", err)
|
||||
}
|
||||
if _, err := p.MulticastInterface(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastInterface failed: %v", err)
|
||||
}
|
||||
if err := p.SetMulticastLoopback(true); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastLoopback failed: %v", err)
|
||||
}
|
||||
if _, err := p.MulticastLoopback(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastLoopback failed: %v", err)
|
||||
}
|
||||
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
IfIndex: ifi.Index,
|
||||
}
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
wb := []byte("HELLO-R-U-THERE")
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
cm.HopLimit = i + 1
|
||||
if _, err := p.WriteTo([]byte("HELLO-R-U-THERE"), &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
|
||||
}
|
||||
b := make([]byte, 128)
|
||||
if _, cm, _, err := p.ReadFrom(b); err != nil {
|
||||
cm.HopLimit = i + 1
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
} else if !bytes.Equal(rb[:n], wb) {
|
||||
t.Fatalf("got %v; expected %v", rb[:n], wb)
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
}
|
||||
@@ -79,7 +97,7 @@ func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
||||
|
||||
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -104,22 +122,31 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
|
||||
t.Fatalf("net.ResolveIPAddr failed: %v", err)
|
||||
}
|
||||
|
||||
pshicmp := ipv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP, ianaProtocolIPv6ICMP)
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
if err := p.JoinGroup(ifi, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
if err := p.SetMulticastInterface(ifi); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastInterface failed: %v", err)
|
||||
}
|
||||
if _, err := p.MulticastInterface(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastInterface failed: %v", err)
|
||||
}
|
||||
if err := p.SetMulticastLoopback(true); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastLoopback failed: %v", err)
|
||||
}
|
||||
if _, err := p.MulticastLoopback(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastLoopback failed: %v", err)
|
||||
}
|
||||
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
IfIndex: ifi.Index,
|
||||
}
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
|
||||
var f ipv6.ICMPFilter
|
||||
f.SetAll(true)
|
||||
@@ -128,30 +155,47 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
|
||||
t.Fatalf("ipv6.PacketConn.SetICMPFilter failed: %v", err)
|
||||
}
|
||||
|
||||
var psh []byte
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if toggle {
|
||||
psh = nil
|
||||
if err := p.SetChecksum(true, 2); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetChecksum failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
psh = pshicmp
|
||||
// Some platforms never allow to disable the
|
||||
// kernel checksum processing.
|
||||
p.SetChecksum(false, -1)
|
||||
}
|
||||
wb, err := (&icmpMessage{
|
||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
||||
Body: &icmpEcho{
|
||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
||||
Data: []byte("HELLO-R-U-THERE"),
|
||||
},
|
||||
}).Marshal()
|
||||
}).Marshal(psh)
|
||||
if err != nil {
|
||||
t.Fatalf("icmpMessage.Marshal failed: %v", err)
|
||||
}
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
cm.HopLimit = i + 1
|
||||
if _, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
|
||||
}
|
||||
b := make([]byte, 128)
|
||||
if n, cm, _, err := p.ReadFrom(b); err != nil {
|
||||
cm.HopLimit = i + 1
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
if m, err := parseICMPMessage(b[:n]); err != nil {
|
||||
if m, err := parseICMPMessage(rb[:n]); err != nil {
|
||||
t.Fatalf("parseICMPMessage failed: %v", err)
|
||||
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
|
||||
t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
|
||||
|
||||
70
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastlistener_test.go
generated
vendored
70
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastlistener_test.go
generated
vendored
@@ -21,7 +21,7 @@ var udpMultipleGroupListenerTests = []net.Addr{
|
||||
|
||||
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -59,9 +59,9 @@ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUDPMultipleConnWithMultipleGroupListeners(t *testing.T) {
|
||||
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -113,14 +113,14 @@ func TestUDPMultipleConnWithMultipleGroupListeners(t *testing.T) {
|
||||
|
||||
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
gaddr := &net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
||||
gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
||||
type ml struct {
|
||||
c *ipv6.PacketConn
|
||||
ifi *net.Interface
|
||||
@@ -142,13 +142,13 @@ func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
mlt = append(mlt, &ml{p, &ift[i]})
|
||||
}
|
||||
for _, m := range mlt {
|
||||
if err := m.c.LeaveGroup(m.ifi, gaddr); err != nil {
|
||||
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.LeaveGroup on %v failed: %v", m.ifi, err)
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
|
||||
func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -166,14 +166,14 @@ func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::")
|
||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::") // wildcard address
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
gaddr := &net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
||||
gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
||||
var mift []*net.Interface
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
@@ -184,14 +184,60 @@ func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
if _, ok := isMulticastAvailable(&ifi); !ok {
|
||||
continue
|
||||
}
|
||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
mift = append(mift, &ift[i])
|
||||
}
|
||||
for _, ifi := range mift {
|
||||
if err := p.LeaveGroup(ifi, gaddr); err != nil {
|
||||
if err := p.LeaveGroup(ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.LeaveGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
if os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
|
||||
gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
||||
type ml struct {
|
||||
c *ipv6.PacketConn
|
||||
ifi *net.Interface
|
||||
}
|
||||
var mlt []*ml
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatalf("net.Interfaces failed: %v", err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
ip, ok := isMulticastAvailable(&ifi)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
c, err := net.ListenPacket("ip6:ipv6-icmp", fmt.Sprintf("%s%%%s", ip.String(), ifi.Name)) // unicast address
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
mlt = append(mlt, &ml{p, &ift[i]})
|
||||
}
|
||||
for _, m := range mlt {
|
||||
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.LeaveGroup on %v failed: %v", m.ifi, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastsockopt_test.go
generated
vendored
2
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastsockopt_test.go
generated
vendored
@@ -22,7 +22,7 @@ var packetConnMulticastSocketOptionTests = []struct {
|
||||
|
||||
func TestPacketConnMulticastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
||||
168
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/readwrite_test.go
generated
vendored
Normal file
168
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/readwrite_test.go
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
|
||||
c, err := net.ListenPacket("udp6", "[::1]:0")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
c.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
return c, dst, nil
|
||||
}
|
||||
|
||||
func BenchmarkReadWriteNetUDP(b *testing.B) {
|
||||
c, dst, err := benchmarkUDPListener()
|
||||
if err != nil {
|
||||
b.Fatalf("benchmarkUDPListener failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
|
||||
if _, err := c.WriteTo(wb, dst); err != nil {
|
||||
b.Fatalf("net.PacketConn.WriteTo failed: %v", err)
|
||||
}
|
||||
if _, _, err := c.ReadFrom(rb); err != nil {
|
||||
b.Fatalf("net.PacketConn.ReadFrom failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReadWriteIPv6UDP(b *testing.B) {
|
||||
c, dst, err := benchmarkUDPListener()
|
||||
if err != nil {
|
||||
b.Fatalf("benchmarkUDPListener failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
if err := p.SetControlMessage(cf, true); err != nil {
|
||||
b.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
ifi := loopbackInterface()
|
||||
|
||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
HopLimit: 1,
|
||||
}
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
b.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
b.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
if _, _, _, err := p.ReadFrom(rb); err != nil {
|
||||
b.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("udp6", "[::1]:0")
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
|
||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("net.ResolveUDPAddr failed: %v", err)
|
||||
}
|
||||
|
||||
ifi := loopbackInterface()
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
wb := []byte("HELLO-R-U-THERE")
|
||||
|
||||
var wg sync.WaitGroup
|
||||
reader := func() {
|
||||
defer wg.Done()
|
||||
rb := make([]byte, 128)
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Errorf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
return
|
||||
} else if !bytes.Equal(rb[:n], wb) {
|
||||
t.Errorf("got %v; expected %v", rb[:n], wb)
|
||||
return
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
}
|
||||
}
|
||||
writer := func(toggle bool) {
|
||||
defer wg.Done()
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
Dst: net.IPv6loopback,
|
||||
}
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Errorf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
return
|
||||
}
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Errorf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
return
|
||||
} else if n != len(wb) {
|
||||
t.Errorf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const N = 10
|
||||
wg.Add(N)
|
||||
for i := 0; i < N; i++ {
|
||||
go reader()
|
||||
}
|
||||
wg.Add(2 * N)
|
||||
for i := 0; i < 2*N; i++ {
|
||||
go writer(i%2 != 0)
|
||||
}
|
||||
wg.Add(N)
|
||||
for i := 0; i < N; i++ {
|
||||
go reader()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
66
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc2292_darwin.go
generated
vendored
66
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc2292_darwin.go
generated
vendored
@@ -1,66 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func ipv6ReceiveTrafficClass(fd int) (bool, error) {
|
||||
return false, errNotSupported
|
||||
}
|
||||
|
||||
func setIPv6ReceiveTrafficClass(fd int, v bool) error {
|
||||
return errNotSupported
|
||||
}
|
||||
|
||||
func ipv6ReceiveHopLimit(fd int) (bool, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_2292HOPLIMIT)
|
||||
if err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceiveHopLimit(fd int, v bool) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_2292HOPLIMIT, boolint(v)))
|
||||
}
|
||||
|
||||
func ipv6ReceivePacketInfo(fd int) (bool, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_2292PKTINFO)
|
||||
if err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceivePacketInfo(fd int, v bool) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_2292PKTINFO, boolint(v)))
|
||||
}
|
||||
|
||||
func ipv6PathMTU(fd int) (int, error) {
|
||||
return 0, errNotSupported
|
||||
}
|
||||
|
||||
func ipv6ReceivePathMTU(fd int) (bool, error) {
|
||||
return false, errNotSupported
|
||||
}
|
||||
|
||||
func setIPv6ReceivePathMTU(fd int, v bool) error {
|
||||
return errNotSupported
|
||||
}
|
||||
|
||||
func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
|
||||
v, err := syscall.GetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMP6_FILTER)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return &ICMPFilter{rawICMPFilter: rawICMPFilter{*v}}, nil
|
||||
}
|
||||
|
||||
func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMP6_FILTER, &f.rawICMPFilter.ICMPv6Filter))
|
||||
}
|
||||
73
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc2292_unix.go
generated
vendored
Normal file
73
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc2292_unix.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func ipv6ReceiveTrafficClass(fd int) (bool, error) {
|
||||
return false, errOpNoSupport
|
||||
}
|
||||
|
||||
func setIPv6ReceiveTrafficClass(fd int, v bool) error {
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
func ipv6ReceiveHopLimit(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceiveHopLimit(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6ReceivePacketInfo(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceivePacketInfo(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6PathMTU(fd int) (int, error) {
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
func ipv6ReceivePathMTU(fd int) (bool, error) {
|
||||
return false, errOpNoSupport
|
||||
}
|
||||
|
||||
func setIPv6ReceivePathMTU(fd int, v bool) error {
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
|
||||
var v ICMPFilter
|
||||
l := sysSockoptLen(sysSizeofICMPFilter)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&v.sysICMPFilter)), &l); err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&f.sysICMPFilter)), sysSizeofICMPFilter))
|
||||
}
|
||||
5
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_bsd.go
generated
vendored
5
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_bsd.go
generated
vendored
@@ -8,12 +8,13 @@ package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setIPv6Checksum(fd int, on bool, offset int) error {
|
||||
if !on {
|
||||
offset = -1
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_CHECKSUM, offset))
|
||||
v := int32(offset)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), 4))
|
||||
}
|
||||
|
||||
5
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_linux.go
generated
vendored
5
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_linux.go
generated
vendored
@@ -6,12 +6,13 @@ package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setIPv6Checksum(fd int, on bool, offset int) error {
|
||||
if !on {
|
||||
offset = -1
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolReserved, syscall.IPV6_CHECKSUM, offset))
|
||||
v := int32(offset)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolReserved, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), 4))
|
||||
}
|
||||
|
||||
76
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_unix.go
generated
vendored
76
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_unix.go
generated
vendored
@@ -9,66 +9,74 @@ package ipv6
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func ipv6TrafficClass(fd int) (int, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_TCLASS)
|
||||
if err != nil {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptTrafficClass, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v, nil
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func setIPv6TrafficClass(fd, v int) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_TCLASS, v))
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptTrafficClass, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6HopLimit(fd int) (int, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_UNICAST_HOPS)
|
||||
if err != nil {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v, nil
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func setIPv6HopLimit(fd, v int) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_UNICAST_HOPS, v))
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6Checksum(fd int) (bool, int, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_CHECKSUM)
|
||||
if err != nil {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
on := true
|
||||
if v == -1 {
|
||||
on = false
|
||||
}
|
||||
return on, v, nil
|
||||
return on, int(v), nil
|
||||
}
|
||||
|
||||
func ipv6MulticastHopLimit(fd int) (int, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_HOPS)
|
||||
if err != nil {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v, nil
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func setIPv6MulticastHopLimit(fd, v int) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_HOPS, v))
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6MulticastInterface(fd int) (*net.Interface, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_IF)
|
||||
if err != nil {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
if v == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
ifi, err := net.InterfaceByIndex(v)
|
||||
ifi, err := net.InterfaceByIndex(int(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -76,39 +84,41 @@ func ipv6MulticastInterface(fd int) (*net.Interface, error) {
|
||||
}
|
||||
|
||||
func setIPv6MulticastInterface(fd int, ifi *net.Interface) error {
|
||||
var v int
|
||||
var v int32
|
||||
if ifi != nil {
|
||||
v = ifi.Index
|
||||
v = int32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_IF, v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, uintptr(unsafe.Pointer(&v)), 4))
|
||||
}
|
||||
|
||||
func ipv6MulticastLoopback(fd int) (bool, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_LOOP)
|
||||
if err != nil {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6MulticastLoopback(fd int, v bool) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_LOOP, boolint(v)))
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func joinIPv6Group(fd int, ifi *net.Interface, grp net.IP) error {
|
||||
mreq := syscall.IPv6Mreq{}
|
||||
copy(mreq.Multiaddr[:], grp)
|
||||
mreq := sysMulticastReq{}
|
||||
copy(mreq.IP[:], grp)
|
||||
if ifi != nil {
|
||||
mreq.Interface = uint32(ifi.Index)
|
||||
mreq.IfIndex = uint32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd, ianaProtocolIPv6, syscall.IPV6_JOIN_GROUP, &mreq))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptJoinGroup, uintptr(unsafe.Pointer(&mreq)), sysSizeofMulticastReq))
|
||||
}
|
||||
|
||||
func leaveIPv6Group(fd int, ifi *net.Interface, grp net.IP) error {
|
||||
mreq := syscall.IPv6Mreq{}
|
||||
copy(mreq.Multiaddr[:], grp)
|
||||
mreq := sysMulticastReq{}
|
||||
copy(mreq.IP[:], grp)
|
||||
if ifi != nil {
|
||||
mreq.Interface = uint32(ifi.Index)
|
||||
mreq.IfIndex = uint32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd, ianaProtocolIPv6, syscall.IPV6_LEAVE_GROUP, &mreq))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptLeaveGroup, uintptr(unsafe.Pointer(&mreq)), sysSizeofMulticastReq))
|
||||
}
|
||||
|
||||
32
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_windows.go
generated
vendored
32
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_windows.go
generated
vendored
@@ -24,7 +24,7 @@ func setIPv6TrafficClass(fd syscall.Handle, v int) error {
|
||||
func ipv6HopLimit(fd syscall.Handle) (int, error) {
|
||||
var v int32
|
||||
l := int32(4)
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, syscall.IPV6_UNICAST_HOPS, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v), nil
|
||||
@@ -32,7 +32,7 @@ func ipv6HopLimit(fd syscall.Handle) (int, error) {
|
||||
|
||||
func setIPv6HopLimit(fd syscall.Handle, v int) error {
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_UNICAST_HOPS, (*byte)(unsafe.Pointer(&vv)), 4))
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6Checksum(fd syscall.Handle) (bool, int, error) {
|
||||
@@ -43,7 +43,7 @@ func ipv6Checksum(fd syscall.Handle) (bool, int, error) {
|
||||
func ipv6MulticastHopLimit(fd syscall.Handle) (int, error) {
|
||||
var v int32
|
||||
l := int32(4)
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_HOPS, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v), nil
|
||||
@@ -51,13 +51,13 @@ func ipv6MulticastHopLimit(fd syscall.Handle) (int, error) {
|
||||
|
||||
func setIPv6MulticastHopLimit(fd syscall.Handle, v int) error {
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_HOPS, (*byte)(unsafe.Pointer(&vv)), 4))
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, (*byte)(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6MulticastInterface(fd syscall.Handle) (*net.Interface, error) {
|
||||
var v int32
|
||||
l := int32(4)
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_IF, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
if v == 0 {
|
||||
@@ -75,13 +75,13 @@ func setIPv6MulticastInterface(fd syscall.Handle, ifi *net.Interface) error {
|
||||
if ifi != nil {
|
||||
v = int32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_IF, (*byte)(unsafe.Pointer(&v)), 4))
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, (*byte)(unsafe.Pointer(&v)), 4))
|
||||
}
|
||||
|
||||
func ipv6MulticastLoopback(fd syscall.Handle) (bool, error) {
|
||||
var v int32
|
||||
l := int32(4)
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_LOOP, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
@@ -89,25 +89,25 @@ func ipv6MulticastLoopback(fd syscall.Handle) (bool, error) {
|
||||
|
||||
func setIPv6MulticastLoopback(fd syscall.Handle, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_LOOP, (*byte)(unsafe.Pointer(&vv)), 4))
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, (*byte)(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func joinIPv6Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error {
|
||||
mreq := syscall.IPv6Mreq{}
|
||||
copy(mreq.Multiaddr[:], grp)
|
||||
mreq := sysMulticastReq{}
|
||||
copy(mreq.IP[:], grp)
|
||||
if ifi != nil {
|
||||
mreq.Interface = uint32(ifi.Index)
|
||||
mreq.IfIndex = uint32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_JOIN_GROUP, (*byte)(unsafe.Pointer(&mreq)), int32(unsafe.Sizeof(mreq))))
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptJoinGroup, (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofMulticastReq)))
|
||||
}
|
||||
|
||||
func leaveIPv6Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error {
|
||||
mreq := syscall.IPv6Mreq{}
|
||||
copy(mreq.Multiaddr[:], grp)
|
||||
mreq := sysMulticastReq{}
|
||||
copy(mreq.IP[:], grp)
|
||||
if ifi != nil {
|
||||
mreq.Interface = uint32(ifi.Index)
|
||||
mreq.IfIndex = uint32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_LEAVE_GROUP, (*byte)(unsafe.Pointer(&mreq)), int32(unsafe.Sizeof(mreq))))
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptLeaveGroup, (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofMulticastReq)))
|
||||
}
|
||||
|
||||
func setIPv6Checksum(fd syscall.Handle, on bool, offset int) error {
|
||||
|
||||
44
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_bsd.go
generated
vendored
44
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_bsd.go
generated
vendored
@@ -1,44 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build freebsd netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func ipv6PathMTU(fd int) (int, error) {
|
||||
v, err := syscall.GetsockoptIPv6MTUInfo(fd, ianaProtocolIPv6, syscall.IPV6_PATHMTU)
|
||||
if err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v.Mtu), nil
|
||||
}
|
||||
|
||||
func ipv6ReceivePathMTU(fd int) (bool, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVPATHMTU)
|
||||
if err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceivePathMTU(fd int, v bool) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVPATHMTU, boolint(v)))
|
||||
}
|
||||
|
||||
func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
|
||||
v, err := syscall.GetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMP6_FILTER)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return &ICMPFilter{rawICMPFilter: rawICMPFilter{*v}}, nil
|
||||
}
|
||||
|
||||
func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMP6_FILTER, &f.rawICMPFilter.ICMPv6Filter))
|
||||
}
|
||||
42
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_linux.go
generated
vendored
42
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_linux.go
generated
vendored
@@ -1,42 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func ipv6PathMTU(fd int) (int, error) {
|
||||
v, err := syscall.GetsockoptIPv6MTUInfo(fd, ianaProtocolIPv6, syscall_IPV6_PATHMTU)
|
||||
if err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v.Mtu), nil
|
||||
}
|
||||
|
||||
func ipv6ReceivePathMTU(fd int) (bool, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall_IPV6_RECVPATHMTU)
|
||||
if err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceivePathMTU(fd int, v bool) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall_IPV6_RECVPATHMTU, boolint(v)))
|
||||
}
|
||||
|
||||
func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
|
||||
v, err := syscall.GetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMPV6_FILTER)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return &ICMPFilter{rawICMPFilter: rawICMPFilter{*v}}, nil
|
||||
}
|
||||
|
||||
func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMPV6_FILTER, &f.rawICMPFilter.ICMPv6Filter))
|
||||
}
|
||||
@@ -2,11 +2,11 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
import "syscall"
|
||||
package ipv6
|
||||
|
||||
func ipv6PathMTU(fd int) (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, syscall.EPLAN9
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
62
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_unix.go
generated
vendored
62
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_unix.go
generated
vendored
@@ -8,41 +8,83 @@ package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func ipv6ReceiveTrafficClass(fd int) (bool, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVTCLASS)
|
||||
if err != nil {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceiveTrafficClass(fd int, v bool) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVTCLASS, boolint(v)))
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6ReceiveHopLimit(fd int) (bool, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVHOPLIMIT)
|
||||
if err != nil {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceiveHopLimit(fd int, v bool) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVHOPLIMIT, boolint(v)))
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6ReceivePacketInfo(fd int) (bool, error) {
|
||||
v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVPKTINFO)
|
||||
if err != nil {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceivePacketInfo(fd int, v bool) error {
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVPKTINFO, boolint(v)))
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6PathMTU(fd int) (int, error) {
|
||||
var v sysMTUInfo
|
||||
l := sysSockoptLen(sysSizeofMTUInfo)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptPathMTU, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v.MTU), nil
|
||||
}
|
||||
|
||||
func ipv6ReceivePathMTU(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceivePathMTU(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
|
||||
var v ICMPFilter
|
||||
l := sysSockoptLen(sysSizeofICMPFilter)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&v.sysICMPFilter)), &l); err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&f.sysICMPFilter)), sysSizeofICMPFilter))
|
||||
}
|
||||
|
||||
8
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_test.go
generated
vendored
8
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_test.go
generated
vendored
@@ -24,7 +24,7 @@ func init() {
|
||||
var condFatalf = func() func(*testing.T, string, ...interface{}) {
|
||||
// A few APIs are not implemented yet on some platforms.
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "plan9", "windows":
|
||||
case "darwin", "dragonfly", "plan9", "solaris", "windows":
|
||||
return (*testing.T).Logf
|
||||
}
|
||||
return (*testing.T).Fatalf
|
||||
@@ -32,7 +32,7 @@ var condFatalf = func() func(*testing.T, string, ...interface{}) {
|
||||
|
||||
func TestConnInitiatorPathMTU(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -65,7 +65,7 @@ func TestConnInitiatorPathMTU(t *testing.T) {
|
||||
|
||||
func TestConnResponderPathMTU(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -98,7 +98,7 @@ func TestConnResponderPathMTU(t *testing.T) {
|
||||
|
||||
func TestPacketConnChecksum(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
||||
23
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys.go
generated
vendored
Normal file
23
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
type sysSockoptLen uint32
|
||||
|
||||
const (
|
||||
sysSizeofPacketInfo = 0x14
|
||||
sysSizeofMulticastReq = 0x14
|
||||
sysSizeofICMPFilter = 0x20
|
||||
)
|
||||
|
||||
type sysPacketInfo struct {
|
||||
IP [16]byte
|
||||
IfIndex uint32
|
||||
}
|
||||
|
||||
type sysMulticastReq struct {
|
||||
IP [16]byte
|
||||
IfIndex uint32
|
||||
}
|
||||
48
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_bsd.go
generated
vendored
Normal file
48
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build freebsd netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// RFC 3493 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptUnicastHopLimit = 0x4
|
||||
sysSockoptMulticastHopLimit = 0xa
|
||||
sysSockoptMulticastInterface = 0x9
|
||||
sysSockoptMulticastLoopback = 0xb
|
||||
sysSockoptJoinGroup = 0xc
|
||||
sysSockoptLeaveGroup = 0xd
|
||||
)
|
||||
|
||||
// RFC 3542 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptReceiveTrafficClass = 0x39
|
||||
sysSockoptTrafficClass = 0x3d
|
||||
sysSockoptReceiveHopLimit = 0x25
|
||||
sysSockoptHopLimit = 0x2f
|
||||
sysSockoptReceivePacketInfo = 0x24
|
||||
sysSockoptPacketInfo = 0x2e
|
||||
sysSockoptReceivePathMTU = 0x2b
|
||||
sysSockoptPathMTU = 0x2c
|
||||
sysSockoptNextHop = 0x30
|
||||
sysSockoptChecksum = 0x1a
|
||||
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptICMPFilter = 0x12
|
||||
)
|
||||
|
||||
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
|
||||
sa.Len = syscall.SizeofSockaddrInet6
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], ip)
|
||||
sa.Scope_id = uint32(ifindex)
|
||||
}
|
||||
54
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_darwin.go
generated
vendored
Normal file
54
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// RFC 2292 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockopt2292HopLimit = 0x14
|
||||
sysSockopt2292PacketInfo = 0x13
|
||||
sysSockopt2292NextHop = 0x15
|
||||
)
|
||||
|
||||
// RFC 3493 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptUnicastHopLimit = 0x4
|
||||
sysSockoptMulticastHopLimit = 0xa
|
||||
sysSockoptMulticastInterface = 0x9
|
||||
sysSockoptMulticastLoopback = 0xb
|
||||
sysSockoptJoinGroup = 0xc
|
||||
sysSockoptLeaveGroup = 0xd
|
||||
)
|
||||
|
||||
// RFC 3542 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptReceiveTrafficClass = 0x23
|
||||
sysSockoptTrafficClass = 0x24
|
||||
sysSockoptReceiveHopLimit = 0x25
|
||||
sysSockoptHopLimit = 0x2f
|
||||
sysSockoptReceivePacketInfo = 0x3d
|
||||
sysSockoptPacketInfo = 0x2e
|
||||
sysSockoptReceivePathMTU = 0x2b
|
||||
sysSockoptPathMTU = 0x2c
|
||||
sysSockoptNextHop = 0x30
|
||||
sysSockoptChecksum = 0x1a
|
||||
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptICMPFilter = 0x12
|
||||
)
|
||||
|
||||
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
|
||||
sa.Len = syscall.SizeofSockaddrInet6
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], ip)
|
||||
sa.Scope_id = uint32(ifindex)
|
||||
}
|
||||
45
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_linux.go
generated
vendored
Normal file
45
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_linux.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// RFC 3493 options
|
||||
const (
|
||||
// See /usr/include/linux/in6.h.
|
||||
sysSockoptUnicastHopLimit = 0x10
|
||||
sysSockoptMulticastHopLimit = 0x12
|
||||
sysSockoptMulticastInterface = 0x11
|
||||
sysSockoptMulticastLoopback = 0x13
|
||||
sysSockoptJoinGroup = 0x14
|
||||
sysSockoptLeaveGroup = 0x15
|
||||
)
|
||||
|
||||
// RFC 3542 options
|
||||
const (
|
||||
// See /usr/include/linux/ipv6.h,in6.h.
|
||||
sysSockoptReceiveTrafficClass = 0x42
|
||||
sysSockoptTrafficClass = 0x43
|
||||
sysSockoptReceiveHopLimit = 0x33
|
||||
sysSockoptHopLimit = 0x34
|
||||
sysSockoptReceivePacketInfo = 0x31
|
||||
sysSockoptPacketInfo = 0x32
|
||||
sysSockoptReceivePathMTU = 0x3c
|
||||
sysSockoptPathMTU = 0x3d
|
||||
sysSockoptNextHop = 0x9
|
||||
sysSockoptChecksum = 0x7
|
||||
|
||||
// See /usr/include/linux/icmpv6.h.
|
||||
sysSockoptICMPFilter = 0x1
|
||||
)
|
||||
|
||||
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], ip)
|
||||
sa.Scope_id = uint32(ifindex)
|
||||
}
|
||||
16
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_unix.go
generated
vendored
Normal file
16
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_unix.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
const sysSizeofMTUInfo = 0x20
|
||||
|
||||
type sysMTUInfo struct {
|
||||
Addr syscall.RawSockaddrInet6
|
||||
MTU uint32
|
||||
}
|
||||
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_windows.go
generated
vendored
Normal file
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_windows.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// RFC 3493 options
|
||||
const (
|
||||
// See ws2tcpip.h.
|
||||
sysSockoptUnicastHopLimit = 0x4
|
||||
sysSockoptMulticastHopLimit = 0xa
|
||||
sysSockoptMulticastInterface = 0x9
|
||||
sysSockoptMulticastLoopback = 0xb
|
||||
sysSockoptJoinGroup = 0xc
|
||||
sysSockoptLeaveGroup = 0xd
|
||||
)
|
||||
|
||||
// RFC 3542 options
|
||||
const (
|
||||
// See ws2tcpip.h.
|
||||
sysSockoptPacketInfo = 0x13
|
||||
)
|
||||
|
||||
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], ip)
|
||||
sa.Scope_id = uint32(ifindex)
|
||||
}
|
||||
42
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.go
generated
vendored
Normal file
42
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code is a duplicate of syscall/syscall_linux_386.go with small
|
||||
// modifications.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// On x86 Linux, all the socket calls go through an extra indirection,
|
||||
// I think because the 5-register system call interface can't handle
|
||||
// the 6-argument calls like sendto and recvfrom. Instead the
|
||||
// arguments to the underlying system call are the number below and a
|
||||
// pointer to an array of uintptr. We hide the pointer in the
|
||||
// socketcall assembly to avoid allocation on every system call.
|
||||
|
||||
const (
|
||||
// See /usr/include/linux/net.h.
|
||||
_SETSOCKOPT = 14
|
||||
_GETSOCKOPT = 15
|
||||
)
|
||||
|
||||
var socketcall func(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
|
||||
|
||||
func getsockopt(fd int, level int, name int, v uintptr, l *sysSockoptLen) error {
|
||||
if _, errno := socketcall(_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setsockopt(fd int, level int, name int, v uintptr, l uintptr) error {
|
||||
if _, errno := socketcall(_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), v, l, 0); errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
56
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.s
generated
vendored
Normal file
56
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.s
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code is a duplicate of syscall/syscall_linux_386.s with small
|
||||
// modifications.
|
||||
|
||||
#define SYS_SOCKETCALL 102 // from zsysnum_linux_386.go
|
||||
|
||||
// func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
|
||||
// Kernel interface gets call sub-number and pointer to a0 for Go 1.1.
|
||||
TEXT ·socketcallnosplit7(SB),7,$0
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOVL $SYS_SOCKETCALL, AX // syscall entry
|
||||
MOVL 4(SP), BX // socket call number
|
||||
LEAL 8(SP), CX // pointer to call arguments
|
||||
MOVL $0, DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
CALL *runtime·_vdso(SB)
|
||||
CMPL AX, $0xfffff001
|
||||
JLS ok1
|
||||
MOVL $-1, 32(SP) // n
|
||||
NEGL AX
|
||||
MOVL AX, 36(SP) // errno
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
ok1:
|
||||
MOVL AX, 32(SP) // n
|
||||
MOVL $0, 36(SP) // errno
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
// func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
|
||||
// Kernel interface gets call sub-number and pointer to a0 for Go 1.2.
|
||||
TEXT ·socketcallnosplit4(SB),4,$0-40
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOVL $SYS_SOCKETCALL, AX // syscall entry
|
||||
MOVL 4(SP), BX // socket call number
|
||||
LEAL 8(SP), CX // pointer to call arguments
|
||||
MOVL $0, DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
CALL *runtime·_vdso(SB)
|
||||
CMPL AX, $0xfffff001
|
||||
JLS ok2
|
||||
MOVL $-1, 32(SP) // n
|
||||
NEGL AX
|
||||
MOVL AX, 36(SP) // errno
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
ok2:
|
||||
MOVL AX, 32(SP) // n
|
||||
MOVL $0, 36(SP) // errno
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit4_linux_386.go
generated
vendored
Normal file
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit4_linux_386.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.2
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
|
||||
|
||||
func init() {
|
||||
socketcall = socketcallnosplit4
|
||||
}
|
||||
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit7_linux_386.go
generated
vendored
Normal file
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit7_linux_386.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.1,!go1.2
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
|
||||
|
||||
func init() {
|
||||
socketcall = socketcallnosplit7
|
||||
}
|
||||
26
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_unix.go
generated
vendored
Normal file
26
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_unix.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux,amd64 linux,arm netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func getsockopt(fd int, level, name int, v uintptr, l *sysSockoptLen) error {
|
||||
if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setsockopt(fd int, level int, name int, v uintptr, l uintptr) error {
|
||||
if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
149
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicast_test.go
generated
vendored
149
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicast_test.go
generated
vendored
@@ -5,89 +5,18 @@
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
|
||||
c, err := net.ListenPacket("udp6", "[::1]:0")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
c.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
return c, dst, nil
|
||||
}
|
||||
|
||||
func BenchmarkReadWriteNetUDP(b *testing.B) {
|
||||
c, dst, err := benchmarkUDPListener()
|
||||
if err != nil {
|
||||
b.Fatalf("benchmarkUDPListener failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
|
||||
if _, err := c.WriteTo(wb, dst); err != nil {
|
||||
b.Fatalf("net.PacketConn.WriteTo failed: %v", err)
|
||||
}
|
||||
if _, _, err := c.ReadFrom(rb); err != nil {
|
||||
b.Fatalf("net.PacketConn.ReadFrom failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReadWriteIPv6UDP(b *testing.B) {
|
||||
c, dst, err := benchmarkUDPListener()
|
||||
if err != nil {
|
||||
b.Fatalf("benchmarkUDPListener failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
if err := p.SetControlMessage(cf, true); err != nil {
|
||||
b.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
ifi := loopbackInterface()
|
||||
|
||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
HopLimit: 1,
|
||||
}
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
if _, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
b.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
}
|
||||
if _, _, _, err := p.ReadFrom(rb); err != nil {
|
||||
b.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -99,33 +28,47 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
|
||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("net.ResolveUDPAddr failed: %v", err)
|
||||
}
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
Dst: net.IPv6loopback,
|
||||
}
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
ifi := loopbackInterface()
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
wb := []byte("HELLO-R-U-THERE")
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
cm.HopLimit = i + 1
|
||||
if _, err := p.WriteTo([]byte("HELLO-R-U-THERE"), &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
|
||||
}
|
||||
b := make([]byte, 128)
|
||||
if _, cm, _, err := p.ReadFrom(b); err != nil {
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetReadDeadline failed: %v", err)
|
||||
}
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
} else if !bytes.Equal(rb[:n], wb) {
|
||||
t.Fatalf("got %v; expected %v", rb[:n], wb)
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
}
|
||||
@@ -134,7 +77,7 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
||||
|
||||
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -149,15 +92,21 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
|
||||
dst, err := net.ResolveIPAddr("ip6", "::1")
|
||||
if err != nil {
|
||||
t.Fatalf("net.ResolveIPAddr failed: %v", err)
|
||||
}
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
cm := ipv6.ControlMessage{TrafficClass: DiffServAF11 | CongestionExperienced}
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
pshicmp := ipv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP, ianaProtocolIPv6ICMP)
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
Dst: net.IPv6loopback,
|
||||
}
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
ifi := loopbackInterface()
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
@@ -170,14 +119,26 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
||||
t.Fatalf("ipv6.PacketConn.SetICMPFilter failed: %v", err)
|
||||
}
|
||||
|
||||
var psh []byte
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if toggle {
|
||||
psh = nil
|
||||
if err := p.SetChecksum(true, 2); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetChecksum failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
psh = pshicmp
|
||||
// Some platforms never allow to disable the
|
||||
// kernel checksum processing.
|
||||
p.SetChecksum(false, -1)
|
||||
}
|
||||
wb, err := (&icmpMessage{
|
||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
||||
Body: &icmpEcho{
|
||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
||||
Data: []byte("HELLO-R-U-THERE"),
|
||||
},
|
||||
}).Marshal()
|
||||
}).Marshal(psh)
|
||||
if err != nil {
|
||||
t.Fatalf("icmpMessage.Marshal failed: %v", err)
|
||||
}
|
||||
@@ -185,15 +146,23 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
||||
t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
cm.HopLimit = i + 1
|
||||
if _, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
|
||||
}
|
||||
b := make([]byte, 128)
|
||||
if n, cm, _, err := p.ReadFrom(b); err != nil {
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetReadDeadline failed: %v", err)
|
||||
}
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
if m, err := parseICMPMessage(b[:n]); err != nil {
|
||||
if m, err := parseICMPMessage(rb[:n]); err != nil {
|
||||
t.Fatalf("parseICMPMessage failed: %v", err)
|
||||
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
|
||||
t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
|
||||
|
||||
4
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicastsockopt_test.go
generated
vendored
4
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicastsockopt_test.go
generated
vendored
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
func TestConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
@@ -50,7 +50,7 @@ var packetConnUnicastSocketOptionTests = []struct {
|
||||
|
||||
func TestPacketConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
||||
Reference in New Issue
Block a user