mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 19:08:58 +00:00
Use IPv4 multicast discovery
This commit is contained in:
parent
17a21102b3
commit
3700eb1e61
7
Godeps/Godeps.json
generated
7
Godeps/Godeps.json
generated
@ -1,15 +1,10 @@
|
|||||||
{
|
{
|
||||||
"ImportPath": "github.com/calmh/syncthing",
|
"ImportPath": "github.com/calmh/syncthing",
|
||||||
"GoVersion": "devel +3ca54dd30864 Sat Mar 22 11:05:40 2014 -0700",
|
"GoVersion": "go1.2.1",
|
||||||
"Packages": [
|
"Packages": [
|
||||||
"./cmd/syncthing"
|
"./cmd/syncthing"
|
||||||
],
|
],
|
||||||
"Deps": [
|
"Deps": [
|
||||||
{
|
|
||||||
"ImportPath": "code.google.com/p/go.net/ipv6",
|
|
||||||
"Comment": "null-117",
|
|
||||||
"Rev": "c17ad62118ea511e1051721b429779fa40bddc74"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "code.google.com/p/go.text/transform",
|
"ImportPath": "code.google.com/p/go.text/transform",
|
||||||
"Comment": "null-81",
|
"Comment": "null-81",
|
||||||
|
83
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control.go
generated
vendored
83
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control.go
generated
vendored
@ -1,83 +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 (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
errMissingAddress = errors.New("missing address")
|
|
||||||
errInvalidConnType = errors.New("invalid conn type")
|
|
||||||
errNoSuchInterface = errors.New("no such interface")
|
|
||||||
)
|
|
||||||
|
|
||||||
// References:
|
|
||||||
//
|
|
||||||
// RFC 2292 Advanced Sockets API for IPv6
|
|
||||||
// http://tools.ietf.org/html/rfc2292
|
|
||||||
// RFC 2460 Internet Protocol, Version 6 (IPv6) Specification
|
|
||||||
// http://tools.ietf.org/html/rfc2460
|
|
||||||
// RFC 3493 Basic Socket Interface Extensions for IPv6
|
|
||||||
// http://tools.ietf.org/html/rfc3493.html
|
|
||||||
// RFC 3542 Advanced Sockets Application Program Interface (API) for IPv6
|
|
||||||
// http://tools.ietf.org/html/rfc3542
|
|
||||||
//
|
|
||||||
// Note that RFC 3542 obsoltes RFC 2292 but OS X Snow Leopard and the
|
|
||||||
// former still support RFC 2292 only. Please be aware that almost
|
|
||||||
// all protocol implementations prohibit using a combination of RFC
|
|
||||||
// 2292 and RFC 3542 for some practical reasons.
|
|
||||||
|
|
||||||
type rawOpt struct {
|
|
||||||
sync.Mutex
|
|
||||||
cflags ControlFlags
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *rawOpt) set(f ControlFlags) { c.cflags |= f }
|
|
||||||
func (c *rawOpt) clear(f ControlFlags) { c.cflags &^= f }
|
|
||||||
func (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 }
|
|
||||||
|
|
||||||
// A ControlFlags reprensents per packet basis IP-level socket option
|
|
||||||
// control flags.
|
|
||||||
type ControlFlags uint
|
|
||||||
|
|
||||||
const (
|
|
||||||
FlagTrafficClass ControlFlags = 1 << iota // pass the traffic class on the received packet
|
|
||||||
FlagHopLimit // pass the hop limit on the received packet
|
|
||||||
FlagSrc // pass the source address on the received packet
|
|
||||||
FlagDst // pass the destination address on the received packet
|
|
||||||
FlagInterface // pass the interface index on the received packet
|
|
||||||
FlagPathMTU // pass the path MTU on the received packet path
|
|
||||||
)
|
|
||||||
|
|
||||||
// A ControlMessage represents per packet basis IP-level socket
|
|
||||||
// options.
|
|
||||||
type ControlMessage struct {
|
|
||||||
// Receiving socket options: SetControlMessage allows to
|
|
||||||
// receive the options from the protocol stack using ReadFrom
|
|
||||||
// method of PacketConn.
|
|
||||||
//
|
|
||||||
// Specifying socket options: ControlMessage for WriteTo
|
|
||||||
// method of PacketConn allows to send the options to the
|
|
||||||
// protocol stack.
|
|
||||||
//
|
|
||||||
TrafficClass int // traffic class, must be 1 <= value <= 255 when specifying
|
|
||||||
HopLimit int // hop limit, must be 1 <= value <= 255 when specifying
|
|
||||||
Src net.IP // source address, specifying only
|
|
||||||
Dst net.IP // destination address, receiving only
|
|
||||||
IfIndex int // interface index, must be 1 <= value when specifying
|
|
||||||
NextHop net.IP // next hop address, specifying only
|
|
||||||
MTU int // path MTU, receiving only
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cm *ControlMessage) String() string {
|
|
||||||
if cm == nil {
|
|
||||||
return "<nil>"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("tclass: %#x, hoplim: %v, src: %v, dst: %v, ifindex: %v, nexthop: %v, mtu: %v", cm.TrafficClass, cm.HopLimit, cm.Src, cm.Dst, cm.IfIndex, cm.NextHop, cm.MTU)
|
|
||||||
}
|
|
151
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc2292_unix.go
generated
vendored
151
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc2292_unix.go
generated
vendored
@ -1,151 +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 darwin
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const pktinfo = FlagDst | FlagInterface
|
|
||||||
|
|
||||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
|
||||||
opt.Lock()
|
|
||||||
defer opt.Unlock()
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
|
||||||
opt.Lock()
|
|
||||||
defer opt.Unlock()
|
|
||||||
l, off := 0, 0
|
|
||||||
if opt.isset(FlagHopLimit) {
|
|
||||||
l += syscall.CmsgSpace(4)
|
|
||||||
}
|
|
||||||
if opt.isset(pktinfo) {
|
|
||||||
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 = 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 = sysSockopt2292PacketInfo
|
|
||||||
m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
|
|
||||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 sysSockopt2292HopLimit:
|
|
||||||
cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
|
||||||
case sysSockopt2292PacketInfo:
|
|
||||||
pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
|
|
||||||
cm.IfIndex = int(pi.IfIndex)
|
|
||||||
cm.Dst = pi.IP[:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cm, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
|
||||||
if cm == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
l, off := 0, 0
|
|
||||||
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(sysSizeofPacketInfo)
|
|
||||||
}
|
|
||||||
if len(cm.NextHop) == net.IPv6len {
|
|
||||||
l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
|
||||||
}
|
|
||||||
if l > 0 {
|
|
||||||
oob = make([]byte, l)
|
|
||||||
if cm.HopLimit > 0 {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
|
||||||
m.Level = ianaProtocolIPv6
|
|
||||||
m.Type = sysSockopt2292HopLimit
|
|
||||||
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 = 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.IP[:], ip)
|
|
||||||
}
|
|
||||||
if cm.IfIndex != 0 {
|
|
||||||
pi.IfIndex = uint32(cm.IfIndex)
|
|
||||||
}
|
|
||||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
|
||||||
}
|
|
||||||
if len(cm.NextHop) == net.IPv6len {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
|
||||||
m.Level = ianaProtocolIPv6
|
|
||||||
m.Type = sysSockopt2292NextHop
|
|
||||||
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
|
|
||||||
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
|
||||||
setSockaddr(sa, cm.NextHop, cm.IfIndex)
|
|
||||||
off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
27
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_stub.go
generated
vendored
27
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_stub.go
generated
vendored
@ -1,27 +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 dragonfly plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return nil, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return nil
|
|
||||||
}
|
|
210
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_unix.go
generated
vendored
210
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_unix.go
generated
vendored
@ -1,210 +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 linux netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
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(sysSizeofPacketInfo)
|
|
||||||
}
|
|
||||||
if opt.isset(FlagPathMTU) {
|
|
||||||
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 = 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 = 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 = 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 = sysSockoptReceivePathMTU
|
|
||||||
m.SetLen(syscall.CmsgLen(sysSizeofMTUInfo))
|
|
||||||
off += syscall.CmsgSpace(sysSizeofMTUInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 sysSockoptTrafficClass:
|
|
||||||
cm.TrafficClass = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
|
||||||
case sysSockoptHopLimit:
|
|
||||||
cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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(sysSizeofPacketInfo)
|
|
||||||
}
|
|
||||||
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 = sysSockoptTrafficClass
|
|
||||||
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 = sysSockoptHopLimit
|
|
||||||
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 = 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.IP[:], ip)
|
|
||||||
}
|
|
||||||
if cm.IfIndex != 0 {
|
|
||||||
pi.IfIndex = uint32(cm.IfIndex)
|
|
||||||
}
|
|
||||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
|
||||||
}
|
|
||||||
if len(cm.NextHop) == net.IPv6len {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
|
||||||
m.Level = ianaProtocolIPv6
|
|
||||||
m.Type = sysSockoptNextHop
|
|
||||||
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
|
|
||||||
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
|
||||||
setSockaddr(sa, cm.NextHop, cm.IfIndex)
|
|
||||||
off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
27
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_windows.go
generated
vendored
27
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_windows.go
generated
vendored
@ -1,27 +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 "syscall"
|
|
||||||
|
|
||||||
func setControlMessage(fd syscall.Handle, opt *rawOpt, cf ControlFlags, on bool) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return nil, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return nil
|
|
||||||
}
|
|
178
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/dgramopt_posix.go
generated
vendored
178
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/dgramopt_posix.go
generated
vendored
@ -1,178 +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 darwin freebsd linux netbsd openbsd windows
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MulticastHopLimit returns the hop limit field value for outgoing
|
|
||||||
// multicast packets.
|
|
||||||
func (c *dgramOpt) MulticastHopLimit() (int, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return ipv6MulticastHopLimit(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMulticastHopLimit sets the hop limit field value for future
|
|
||||||
// outgoing multicast packets.
|
|
||||||
func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setIPv6MulticastHopLimit(fd, hoplim)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MulticastInterface returns the default interface for multicast
|
|
||||||
// packet transmissions.
|
|
||||||
func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return nil, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ipv6MulticastInterface(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMulticastInterface sets the default interface for future
|
|
||||||
// multicast packet transmissions.
|
|
||||||
func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setIPv6MulticastInterface(fd, ifi)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MulticastLoopback reports whether transmitted multicast packets
|
|
||||||
// should be copied and send back to the originator.
|
|
||||||
func (c *dgramOpt) MulticastLoopback() (bool, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return false, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return ipv6MulticastLoopback(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMulticastLoopback sets whether transmitted multicast packets
|
|
||||||
// should be copied and send back to the originator.
|
|
||||||
func (c *dgramOpt) SetMulticastLoopback(on bool) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setIPv6MulticastLoopback(fd, on)
|
|
||||||
}
|
|
||||||
|
|
||||||
// JoinGroup joins the group address group on the interface ifi.
|
|
||||||
// It uses the system assigned multicast interface when ifi is nil,
|
|
||||||
// although this is not recommended because the assignment depends on
|
|
||||||
// platforms and sometimes it might require routing configuration.
|
|
||||||
func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
grp := netAddrToIP16(group)
|
|
||||||
if grp == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
return joinIPv6Group(fd, ifi, grp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LeaveGroup leaves the group address group on the interface ifi.
|
|
||||||
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
grp := netAddrToIP16(group)
|
|
||||||
if grp == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
return leaveIPv6Group(fd, ifi, grp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checksum reports whether the kernel will compute, store or verify a
|
|
||||||
// checksum for both incoming and outgoing packets. If on is true, it
|
|
||||||
// returns an offset in bytes into the data of where the checksum
|
|
||||||
// field is located.
|
|
||||||
func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return false, 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return false, 0, err
|
|
||||||
}
|
|
||||||
return ipv6Checksum(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChecksum enables the kernel checksum processing. If on is ture,
|
|
||||||
// the offset should be an offset in bytes into the data of where the
|
|
||||||
// checksum field is located.
|
|
||||||
func (c *dgramOpt) SetChecksum(on bool, offset int) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setIPv6Checksum(fd, on, offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ICMPFilter returns an ICMP filter.
|
|
||||||
func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return nil, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ipv6ICMPFilter(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetICMPFilter deploys the ICMP filter.
|
|
||||||
func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setIPv6ICMPFilter(fd, f)
|
|
||||||
}
|
|
95
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/dgramopt_stub.go
generated
vendored
95
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/dgramopt_stub.go
generated
vendored
@ -1,95 +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 dragonfly plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
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, 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 errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// MulticastInterface returns the default interface for multicast
|
|
||||||
// packet transmissions.
|
|
||||||
func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
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 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, 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 errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// JoinGroup joins the group address group on the interface ifi.
|
|
||||||
// It uses the system assigned multicast interface when ifi is nil,
|
|
||||||
// although this is not recommended because the assignment depends on
|
|
||||||
// platforms and sometimes it might require routing configuration.
|
|
||||||
func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
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 errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checksum reports whether the kernel will compute, store or verify a
|
|
||||||
// checksum for both incoming and outgoing packets. If on is true, it
|
|
||||||
// returns an offset in bytes into the data of where the checksum
|
|
||||||
// field is located.
|
|
||||||
func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return false, 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChecksum enables the kernel checksum processing. If on is ture,
|
|
||||||
// the offset should be an offset in bytes into the data of where the
|
|
||||||
// checksum field is located.
|
|
||||||
func (c *dgramOpt) SetChecksum(on bool, offset int) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// ICMPFilter returns an ICMP filter.
|
|
||||||
func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return nil, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetICMPFilter deploys the ICMP filter.
|
|
||||||
func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
193
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/doc.go
generated
vendored
193
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/doc.go
generated
vendored
@ -1,193 +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 implements IP-level socket options for the Internet
|
|
||||||
// Protocol version 6.
|
|
||||||
//
|
|
||||||
// The package provides IP-level socket options that allow
|
|
||||||
// manipulation of IPv6 facilities. The IPv6 and socket options for
|
|
||||||
// IPv6 are defined in RFC 2460, RFC 3493 and RFC 3542.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Unicasting
|
|
||||||
//
|
|
||||||
// The options for unicasting are available for net.TCPConn,
|
|
||||||
// net.UDPConn and net.IPConn which are created as network connections
|
|
||||||
// that use the IPv6 transport. When a single TCP connection carrying
|
|
||||||
// a data flow of multiple packets needs to indicate the flow is
|
|
||||||
// important, ipv6.Conn is used to set the traffic class field on the
|
|
||||||
// IPv6 header for each packet.
|
|
||||||
//
|
|
||||||
// ln, err := net.Listen("tcp6", "[::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer ln.Close()
|
|
||||||
// for {
|
|
||||||
// c, err := ln.Accept()
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// go func(c net.Conn) {
|
|
||||||
// defer c.Close()
|
|
||||||
//
|
|
||||||
// The outgoing packets will be labeled DiffServ assured forwarding
|
|
||||||
// class 1 low drop precedence, as known as AF11 packets.
|
|
||||||
//
|
|
||||||
// if err := ipv6.NewConn(c).SetTrafficClass(DiffServAF11); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if _, err := c.Write(data); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// }(c)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Multicasting
|
|
||||||
//
|
|
||||||
// The options for multicasting are available for net.UDPConn and
|
|
||||||
// net.IPconn which are created as network connections that use the
|
|
||||||
// IPv6 transport. A few network facilities must be prepared before
|
|
||||||
// you begin multicasting, at a minimum joining network interfaces and
|
|
||||||
// multicast groups.
|
|
||||||
//
|
|
||||||
// en0, err := net.InterfaceByName("en0")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// en1, err := net.InterfaceByIndex(911)
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// group := net.ParseIP("ff02::114")
|
|
||||||
//
|
|
||||||
// First, an application listens to an appropriate address with an
|
|
||||||
// appropriate service port.
|
|
||||||
//
|
|
||||||
// c, err := net.ListenPacket("udp6", "[::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer c.Close()
|
|
||||||
//
|
|
||||||
// Second, the application joins multicast groups, starts listening to
|
|
||||||
// the groups on the specified network interfaces. Note that the
|
|
||||||
// service port for transport layer protocol does not matter with this
|
|
||||||
// operation as joining groups affects only network and link layer
|
|
||||||
// protocols, such as IPv6 and Ethernet.
|
|
||||||
//
|
|
||||||
// p := ipv6.NewPacketConn(c)
|
|
||||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The application might set per packet control message transmissions
|
|
||||||
// between the protocol stack within the kernel. When the application
|
|
||||||
// needs a destination address on an incoming packet,
|
|
||||||
// SetControlMessage of ipv6.PacketConn is used to enable control
|
|
||||||
// message transmissons.
|
|
||||||
//
|
|
||||||
// if err := p.SetControlMessage(ipv6.FlagDst, true); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The application could identify whether the received packets are
|
|
||||||
// of interest by using the control message that contains the
|
|
||||||
// destination address of the received packet.
|
|
||||||
//
|
|
||||||
// b := make([]byte, 1500)
|
|
||||||
// for {
|
|
||||||
// n, rcm, src, err := p.ReadFrom(b)
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if rcm.Dst.IsMulticast() {
|
|
||||||
// if rcm.Dst.Equal(group)
|
|
||||||
// // joined group, do something
|
|
||||||
// } else {
|
|
||||||
// // unknown group, discard
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The application can also send both unicast and multicast packets.
|
|
||||||
//
|
|
||||||
// p.SetTrafficClass(DiffServCS0)
|
|
||||||
// p.SetHopLimit(16)
|
|
||||||
// if _, err := p.WriteTo(data[:n], nil, src); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// dst := &net.UDPAddr{IP: group, Port: 1024}
|
|
||||||
// wcm := ipv6.ControlMessage{TrafficClass: DiffServCS7, HopLimit: 1}
|
|
||||||
// for _, ifi := range []*net.Interface{en0, en1} {
|
|
||||||
// wcm.IfIndex = ifi.Index
|
|
||||||
// if _, err := p.WriteTo(data[:n], &wcm, dst); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// More multicasting
|
|
||||||
//
|
|
||||||
// An application that uses PacketConn may join multiple multicast
|
|
||||||
// groups. For example, a UDP listener with port 1024 might join two
|
|
||||||
// different groups across over two different network interfaces by
|
|
||||||
// using:
|
|
||||||
//
|
|
||||||
// c, err := net.ListenPacket("udp6", "[::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer c.Close()
|
|
||||||
// p := ipv6.NewPacketConn(c)
|
|
||||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::1:114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.JoinGroup(en1, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// It is possible for multiple UDP listeners that listen on the same
|
|
||||||
// UDP port to join the same multicast group. The net package will
|
|
||||||
// provide a socket that listens to a wildcard address with reusable
|
|
||||||
// UDP port when an appropriate multicast address prefix is passed to
|
|
||||||
// the net.ListenPacket or net.ListenUDP.
|
|
||||||
//
|
|
||||||
// c1, err := net.ListenPacket("udp6", "[ff02::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer c1.Close()
|
|
||||||
// c2, err := net.ListenPacket("udp6", "[ff02::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer c2.Close()
|
|
||||||
// p1 := ipv6.NewPacketConn(c1)
|
|
||||||
// if err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// p2 := ipv6.NewPacketConn(c2)
|
|
||||||
// if err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Also it is possible for the application to leave or rejoin a
|
|
||||||
// multicast group on the network interface.
|
|
||||||
//
|
|
||||||
// if err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff01::114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
package ipv6
|
|
119
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/endpoint.go
generated
vendored
119
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/endpoint.go
generated
vendored
@ -1,119 +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"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Conn represents a network endpoint that uses IPv6 transport.
|
|
||||||
// It allows to set basic IP-level socket options such as traffic
|
|
||||||
// class and hop limit.
|
|
||||||
type Conn struct {
|
|
||||||
genericOpt
|
|
||||||
}
|
|
||||||
|
|
||||||
type genericOpt struct {
|
|
||||||
net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
|
|
||||||
|
|
||||||
// PathMTU returns a path MTU value for the destination associated
|
|
||||||
// with the endpoint.
|
|
||||||
func (c *Conn) PathMTU() (int, error) {
|
|
||||||
if !c.genericOpt.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.genericOpt.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return ipv6PathMTU(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewConn returns a new Conn.
|
|
||||||
func NewConn(c net.Conn) *Conn {
|
|
||||||
return &Conn{
|
|
||||||
genericOpt: genericOpt{Conn: c},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A PacketConn represents a packet network endpoint that uses IPv6
|
|
||||||
// transport. It is used to control several IP-level socket options
|
|
||||||
// including IPv6 header manipulation. It also provides datagram
|
|
||||||
// based network I/O methods specific to the IPv6 and higher layer
|
|
||||||
// protocols such as OSPF, GRE, and UDP.
|
|
||||||
type PacketConn struct {
|
|
||||||
genericOpt
|
|
||||||
dgramOpt
|
|
||||||
payloadHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
type dgramOpt struct {
|
|
||||||
net.PacketConn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dgramOpt) ok() bool { return c != nil && c.PacketConn != nil }
|
|
||||||
|
|
||||||
// SetControlMessage allows to receive the per packet basis IP-level
|
|
||||||
// socket options.
|
|
||||||
func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.payloadHandler.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setControlMessage(fd, &c.payloadHandler.rawOpt, cf, on)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDeadline sets the read and write deadlines associated with the
|
|
||||||
// endpoint.
|
|
||||||
func (c *PacketConn) SetDeadline(t time.Time) error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
return c.payloadHandler.SetDeadline(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetReadDeadline sets the read deadline associated with the
|
|
||||||
// endpoint.
|
|
||||||
func (c *PacketConn) SetReadDeadline(t time.Time) error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
return c.payloadHandler.SetReadDeadline(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetWriteDeadline sets the write deadline associated with the
|
|
||||||
// endpoint.
|
|
||||||
func (c *PacketConn) SetWriteDeadline(t time.Time) error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
return c.payloadHandler.SetWriteDeadline(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the endpoint.
|
|
||||||
func (c *PacketConn) Close() error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
return c.payloadHandler.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPacketConn returns a new PacketConn using c as its underlying
|
|
||||||
// transport.
|
|
||||||
func NewPacketConn(c net.PacketConn) *PacketConn {
|
|
||||||
return &PacketConn{
|
|
||||||
genericOpt: genericOpt{Conn: c.(net.Conn)},
|
|
||||||
dgramOpt: dgramOpt{PacketConn: c},
|
|
||||||
payloadHandler: payloadHandler{PacketConn: c},
|
|
||||||
}
|
|
||||||
}
|
|
241
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/gen.go
generated
vendored
241
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/gen.go
generated
vendored
@ -1,241 +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 ignore
|
|
||||||
|
|
||||||
// This program generates internet protocol constatns and tables by
|
|
||||||
// reading IANA protocol registries.
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// go run gen.go > iana.go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"go/format"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var registries = []struct {
|
|
||||||
url string
|
|
||||||
parse func(io.Writer, io.Reader) error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xml",
|
|
||||||
parseICMPv6Parameters,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml",
|
|
||||||
parseProtocolNumbers,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var bb bytes.Buffer
|
|
||||||
fmt.Fprintf(&bb, "// go run gen.go\n")
|
|
||||||
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
|
|
||||||
fmt.Fprintf(&bb, "package ipv6\n\n")
|
|
||||||
for _, r := range registries {
|
|
||||||
resp, err := http.Get(r.url)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if err := r.parse(&bb, resp.Body); err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(&bb, "\n")
|
|
||||||
}
|
|
||||||
b, err := format.Source(bb.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
os.Stdout.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseICMPv6Parameters(w io.Writer, r io.Reader) error {
|
|
||||||
dec := xml.NewDecoder(r)
|
|
||||||
var icp icmpv6Parameters
|
|
||||||
if err := dec.Decode(&icp); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
prs := icp.escape()
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
|
|
||||||
fmt.Fprintf(w, "const (\n")
|
|
||||||
for _, pr := range prs {
|
|
||||||
if pr.Name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Name, pr.Value)
|
|
||||||
fmt.Fprintf(w, "// %s\n", pr.OrigName)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, ")\n\n")
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
|
|
||||||
fmt.Fprintf(w, "var icmpTypes = map[ICMPType]string{\n")
|
|
||||||
for _, pr := range prs {
|
|
||||||
if pr.Name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigName))
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "}\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type icmpv6Parameters struct {
|
|
||||||
XMLName xml.Name `xml:"registry"`
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Updated string `xml:"updated"`
|
|
||||||
Registries []struct {
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Records []struct {
|
|
||||||
Value string `xml:"value"`
|
|
||||||
Name string `xml:"name"`
|
|
||||||
} `xml:"record"`
|
|
||||||
} `xml:"registry"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type canonICMPv6ParamRecord struct {
|
|
||||||
OrigName string
|
|
||||||
Name string
|
|
||||||
Value int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (icp *icmpv6Parameters) escape() []canonICMPv6ParamRecord {
|
|
||||||
id := -1
|
|
||||||
for i, r := range icp.Registries {
|
|
||||||
if strings.Contains(r.Title, "Type") || strings.Contains(r.Title, "type") {
|
|
||||||
id = i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if id < 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
prs := make([]canonICMPv6ParamRecord, len(icp.Registries[id].Records))
|
|
||||||
sr := strings.NewReplacer(
|
|
||||||
"Messages", "",
|
|
||||||
"Message", "",
|
|
||||||
"ICMP", "",
|
|
||||||
"+", "P",
|
|
||||||
"-", "",
|
|
||||||
"/", "",
|
|
||||||
".", "",
|
|
||||||
" ", "",
|
|
||||||
)
|
|
||||||
for i, pr := range icp.Registries[id].Records {
|
|
||||||
if strings.Contains(pr.Name, "Reserved") ||
|
|
||||||
strings.Contains(pr.Name, "Unassigned") ||
|
|
||||||
strings.Contains(pr.Name, "Deprecated") ||
|
|
||||||
strings.Contains(pr.Name, "Experiment") ||
|
|
||||||
strings.Contains(pr.Name, "experiment") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ss := strings.Split(pr.Name, "\n")
|
|
||||||
if len(ss) > 1 {
|
|
||||||
prs[i].Name = strings.Join(ss, " ")
|
|
||||||
} else {
|
|
||||||
prs[i].Name = ss[0]
|
|
||||||
}
|
|
||||||
s := strings.TrimSpace(prs[i].Name)
|
|
||||||
prs[i].OrigName = s
|
|
||||||
prs[i].Name = sr.Replace(s)
|
|
||||||
prs[i].Value, _ = strconv.Atoi(pr.Value)
|
|
||||||
}
|
|
||||||
return prs
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseProtocolNumbers(w io.Writer, r io.Reader) error {
|
|
||||||
dec := xml.NewDecoder(r)
|
|
||||||
var pn protocolNumbers
|
|
||||||
if err := dec.Decode(&pn); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
prs := pn.escape()
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", pn.Title, pn.Updated)
|
|
||||||
fmt.Fprintf(w, "const (\n")
|
|
||||||
for _, pr := range prs {
|
|
||||||
if pr.Name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "ianaProtocol%s = %d", pr.Name, pr.Value)
|
|
||||||
s := pr.Descr
|
|
||||||
if s == "" {
|
|
||||||
s = pr.OrigName
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "// %s\n", s)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, ")\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type protocolNumbers struct {
|
|
||||||
XMLName xml.Name `xml:"registry"`
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Updated string `xml:"updated"`
|
|
||||||
RegTitle string `xml:"registry>title"`
|
|
||||||
Note string `xml:"registry>note"`
|
|
||||||
Records []struct {
|
|
||||||
Value string `xml:"value"`
|
|
||||||
Name string `xml:"name"`
|
|
||||||
Descr string `xml:"description"`
|
|
||||||
} `xml:"registry>record"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type canonProtocolRecord struct {
|
|
||||||
OrigName string
|
|
||||||
Name string
|
|
||||||
Descr string
|
|
||||||
Value int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pn *protocolNumbers) escape() []canonProtocolRecord {
|
|
||||||
prs := make([]canonProtocolRecord, len(pn.Records))
|
|
||||||
sr := strings.NewReplacer(
|
|
||||||
"-in-", "in",
|
|
||||||
"-within-", "within",
|
|
||||||
"-over-", "over",
|
|
||||||
"+", "P",
|
|
||||||
"-", "",
|
|
||||||
"/", "",
|
|
||||||
".", "",
|
|
||||||
" ", "",
|
|
||||||
)
|
|
||||||
for i, pr := range pn.Records {
|
|
||||||
prs[i].OrigName = pr.Name
|
|
||||||
s := strings.TrimSpace(pr.Name)
|
|
||||||
switch pr.Name {
|
|
||||||
case "ISIS over IPv4":
|
|
||||||
prs[i].Name = "ISIS"
|
|
||||||
case "manet":
|
|
||||||
prs[i].Name = "MANET"
|
|
||||||
default:
|
|
||||||
prs[i].Name = sr.Replace(s)
|
|
||||||
}
|
|
||||||
ss := strings.Split(pr.Descr, "\n")
|
|
||||||
for i := range ss {
|
|
||||||
ss[i] = strings.TrimSpace(ss[i])
|
|
||||||
}
|
|
||||||
if len(ss) > 1 {
|
|
||||||
prs[i].Descr = strings.Join(ss, " ")
|
|
||||||
} else {
|
|
||||||
prs[i].Descr = ss[0]
|
|
||||||
}
|
|
||||||
prs[i].Value, _ = strconv.Atoi(pr.Value)
|
|
||||||
}
|
|
||||||
return prs
|
|
||||||
}
|
|
60
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/genericopt_posix.go
generated
vendored
60
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/genericopt_posix.go
generated
vendored
@ -1,60 +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 darwin freebsd linux netbsd openbsd windows
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
// TrafficClass returns the traffic class field value for outgoing
|
|
||||||
// packets.
|
|
||||||
func (c *genericOpt) TrafficClass() (int, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return ipv6TrafficClass(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTrafficClass sets the traffic class field value for future
|
|
||||||
// outgoing packets.
|
|
||||||
func (c *genericOpt) SetTrafficClass(tclass int) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setIPv6TrafficClass(fd, tclass)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HopLimit returns the hop limit field value for outgoing packets.
|
|
||||||
func (c *genericOpt) HopLimit() (int, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return ipv6HopLimit(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetHopLimit sets the hop limit field value for future outgoing
|
|
||||||
// packets.
|
|
||||||
func (c *genericOpt) SetHopLimit(hoplim int) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setIPv6HopLimit(fd, hoplim)
|
|
||||||
}
|
|
34
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/genericopt_stub.go
generated
vendored
34
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/genericopt_stub.go
generated
vendored
@ -1,34 +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 dragonfly plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
// TrafficClass returns the traffic class field value for outgoing
|
|
||||||
// packets.
|
|
||||||
func (c *genericOpt) TrafficClass() (int, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
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 errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// HopLimit returns the hop limit field value for outgoing packets.
|
|
||||||
func (c *genericOpt) HopLimit() (int, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
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 errOpNoSupport
|
|
||||||
}
|
|
195
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/gentest.go
generated
vendored
195
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/gentest.go
generated
vendored
@ -1,195 +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 ignore
|
|
||||||
|
|
||||||
// This program generates internet protocol constants by reading IANA
|
|
||||||
// protocol registries.
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// go run gentest.go > iana_test.go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"go/format"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var registries = []struct {
|
|
||||||
url string
|
|
||||||
parse func(io.Writer, io.Reader) error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"http://www.iana.org/assignments/dscp-registry/dscp-registry.xml",
|
|
||||||
parseDSCPRegistry,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"http://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml",
|
|
||||||
parseTOSTCByte,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var bb bytes.Buffer
|
|
||||||
fmt.Fprintf(&bb, "// go run gentest.go\n")
|
|
||||||
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
|
|
||||||
fmt.Fprintf(&bb, "package ipv6_test\n\n")
|
|
||||||
for _, r := range registries {
|
|
||||||
resp, err := http.Get(r.url)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if err := r.parse(&bb, resp.Body); err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(&bb, "\n")
|
|
||||||
}
|
|
||||||
b, err := format.Source(bb.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
os.Stdout.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseDSCPRegistry(w io.Writer, r io.Reader) error {
|
|
||||||
dec := xml.NewDecoder(r)
|
|
||||||
var dr dscpRegistry
|
|
||||||
if err := dec.Decode(&dr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
drs := dr.escape()
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated)
|
|
||||||
fmt.Fprintf(w, "const (\n")
|
|
||||||
for _, dr := range drs {
|
|
||||||
fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value)
|
|
||||||
fmt.Fprintf(w, "// %s\n", dr.OrigName)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, ")\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type dscpRegistry struct {
|
|
||||||
XMLName xml.Name `xml:"registry"`
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Updated string `xml:"updated"`
|
|
||||||
Note string `xml:"note"`
|
|
||||||
RegTitle string `xml:"registry>title"`
|
|
||||||
PoolRecords []struct {
|
|
||||||
Name string `xml:"name"`
|
|
||||||
Space string `xml:"space"`
|
|
||||||
} `xml:"registry>record"`
|
|
||||||
Records []struct {
|
|
||||||
Name string `xml:"name"`
|
|
||||||
Space string `xml:"space"`
|
|
||||||
} `xml:"registry>registry>record"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type canonDSCPRecord struct {
|
|
||||||
OrigName string
|
|
||||||
Name string
|
|
||||||
Value int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (drr *dscpRegistry) escape() []canonDSCPRecord {
|
|
||||||
drs := make([]canonDSCPRecord, len(drr.Records))
|
|
||||||
sr := strings.NewReplacer(
|
|
||||||
"+", "",
|
|
||||||
"-", "",
|
|
||||||
"/", "",
|
|
||||||
".", "",
|
|
||||||
" ", "",
|
|
||||||
)
|
|
||||||
for i, dr := range drr.Records {
|
|
||||||
s := strings.TrimSpace(dr.Name)
|
|
||||||
drs[i].OrigName = s
|
|
||||||
drs[i].Name = sr.Replace(s)
|
|
||||||
n, err := strconv.ParseUint(dr.Space, 2, 8)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
drs[i].Value = int(n) << 2
|
|
||||||
}
|
|
||||||
return drs
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseTOSTCByte(w io.Writer, r io.Reader) error {
|
|
||||||
dec := xml.NewDecoder(r)
|
|
||||||
var ttb tosTCByte
|
|
||||||
if err := dec.Decode(&ttb); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
trs := ttb.escape()
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated)
|
|
||||||
fmt.Fprintf(w, "const (\n")
|
|
||||||
for _, tr := range trs {
|
|
||||||
fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value)
|
|
||||||
fmt.Fprintf(w, "// %s\n", tr.OrigKeyword)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, ")\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type tosTCByte struct {
|
|
||||||
XMLName xml.Name `xml:"registry"`
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Updated string `xml:"updated"`
|
|
||||||
Note string `xml:"note"`
|
|
||||||
RegTitle string `xml:"registry>title"`
|
|
||||||
Records []struct {
|
|
||||||
Binary string `xml:"binary"`
|
|
||||||
Keyword string `xml:"keyword"`
|
|
||||||
} `xml:"registry>record"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type canonTOSTCByteRecord struct {
|
|
||||||
OrigKeyword string
|
|
||||||
Keyword string
|
|
||||||
Value int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ttb *tosTCByte) escape() []canonTOSTCByteRecord {
|
|
||||||
trs := make([]canonTOSTCByteRecord, len(ttb.Records))
|
|
||||||
sr := strings.NewReplacer(
|
|
||||||
"Capable", "",
|
|
||||||
"(", "",
|
|
||||||
")", "",
|
|
||||||
"+", "",
|
|
||||||
"-", "",
|
|
||||||
"/", "",
|
|
||||||
".", "",
|
|
||||||
" ", "",
|
|
||||||
)
|
|
||||||
for i, tr := range ttb.Records {
|
|
||||||
s := strings.TrimSpace(tr.Keyword)
|
|
||||||
trs[i].OrigKeyword = s
|
|
||||||
ss := strings.Split(s, " ")
|
|
||||||
if len(ss) > 1 {
|
|
||||||
trs[i].Keyword = strings.Join(ss[1:], " ")
|
|
||||||
} else {
|
|
||||||
trs[i].Keyword = ss[0]
|
|
||||||
}
|
|
||||||
trs[i].Keyword = sr.Replace(trs[i].Keyword)
|
|
||||||
n, err := strconv.ParseUint(tr.Binary, 2, 8)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
trs[i].Value = int(n)
|
|
||||||
}
|
|
||||||
return trs
|
|
||||||
}
|
|
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper.go
generated
vendored
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper.go
generated
vendored
@ -1,33 +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 (
|
|
||||||
"errors"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
var errOpNoSupport = errors.New("operation not supported")
|
|
||||||
|
|
||||||
func boolint(b bool) int {
|
|
||||||
if b {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func netAddrToIP16(a net.Addr) net.IP {
|
|
||||||
switch v := a.(type) {
|
|
||||||
case *net.UDPAddr:
|
|
||||||
if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
case *net.IPAddr:
|
|
||||||
if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_stub.go
generated
vendored
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_stub.go
generated
vendored
@ -1,22 +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 dragonfly plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
func (c *genericOpt) sysfd() (int, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dgramOpt) sysfd() (int, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *payloadHandler) sysfd() (int, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
46
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_unix.go
generated
vendored
46
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_unix.go
generated
vendored
@ -1,46 +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 darwin freebsd linux netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *genericOpt) sysfd() (int, error) {
|
|
||||||
switch p := c.Conn.(type) {
|
|
||||||
case *net.TCPConn, *net.UDPConn, *net.IPConn:
|
|
||||||
return sysfd(p)
|
|
||||||
}
|
|
||||||
return 0, errInvalidConnType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dgramOpt) sysfd() (int, error) {
|
|
||||||
switch p := c.PacketConn.(type) {
|
|
||||||
case *net.UDPConn, *net.IPConn:
|
|
||||||
return sysfd(p.(net.Conn))
|
|
||||||
}
|
|
||||||
return 0, errInvalidConnType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *payloadHandler) sysfd() (int, error) {
|
|
||||||
return sysfd(c.PacketConn.(net.Conn))
|
|
||||||
}
|
|
||||||
|
|
||||||
func sysfd(c net.Conn) (int, error) {
|
|
||||||
cv := reflect.ValueOf(c)
|
|
||||||
switch ce := cv.Elem(); ce.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
nfd := ce.FieldByName("conn").FieldByName("fd")
|
|
||||||
switch fe := nfd.Elem(); fe.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
fd := fe.FieldByName("sysfd")
|
|
||||||
return int(fd.Int()), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, errInvalidConnType
|
|
||||||
}
|
|
45
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_windows.go
generated
vendored
45
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_windows.go
generated
vendored
@ -1,45 +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"
|
|
||||||
"reflect"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *genericOpt) sysfd() (syscall.Handle, error) {
|
|
||||||
switch p := c.Conn.(type) {
|
|
||||||
case *net.TCPConn, *net.UDPConn, *net.IPConn:
|
|
||||||
return sysfd(p)
|
|
||||||
}
|
|
||||||
return syscall.InvalidHandle, errInvalidConnType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dgramOpt) sysfd() (syscall.Handle, error) {
|
|
||||||
switch p := c.PacketConn.(type) {
|
|
||||||
case *net.UDPConn, *net.IPConn:
|
|
||||||
return sysfd(p.(net.Conn))
|
|
||||||
}
|
|
||||||
return syscall.InvalidHandle, errInvalidConnType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *payloadHandler) sysfd() (syscall.Handle, error) {
|
|
||||||
return sysfd(c.PacketConn.(net.Conn))
|
|
||||||
}
|
|
||||||
|
|
||||||
func sysfd(c net.Conn) (syscall.Handle, error) {
|
|
||||||
cv := reflect.ValueOf(c)
|
|
||||||
switch ce := cv.Elem(); ce.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
netfd := ce.FieldByName("conn").FieldByName("fd")
|
|
||||||
switch fe := netfd.Elem(); fe.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
fd := fe.FieldByName("sysfd")
|
|
||||||
return syscall.Handle(fd.Uint()), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return syscall.InvalidHandle, errInvalidConnType
|
|
||||||
}
|
|
224
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/iana.go
generated
vendored
224
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/iana.go
generated
vendored
@ -1,224 +0,0 @@
|
|||||||
// go run gen.go
|
|
||||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2013-07-03
|
|
||||||
const (
|
|
||||||
ICMPTypeDestinationUnreachable ICMPType = 1 // Destination Unreachable
|
|
||||||
ICMPTypePacketTooBig ICMPType = 2 // Packet Too Big
|
|
||||||
ICMPTypeTimeExceeded ICMPType = 3 // Time Exceeded
|
|
||||||
ICMPTypeParameterProblem ICMPType = 4 // Parameter Problem
|
|
||||||
ICMPTypeEchoRequest ICMPType = 128 // Echo Request
|
|
||||||
ICMPTypeEchoReply ICMPType = 129 // Echo Reply
|
|
||||||
ICMPTypeMulticastListenerQuery ICMPType = 130 // Multicast Listener Query
|
|
||||||
ICMPTypeMulticastListenerReport ICMPType = 131 // Multicast Listener Report
|
|
||||||
ICMPTypeMulticastListenerDone ICMPType = 132 // Multicast Listener Done
|
|
||||||
ICMPTypeRouterSolicitation ICMPType = 133 // Router Solicitation
|
|
||||||
ICMPTypeRouterAdvertisement ICMPType = 134 // Router Advertisement
|
|
||||||
ICMPTypeNeighborSolicitation ICMPType = 135 // Neighbor Solicitation
|
|
||||||
ICMPTypeNeighborAdvertisement ICMPType = 136 // Neighbor Advertisement
|
|
||||||
ICMPTypeRedirect ICMPType = 137 // Redirect Message
|
|
||||||
ICMPTypeRouterRenumbering ICMPType = 138 // Router Renumbering
|
|
||||||
ICMPTypeNodeInformationQuery ICMPType = 139 // ICMP Node Information Query
|
|
||||||
ICMPTypeNodeInformationResponse ICMPType = 140 // ICMP Node Information Response
|
|
||||||
ICMPTypeInverseNeighborDiscoverySolicitation ICMPType = 141 // Inverse Neighbor Discovery Solicitation Message
|
|
||||||
ICMPTypeInverseNeighborDiscoveryAdvertisement ICMPType = 142 // Inverse Neighbor Discovery Advertisement Message
|
|
||||||
ICMPTypeVersion2MulticastListenerReport ICMPType = 143 // Version 2 Multicast Listener Report
|
|
||||||
ICMPTypeHomeAgentAddressDiscoveryRequest ICMPType = 144 // Home Agent Address Discovery Request Message
|
|
||||||
ICMPTypeHomeAgentAddressDiscoveryReply ICMPType = 145 // Home Agent Address Discovery Reply Message
|
|
||||||
ICMPTypeMobilePrefixSolicitation ICMPType = 146 // Mobile Prefix Solicitation
|
|
||||||
ICMPTypeMobilePrefixAdvertisement ICMPType = 147 // Mobile Prefix Advertisement
|
|
||||||
ICMPTypeCertificationPathSolicitation ICMPType = 148 // Certification Path Solicitation Message
|
|
||||||
ICMPTypeCertificationPathAdvertisement ICMPType = 149 // Certification Path Advertisement Message
|
|
||||||
ICMPTypeMulticastRouterAdvertisement ICMPType = 151 // Multicast Router Advertisement
|
|
||||||
ICMPTypeMulticastRouterSolicitation ICMPType = 152 // Multicast Router Solicitation
|
|
||||||
ICMPTypeMulticastRouterTermination ICMPType = 153 // Multicast Router Termination
|
|
||||||
ICMPTypeFMIPv6 ICMPType = 154 // FMIPv6 Messages
|
|
||||||
ICMPTypeRPLControl ICMPType = 155 // RPL Control Message
|
|
||||||
ICMPTypeILNPv6LocatorUpdate ICMPType = 156 // ILNPv6 Locator Update Message
|
|
||||||
ICMPTypeDuplicateAddressRequest ICMPType = 157 // Duplicate Address Request
|
|
||||||
ICMPTypeDuplicateAddressConfirmation ICMPType = 158 // Duplicate Address Confirmation
|
|
||||||
)
|
|
||||||
|
|
||||||
// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2013-07-03
|
|
||||||
var icmpTypes = map[ICMPType]string{
|
|
||||||
1: "destination unreachable",
|
|
||||||
2: "packet too big",
|
|
||||||
3: "time exceeded",
|
|
||||||
4: "parameter problem",
|
|
||||||
128: "echo request",
|
|
||||||
129: "echo reply",
|
|
||||||
130: "multicast listener query",
|
|
||||||
131: "multicast listener report",
|
|
||||||
132: "multicast listener done",
|
|
||||||
133: "router solicitation",
|
|
||||||
134: "router advertisement",
|
|
||||||
135: "neighbor solicitation",
|
|
||||||
136: "neighbor advertisement",
|
|
||||||
137: "redirect message",
|
|
||||||
138: "router renumbering",
|
|
||||||
139: "icmp node information query",
|
|
||||||
140: "icmp node information response",
|
|
||||||
141: "inverse neighbor discovery solicitation message",
|
|
||||||
142: "inverse neighbor discovery advertisement message",
|
|
||||||
143: "version 2 multicast listener report",
|
|
||||||
144: "home agent address discovery request message",
|
|
||||||
145: "home agent address discovery reply message",
|
|
||||||
146: "mobile prefix solicitation",
|
|
||||||
147: "mobile prefix advertisement",
|
|
||||||
148: "certification path solicitation message",
|
|
||||||
149: "certification path advertisement message",
|
|
||||||
151: "multicast router advertisement",
|
|
||||||
152: "multicast router solicitation",
|
|
||||||
153: "multicast router termination",
|
|
||||||
154: "fmipv6 messages",
|
|
||||||
155: "rpl control message",
|
|
||||||
156: "ilnpv6 locator update message",
|
|
||||||
157: "duplicate address request",
|
|
||||||
158: "duplicate address confirmation",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protocol Numbers, Updated: 2013-02-17
|
|
||||||
const (
|
|
||||||
ianaProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option
|
|
||||||
ianaProtocolICMP = 1 // Internet Control Message
|
|
||||||
ianaProtocolIGMP = 2 // Internet Group Management
|
|
||||||
ianaProtocolGGP = 3 // Gateway-to-Gateway
|
|
||||||
ianaProtocolIPv4 = 4 // IPv4 encapsulation
|
|
||||||
ianaProtocolST = 5 // Stream
|
|
||||||
ianaProtocolTCP = 6 // Transmission Control
|
|
||||||
ianaProtocolCBT = 7 // CBT
|
|
||||||
ianaProtocolEGP = 8 // Exterior Gateway Protocol
|
|
||||||
ianaProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP)
|
|
||||||
ianaProtocolBBNRCCMON = 10 // BBN RCC Monitoring
|
|
||||||
ianaProtocolNVPII = 11 // Network Voice Protocol
|
|
||||||
ianaProtocolPUP = 12 // PUP
|
|
||||||
ianaProtocolARGUS = 13 // ARGUS
|
|
||||||
ianaProtocolEMCON = 14 // EMCON
|
|
||||||
ianaProtocolXNET = 15 // Cross Net Debugger
|
|
||||||
ianaProtocolCHAOS = 16 // Chaos
|
|
||||||
ianaProtocolUDP = 17 // User Datagram
|
|
||||||
ianaProtocolMUX = 18 // Multiplexing
|
|
||||||
ianaProtocolDCNMEAS = 19 // DCN Measurement Subsystems
|
|
||||||
ianaProtocolHMP = 20 // Host Monitoring
|
|
||||||
ianaProtocolPRM = 21 // Packet Radio Measurement
|
|
||||||
ianaProtocolXNSIDP = 22 // XEROX NS IDP
|
|
||||||
ianaProtocolTRUNK1 = 23 // Trunk-1
|
|
||||||
ianaProtocolTRUNK2 = 24 // Trunk-2
|
|
||||||
ianaProtocolLEAF1 = 25 // Leaf-1
|
|
||||||
ianaProtocolLEAF2 = 26 // Leaf-2
|
|
||||||
ianaProtocolRDP = 27 // Reliable Data Protocol
|
|
||||||
ianaProtocolIRTP = 28 // Internet Reliable Transaction
|
|
||||||
ianaProtocolISOTP4 = 29 // ISO Transport Protocol Class 4
|
|
||||||
ianaProtocolNETBLT = 30 // Bulk Data Transfer Protocol
|
|
||||||
ianaProtocolMFENSP = 31 // MFE Network Services Protocol
|
|
||||||
ianaProtocolMERITINP = 32 // MERIT Internodal Protocol
|
|
||||||
ianaProtocolDCCP = 33 // Datagram Congestion Control Protocol
|
|
||||||
ianaProtocol3PC = 34 // Third Party Connect Protocol
|
|
||||||
ianaProtocolIDPR = 35 // Inter-Domain Policy Routing Protocol
|
|
||||||
ianaProtocolXTP = 36 // XTP
|
|
||||||
ianaProtocolDDP = 37 // Datagram Delivery Protocol
|
|
||||||
ianaProtocolIDPRCMTP = 38 // IDPR Control Message Transport Proto
|
|
||||||
ianaProtocolTPPP = 39 // TP++ Transport Protocol
|
|
||||||
ianaProtocolIL = 40 // IL Transport Protocol
|
|
||||||
ianaProtocolIPv6 = 41 // IPv6 encapsulation
|
|
||||||
ianaProtocolSDRP = 42 // Source Demand Routing Protocol
|
|
||||||
ianaProtocolIPv6Route = 43 // Routing Header for IPv6
|
|
||||||
ianaProtocolIPv6Frag = 44 // Fragment Header for IPv6
|
|
||||||
ianaProtocolIDRP = 45 // Inter-Domain Routing Protocol
|
|
||||||
ianaProtocolRSVP = 46 // Reservation Protocol
|
|
||||||
ianaProtocolGRE = 47 // Generic Routing Encapsulation
|
|
||||||
ianaProtocolDSR = 48 // Dynamic Source Routing Protocol
|
|
||||||
ianaProtocolBNA = 49 // BNA
|
|
||||||
ianaProtocolESP = 50 // Encap Security Payload
|
|
||||||
ianaProtocolAH = 51 // Authentication Header
|
|
||||||
ianaProtocolINLSP = 52 // Integrated Net Layer Security TUBA
|
|
||||||
ianaProtocolSWIPE = 53 // IP with Encryption
|
|
||||||
ianaProtocolNARP = 54 // NBMA Address Resolution Protocol
|
|
||||||
ianaProtocolMOBILE = 55 // IP Mobility
|
|
||||||
ianaProtocolTLSP = 56 // Transport Layer Security Protocol using Kryptonet key management
|
|
||||||
ianaProtocolSKIP = 57 // SKIP
|
|
||||||
ianaProtocolIPv6ICMP = 58 // ICMP for IPv6
|
|
||||||
ianaProtocolIPv6NoNxt = 59 // No Next Header for IPv6
|
|
||||||
ianaProtocolIPv6Opts = 60 // Destination Options for IPv6
|
|
||||||
ianaProtocolCFTP = 62 // CFTP
|
|
||||||
ianaProtocolSATEXPAK = 64 // SATNET and Backroom EXPAK
|
|
||||||
ianaProtocolKRYPTOLAN = 65 // Kryptolan
|
|
||||||
ianaProtocolRVD = 66 // MIT Remote Virtual Disk Protocol
|
|
||||||
ianaProtocolIPPC = 67 // Internet Pluribus Packet Core
|
|
||||||
ianaProtocolSATMON = 69 // SATNET Monitoring
|
|
||||||
ianaProtocolVISA = 70 // VISA Protocol
|
|
||||||
ianaProtocolIPCV = 71 // Internet Packet Core Utility
|
|
||||||
ianaProtocolCPNX = 72 // Computer Protocol Network Executive
|
|
||||||
ianaProtocolCPHB = 73 // Computer Protocol Heart Beat
|
|
||||||
ianaProtocolWSN = 74 // Wang Span Network
|
|
||||||
ianaProtocolPVP = 75 // Packet Video Protocol
|
|
||||||
ianaProtocolBRSATMON = 76 // Backroom SATNET Monitoring
|
|
||||||
ianaProtocolSUNND = 77 // SUN ND PROTOCOL-Temporary
|
|
||||||
ianaProtocolWBMON = 78 // WIDEBAND Monitoring
|
|
||||||
ianaProtocolWBEXPAK = 79 // WIDEBAND EXPAK
|
|
||||||
ianaProtocolISOIP = 80 // ISO Internet Protocol
|
|
||||||
ianaProtocolVMTP = 81 // VMTP
|
|
||||||
ianaProtocolSECUREVMTP = 82 // SECURE-VMTP
|
|
||||||
ianaProtocolVINES = 83 // VINES
|
|
||||||
ianaProtocolTTP = 84 // TTP
|
|
||||||
ianaProtocolIPTM = 84 // Protocol Internet Protocol Traffic Manager
|
|
||||||
ianaProtocolNSFNETIGP = 85 // NSFNET-IGP
|
|
||||||
ianaProtocolDGP = 86 // Dissimilar Gateway Protocol
|
|
||||||
ianaProtocolTCF = 87 // TCF
|
|
||||||
ianaProtocolEIGRP = 88 // EIGRP
|
|
||||||
ianaProtocolOSPFIGP = 89 // OSPFIGP
|
|
||||||
ianaProtocolSpriteRPC = 90 // Sprite RPC Protocol
|
|
||||||
ianaProtocolLARP = 91 // Locus Address Resolution Protocol
|
|
||||||
ianaProtocolMTP = 92 // Multicast Transport Protocol
|
|
||||||
ianaProtocolAX25 = 93 // AX.25 Frames
|
|
||||||
ianaProtocolIPIP = 94 // IP-within-IP Encapsulation Protocol
|
|
||||||
ianaProtocolMICP = 95 // Mobile Internetworking Control Pro.
|
|
||||||
ianaProtocolSCCSP = 96 // Semaphore Communications Sec. Pro.
|
|
||||||
ianaProtocolETHERIP = 97 // Ethernet-within-IP Encapsulation
|
|
||||||
ianaProtocolENCAP = 98 // Encapsulation Header
|
|
||||||
ianaProtocolGMTP = 100 // GMTP
|
|
||||||
ianaProtocolIFMP = 101 // Ipsilon Flow Management Protocol
|
|
||||||
ianaProtocolPNNI = 102 // PNNI over IP
|
|
||||||
ianaProtocolPIM = 103 // Protocol Independent Multicast
|
|
||||||
ianaProtocolARIS = 104 // ARIS
|
|
||||||
ianaProtocolSCPS = 105 // SCPS
|
|
||||||
ianaProtocolQNX = 106 // QNX
|
|
||||||
ianaProtocolAN = 107 // Active Networks
|
|
||||||
ianaProtocolIPComp = 108 // IP Payload Compression Protocol
|
|
||||||
ianaProtocolSNP = 109 // Sitara Networks Protocol
|
|
||||||
ianaProtocolCompaqPeer = 110 // Compaq Peer Protocol
|
|
||||||
ianaProtocolIPXinIP = 111 // IPX in IP
|
|
||||||
ianaProtocolVRRP = 112 // Virtual Router Redundancy Protocol
|
|
||||||
ianaProtocolPGM = 113 // PGM Reliable Transport Protocol
|
|
||||||
ianaProtocolL2TP = 115 // Layer Two Tunneling Protocol
|
|
||||||
ianaProtocolDDX = 116 // D-II Data Exchange (DDX)
|
|
||||||
ianaProtocolIATP = 117 // Interactive Agent Transfer Protocol
|
|
||||||
ianaProtocolSTP = 118 // Schedule Transfer Protocol
|
|
||||||
ianaProtocolSRP = 119 // SpectraLink Radio Protocol
|
|
||||||
ianaProtocolUTI = 120 // UTI
|
|
||||||
ianaProtocolSMP = 121 // Simple Message Protocol
|
|
||||||
ianaProtocolSM = 122 // SM
|
|
||||||
ianaProtocolPTP = 123 // Performance Transparency Protocol
|
|
||||||
ianaProtocolISIS = 124 // ISIS over IPv4
|
|
||||||
ianaProtocolFIRE = 125 // FIRE
|
|
||||||
ianaProtocolCRTP = 126 // Combat Radio Transport Protocol
|
|
||||||
ianaProtocolCRUDP = 127 // Combat Radio User Datagram
|
|
||||||
ianaProtocolSSCOPMCE = 128 // SSCOPMCE
|
|
||||||
ianaProtocolIPLT = 129 // IPLT
|
|
||||||
ianaProtocolSPS = 130 // Secure Packet Shield
|
|
||||||
ianaProtocolPIPE = 131 // Private IP Encapsulation within IP
|
|
||||||
ianaProtocolSCTP = 132 // Stream Control Transmission Protocol
|
|
||||||
ianaProtocolFC = 133 // Fibre Channel
|
|
||||||
ianaProtocolRSVPE2EIGNORE = 134 // RSVP-E2E-IGNORE
|
|
||||||
ianaProtocolMobilityHeader = 135 // Mobility Header
|
|
||||||
ianaProtocolUDPLite = 136 // UDPLite
|
|
||||||
ianaProtocolMPLSinIP = 137 // MPLS-in-IP
|
|
||||||
ianaProtocolMANET = 138 // MANET Protocols
|
|
||||||
ianaProtocolHIP = 139 // Host Identity Protocol
|
|
||||||
ianaProtocolShim6 = 140 // Shim6 Protocol
|
|
||||||
ianaProtocolWESP = 141 // Wrapped Encapsulating Security Payload
|
|
||||||
ianaProtocolROHC = 142 // Robust Header Compression
|
|
||||||
ianaProtocolReserved = 255 // Reserved
|
|
||||||
)
|
|
38
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/iana_test.go
generated
vendored
38
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/iana_test.go
generated
vendored
@ -1,38 +0,0 @@
|
|||||||
// go run gentest.go
|
|
||||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
// Differentiated Services Field Codepoints (DSCP), Updated: 2013-06-25
|
|
||||||
const (
|
|
||||||
DiffServCS0 = 0x0 // CS0
|
|
||||||
DiffServCS1 = 0x20 // CS1
|
|
||||||
DiffServCS2 = 0x40 // CS2
|
|
||||||
DiffServCS3 = 0x60 // CS3
|
|
||||||
DiffServCS4 = 0x80 // CS4
|
|
||||||
DiffServCS5 = 0xa0 // CS5
|
|
||||||
DiffServCS6 = 0xc0 // CS6
|
|
||||||
DiffServCS7 = 0xe0 // CS7
|
|
||||||
DiffServAF11 = 0x28 // AF11
|
|
||||||
DiffServAF12 = 0x30 // AF12
|
|
||||||
DiffServAF13 = 0x38 // AF13
|
|
||||||
DiffServAF21 = 0x48 // AF21
|
|
||||||
DiffServAF22 = 0x50 // AF22
|
|
||||||
DiffServAF23 = 0x58 // AF23
|
|
||||||
DiffServAF31 = 0x68 // AF31
|
|
||||||
DiffServAF32 = 0x70 // AF32
|
|
||||||
DiffServAF33 = 0x78 // AF33
|
|
||||||
DiffServAF41 = 0x88 // AF41
|
|
||||||
DiffServAF42 = 0x90 // AF42
|
|
||||||
DiffServAF43 = 0x98 // AF43
|
|
||||||
DiffServEFPHB = 0xb8 // EF PHB
|
|
||||||
DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
|
|
||||||
)
|
|
||||||
|
|
||||||
// IPv4 TOS Byte and IPv6 Traffic Class Octet, Updated: 2001-09-06
|
|
||||||
const (
|
|
||||||
NotECNTransport = 0x0 // Not-ECT (Not ECN-Capable Transport)
|
|
||||||
ECNTransport1 = 0x1 // ECT(1) (ECN-Capable Transport(1))
|
|
||||||
ECNTransport0 = 0x2 // ECT(0) (ECN-Capable Transport(0))
|
|
||||||
CongestionExperienced = 0x3 // CE (Congestion Experienced)
|
|
||||||
)
|
|
47
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp.go
generated
vendored
47
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp.go
generated
vendored
@ -1,47 +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"
|
|
||||||
|
|
||||||
// An ICMPType represents a type of ICMP message.
|
|
||||||
type ICMPType int
|
|
||||||
|
|
||||||
func (typ ICMPType) String() string {
|
|
||||||
s, ok := icmpTypes[typ]
|
|
||||||
if !ok {
|
|
||||||
return "<nil>"
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ICMPFilter represents an ICMP message filter for incoming
|
|
||||||
// packets.
|
|
||||||
type ICMPFilter struct {
|
|
||||||
mu sync.RWMutex
|
|
||||||
sysICMPFilter
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets the ICMP type and filter action to the filter.
|
|
||||||
func (f *ICMPFilter) Set(typ ICMPType, block bool) {
|
|
||||||
f.mu.Lock()
|
|
||||||
f.set(typ, block)
|
|
||||||
f.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAll sets the filter action to the filter.
|
|
||||||
func (f *ICMPFilter) SetAll(block bool) {
|
|
||||||
f.mu.Lock()
|
|
||||||
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()
|
|
||||||
ok := f.willBlock(typ)
|
|
||||||
f.mu.RUnlock()
|
|
||||||
return ok
|
|
||||||
}
|
|
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_bsd.go
generated
vendored
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_bsd.go
generated
vendored
@ -1,33 +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 darwin freebsd netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
type sysICMPFilter struct {
|
|
||||||
Filt [8]uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
|
||||||
if block {
|
|
||||||
f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
|
|
||||||
} else {
|
|
||||||
f.Filt[typ>>5] |= 1 << (uint32(typ) & 31)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) setAll(block bool) {
|
|
||||||
for i := range f.Filt {
|
|
||||||
if block {
|
|
||||||
f.Filt[i] = 0
|
|
||||||
} else {
|
|
||||||
f.Filt[i] = 1<<32 - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
|
||||||
return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
|
|
||||||
}
|
|
31
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_linux.go
generated
vendored
31
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_linux.go
generated
vendored
@ -1,31 +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
|
|
||||||
|
|
||||||
type sysICMPFilter struct {
|
|
||||||
Data [8]uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
|
||||||
if block {
|
|
||||||
f.Data[typ>>5] |= 1 << (uint32(typ) & 31)
|
|
||||||
} else {
|
|
||||||
f.Data[typ>>5] &^= 1 << (uint32(typ) & 31)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) setAll(block bool) {
|
|
||||||
for i := range f.Data {
|
|
||||||
if block {
|
|
||||||
f.Data[i] = 1<<32 - 1
|
|
||||||
} else {
|
|
||||||
f.Data[i] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
|
||||||
return f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0
|
|
||||||
}
|
|
24
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_stub.go
generated
vendored
24
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_stub.go
generated
vendored
@ -1,24 +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 dragonfly plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
type sysICMPFilter struct {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) setAll(block bool) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return false
|
|
||||||
}
|
|
102
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_test.go
generated
vendored
102
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_test.go
generated
vendored
@ -1,102 +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_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.net/ipv6"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
"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 "dragonfly", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %q", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
for _, toggle := range []bool{false, true} {
|
|
||||||
f.SetAll(toggle)
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
for _, typ := range []ipv6.ICMPType{
|
|
||||||
ipv6.ICMPTypeDestinationUnreachable,
|
|
||||||
ipv6.ICMPTypeEchoReply,
|
|
||||||
ipv6.ICMPTypeNeighborSolicitation,
|
|
||||||
ipv6.ICMPTypeDuplicateAddressConfirmation,
|
|
||||||
} {
|
|
||||||
wg.Add(1)
|
|
||||||
go func(typ ipv6.ICMPType) {
|
|
||||||
defer wg.Done()
|
|
||||||
f.Set(typ, false)
|
|
||||||
if f.WillBlock(typ) {
|
|
||||||
t.Errorf("ipv6.ICMPFilter.Set(%v, false) failed", typ)
|
|
||||||
}
|
|
||||||
f.Set(typ, true)
|
|
||||||
if !f.WillBlock(typ) {
|
|
||||||
t.Errorf("ipv6.ICMPFilter.Set(%v, true) failed", typ)
|
|
||||||
}
|
|
||||||
}(typ)
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetICMPFilter(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")
|
|
||||||
}
|
|
||||||
if os.Getuid() != 0 {
|
|
||||||
t.Skip("must be root")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Set(ipv6.ICMPTypeEchoRequest, false)
|
|
||||||
f.Set(ipv6.ICMPTypeEchoReply, false)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.SetICMPFilter failed: %v", err)
|
|
||||||
}
|
|
||||||
kf, err := p.ICMPFilter()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.ICMPFilter failed: %v", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(kf, &f) {
|
|
||||||
t.Fatalf("got unexpected filter %#v; expected %#v", kf, f)
|
|
||||||
}
|
|
||||||
}
|
|
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_windows.go
generated
vendored
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_windows.go
generated
vendored
@ -1,22 +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
|
|
||||||
|
|
||||||
type sysICMPFilter struct {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) setAll(block bool) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return false
|
|
||||||
}
|
|
130
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mockicmp_test.go
generated
vendored
130
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mockicmp_test.go
generated
vendored
@ -1,130 +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_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
|
|
||||||
Code int // code
|
|
||||||
Checksum int // checksum
|
|
||||||
Body icmpMessageBody // body
|
|
||||||
}
|
|
||||||
|
|
||||||
// icmpMessageBody represents an ICMP message body.
|
|
||||||
type icmpMessageBody interface {
|
|
||||||
Len() int
|
|
||||||
Marshal() ([]byte, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal returns the binary enconding of the ICMP echo request or
|
|
||||||
// reply message m.
|
|
||||||
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 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
b = append(b, mb...)
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
s += uint32(b[i+1])<<8 | uint32(b[i])
|
|
||||||
}
|
|
||||||
if csumcv&1 == 0 {
|
|
||||||
s += uint32(b[csumcv])
|
|
||||||
}
|
|
||||||
s = s>>16 + s&0xffff
|
|
||||||
s = s + s>>16
|
|
||||||
// Place checksum back in header; using ^= avoids the
|
|
||||||
// assumption the checksum bytes are zero.
|
|
||||||
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.
|
|
||||||
func parseICMPMessage(b []byte) (*icmpMessage, error) {
|
|
||||||
msglen := len(b)
|
|
||||||
if msglen < 4 {
|
|
||||||
return nil, errors.New("message too short")
|
|
||||||
}
|
|
||||||
m := &icmpMessage{Type: ipv6.ICMPType(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])}
|
|
||||||
if msglen > 4 {
|
|
||||||
var err error
|
|
||||||
switch m.Type {
|
|
||||||
case ipv6.ICMPTypeEchoRequest, ipv6.ICMPTypeEchoReply:
|
|
||||||
m.Body, err = parseICMPEcho(b[4:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// imcpEcho represenets an ICMP echo request or reply message body.
|
|
||||||
type icmpEcho struct {
|
|
||||||
ID int // identifier
|
|
||||||
Seq int // sequence number
|
|
||||||
Data []byte // data
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *icmpEcho) Len() int {
|
|
||||||
if p == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return 4 + len(p.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal returns the binary enconding of the ICMP echo request or
|
|
||||||
// reply message body p.
|
|
||||||
func (p *icmpEcho) Marshal() ([]byte, error) {
|
|
||||||
b := make([]byte, 4+len(p.Data))
|
|
||||||
b[0], b[1] = byte(p.ID>>8), byte(p.ID)
|
|
||||||
b[2], b[3] = byte(p.Seq>>8), byte(p.Seq)
|
|
||||||
copy(b[4:], p.Data)
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseICMPEcho parses b as an ICMP echo request or reply message
|
|
||||||
// body.
|
|
||||||
func parseICMPEcho(b []byte) (*icmpEcho, error) {
|
|
||||||
bodylen := len(b)
|
|
||||||
p := &icmpEcho{ID: int(b[0])<<8 | int(b[1]), Seq: int(b[2])<<8 | int(b[3])}
|
|
||||||
if bodylen > 4 {
|
|
||||||
p.Data = make([]byte, bodylen-4)
|
|
||||||
copy(p.Data, b[4:])
|
|
||||||
}
|
|
||||||
return p, nil
|
|
||||||
}
|
|
88
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mocktransponder_test.go
generated
vendored
88
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mocktransponder_test.go
generated
vendored
@ -1,88 +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_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isLinkLocalUnicast(ip net.IP) bool {
|
|
||||||
return ip.To4() == nil && ip.To16() != nil && ip.IsLinkLocalUnicast()
|
|
||||||
}
|
|
||||||
|
|
||||||
func loopbackInterface() *net.Interface {
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
for _, ifi := range ift {
|
|
||||||
if ifi.Flags&net.FlagLoopback == 0 || ifi.Flags&net.FlagUp == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ifat, err := ifi.Addrs()
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, ifa := range ifat {
|
|
||||||
switch ifa := ifa.(type) {
|
|
||||||
case *net.IPAddr:
|
|
||||||
if isLinkLocalUnicast(ifa.IP) {
|
|
||||||
return &ifi
|
|
||||||
}
|
|
||||||
case *net.IPNet:
|
|
||||||
if isLinkLocalUnicast(ifa.IP) {
|
|
||||||
return &ifi
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isMulticastAvailable(ifi *net.Interface) (net.IP, bool) {
|
|
||||||
if ifi == nil || ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
ifat, err := ifi.Addrs()
|
|
||||||
if err != nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
for _, ifa := range ifat {
|
|
||||||
switch ifa := ifa.(type) {
|
|
||||||
case *net.IPAddr:
|
|
||||||
if isLinkLocalUnicast(ifa.IP) {
|
|
||||||
return ifa.IP, true
|
|
||||||
}
|
|
||||||
case *net.IPNet:
|
|
||||||
if isLinkLocalUnicast(ifa.IP) {
|
|
||||||
return ifa.IP, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func connector(t *testing.T, network, addr string, done chan<- bool) {
|
|
||||||
defer func() { done <- true }()
|
|
||||||
|
|
||||||
c, err := net.Dial(network, addr)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("net.Dial failed: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func acceptor(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
|
|
||||||
}
|
|
||||||
c.Close()
|
|
||||||
}
|
|
205
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicast_test.go
generated
vendored
205
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicast_test.go
generated
vendored
@ -1,205 +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_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"code.google.com/p/go.net/ipv6"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
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 "dragonfly", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %q", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
ifi := loopbackInterface()
|
|
||||||
if ifi == nil {
|
|
||||||
t.Skipf("not available on %q", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("udp6", "[ff02::114]:0") // see RFC 4727
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
_, port, err := net.SplitHostPort(c.LocalAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.SplitHostPort failed: %v", err)
|
|
||||||
}
|
|
||||||
dst, err := net.ResolveUDPAddr("udp6", "[ff02::114]:"+port) // see RFC 4727
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ResolveUDPAddr failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
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.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)
|
|
||||||
}
|
|
||||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteMulticastICMP(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")
|
|
||||||
}
|
|
||||||
if os.Getuid() != 0 {
|
|
||||||
t.Skip("must be root")
|
|
||||||
}
|
|
||||||
ifi := loopbackInterface()
|
|
||||||
if ifi == nil {
|
|
||||||
t.Skipf("not available on %q", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
dst, err := net.ResolveIPAddr("ip6", "ff02::114") // see RFC 4727
|
|
||||||
if err != nil {
|
|
||||||
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.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Set(ipv6.ICMPTypeEchoReply, false)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
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(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)
|
|
||||||
}
|
|
||||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
|
|
||||||
}
|
|
||||||
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(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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
243
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastlistener_test.go
generated
vendored
243
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastlistener_test.go
generated
vendored
@ -1,243 +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_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.net/ipv6"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var udpMultipleGroupListenerTests = []net.Addr{
|
|
||||||
&net.UDPAddr{IP: net.ParseIP("ff02::114")}, // see RFC 4727
|
|
||||||
&net.UDPAddr{IP: net.ParseIP("ff02::1:114")},
|
|
||||||
&net.UDPAddr{IP: net.ParseIP("ff02::2:114")},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUDPSinglePacketConnWithMultipleGroupListeners(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, gaddr := range udpMultipleGroupListenerTests {
|
|
||||||
c, err := net.ListenPacket("udp6", "[::]:0") // wildcard address with non-reusable port
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
var mift []*net.Interface
|
|
||||||
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.Interfaces failed: %v", err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
if _, ok := isMulticastAvailable(&ifi); !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.JoinGroup %v on %v failed: %v", gaddr, ifi, err)
|
|
||||||
}
|
|
||||||
mift = append(mift, &ift[i])
|
|
||||||
}
|
|
||||||
for _, ifi := range mift {
|
|
||||||
if err := p.LeaveGroup(ifi, gaddr); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.LeaveGroup %v on %v failed: %v", gaddr, ifi, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUDPMultiplePacketConnWithMultipleGroupListeners(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, gaddr := range udpMultipleGroupListenerTests {
|
|
||||||
c1, err := net.ListenPacket("udp6", "[ff02::]:1024") // wildcard address with reusable port
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c1.Close()
|
|
||||||
|
|
||||||
c2, err := net.ListenPacket("udp6", "[ff02::]:1024") // wildcard address with reusable port
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c2.Close()
|
|
||||||
|
|
||||||
var ps [2]*ipv6.PacketConn
|
|
||||||
ps[0] = ipv6.NewPacketConn(c1)
|
|
||||||
ps[1] = ipv6.NewPacketConn(c2)
|
|
||||||
var mift []*net.Interface
|
|
||||||
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.Interfaces failed: %v", err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
if _, ok := isMulticastAvailable(&ifi); !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, p := range ps {
|
|
||||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.JoinGroup %v on %v failed: %v", gaddr, ifi, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mift = append(mift, &ift[i])
|
|
||||||
}
|
|
||||||
for _, ifi := range mift {
|
|
||||||
for _, p := range ps {
|
|
||||||
if err := p.LeaveGroup(ifi, gaddr); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.LeaveGroup %v on %v failed: %v", gaddr, ifi, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
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("udp6", fmt.Sprintf("[%s%%%s]:1024", ip.String(), ifi.Name)) // unicast address with non-reusable port
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket with %v failed: %v", ip, 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIPSinglePacketConnWithSingleGroupListener(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")
|
|
||||||
}
|
|
||||||
if os.Getuid() != 0 {
|
|
||||||
t.Skip("must be root")
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
var mift []*net.Interface
|
|
||||||
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.Interfaces failed: %v", err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
if _, ok := isMulticastAvailable(&ifi); !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
76
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastsockopt_test.go
generated
vendored
76
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastsockopt_test.go
generated
vendored
@ -1,76 +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_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.net/ipv6"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var packetConnMulticastSocketOptionTests = []struct {
|
|
||||||
net, proto, addr string
|
|
||||||
gaddr net.Addr
|
|
||||||
}{
|
|
||||||
{"udp6", "", "[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}}, // see RFC 4727
|
|
||||||
{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff02::114")}}, // see RFC 4727
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnMulticastSocketOptions(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")
|
|
||||||
}
|
|
||||||
ifi := loopbackInterface()
|
|
||||||
if ifi == nil {
|
|
||||||
t.Skipf("not available on %q", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range packetConnMulticastSocketOptionTests {
|
|
||||||
if tt.net == "ip6" && os.Getuid() != 0 {
|
|
||||||
t.Skip("must be root")
|
|
||||||
}
|
|
||||||
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
hoplim := 255
|
|
||||||
if err := p.SetMulticastHopLimit(hoplim); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.SetMulticastHopLimit failed: %v", err)
|
|
||||||
}
|
|
||||||
if v, err := p.MulticastHopLimit(); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.MulticastHopLimit failed: %v", err)
|
|
||||||
} else if v != hoplim {
|
|
||||||
t.Fatalf("got unexpected multicast hop limit %v; expected %v", v, hoplim)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, toggle := range []bool{true, false} {
|
|
||||||
if err := p.SetMulticastLoopback(toggle); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.SetMulticastLoopback failed: %v", err)
|
|
||||||
}
|
|
||||||
if v, err := p.MulticastLoopback(); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.MulticastLoopback failed: %v", err)
|
|
||||||
} else if v != toggle {
|
|
||||||
t.Fatalf("got unexpected multicast loopback %v; expected %v", v, toggle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := p.JoinGroup(ifi, tt.gaddr); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.JoinGroup(%v, %v) failed: %v", ifi, tt.gaddr, err)
|
|
||||||
}
|
|
||||||
if err := p.LeaveGroup(ifi, tt.gaddr); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.LeaveGroup(%v, %v) failed: %v", ifi, tt.gaddr, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload.go
generated
vendored
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload.go
generated
vendored
@ -1,15 +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"
|
|
||||||
|
|
||||||
// A payloadHandler represents the IPv6 datagram payload handler.
|
|
||||||
type payloadHandler struct {
|
|
||||||
net.PacketConn
|
|
||||||
rawOpt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil }
|
|
70
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload_cmsg.go
generated
vendored
70
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload_cmsg.go
generated
vendored
@ -1,70 +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 !plan9,!windows
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ReadFrom reads a payload of the received IPv6 datagram, from the
|
|
||||||
// endpoint c, copying the payload into b. It returns the number of
|
|
||||||
// bytes copied into b, the control message cm and the source address
|
|
||||||
// src of the received datagram.
|
|
||||||
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, nil, nil, syscall.EINVAL
|
|
||||||
}
|
|
||||||
oob := newControlMessage(&c.rawOpt)
|
|
||||||
var oobn int
|
|
||||||
switch c := c.PacketConn.(type) {
|
|
||||||
case *net.UDPConn:
|
|
||||||
if n, oobn, _, src, err = c.ReadMsgUDP(b, oob); err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
case *net.IPConn:
|
|
||||||
if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return 0, nil, nil, errInvalidConnType
|
|
||||||
}
|
|
||||||
if cm, err = parseControlMessage(oob[:oobn]); err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
if cm != nil {
|
|
||||||
cm.Src = netAddrToIP16(src)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTo writes a payload of the IPv6 datagram, to the destination
|
|
||||||
// address dst through the endpoint c, copying the payload from b. It
|
|
||||||
// returns the number of bytes written. The control message cm allows
|
|
||||||
// the IPv6 header fields and the datagram path to be specified. The
|
|
||||||
// cm may be nil if control of the outgoing datagram is not required.
|
|
||||||
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
oob := marshalControlMessage(cm)
|
|
||||||
if dst == nil {
|
|
||||||
return 0, errMissingAddress
|
|
||||||
}
|
|
||||||
switch c := c.PacketConn.(type) {
|
|
||||||
case *net.UDPConn:
|
|
||||||
n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr))
|
|
||||||
case *net.IPConn:
|
|
||||||
n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr))
|
|
||||||
default:
|
|
||||||
return 0, errInvalidConnType
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
41
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload_noncmsg.go
generated
vendored
41
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload_noncmsg.go
generated
vendored
@ -1,41 +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 plan9 windows
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ReadFrom reads a payload of the received IPv6 datagram, from the
|
|
||||||
// endpoint c, copying the payload into b. It returns the number of
|
|
||||||
// bytes copied into b, the control message cm and the source address
|
|
||||||
// src of the received datagram.
|
|
||||||
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, nil, nil, syscall.EINVAL
|
|
||||||
}
|
|
||||||
if n, src, err = c.PacketConn.ReadFrom(b); err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTo writes a payload of the IPv6 datagram, to the destination
|
|
||||||
// address dst through the endpoint c, copying the payload from b. It
|
|
||||||
// returns the number of bytes written. The control message cm allows
|
|
||||||
// the IPv6 header fields and the datagram path to be specified. The
|
|
||||||
// cm may be nil if control of the outgoing datagram is not required.
|
|
||||||
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
if dst == nil {
|
|
||||||
return 0, errMissingAddress
|
|
||||||
}
|
|
||||||
return c.PacketConn.WriteTo(b, dst)
|
|
||||||
}
|
|
168
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/readwrite_test.go
generated
vendored
168
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/readwrite_test.go
generated
vendored
@ -1,168 +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_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()
|
|
||||||
}
|
|
73
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc2292_unix.go
generated
vendored
73
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc2292_unix.go
generated
vendored
@ -1,73 +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 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))
|
|
||||||
}
|
|
20
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_bsd.go
generated
vendored
20
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_bsd.go
generated
vendored
@ -1,20 +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 darwin freebsd netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setIPv6Checksum(fd int, on bool, offset int) error {
|
|
||||||
if !on {
|
|
||||||
offset = -1
|
|
||||||
}
|
|
||||||
v := int32(offset)
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), 4))
|
|
||||||
}
|
|
18
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_linux.go
generated
vendored
18
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_linux.go
generated
vendored
@ -1,18 +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"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setIPv6Checksum(fd int, on bool, offset int) error {
|
|
||||||
if !on {
|
|
||||||
offset = -1
|
|
||||||
}
|
|
||||||
v := int32(offset)
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolReserved, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), 4))
|
|
||||||
}
|
|
124
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_unix.go
generated
vendored
124
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_unix.go
generated
vendored
@ -1,124 +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 darwin freebsd linux netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ipv6TrafficClass(fd int) (int, error) {
|
|
||||||
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 int(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6TrafficClass(fd, v int) error {
|
|
||||||
vv := int32(v)
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptTrafficClass, uintptr(unsafe.Pointer(&vv)), 4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6HopLimit(fd int) (int, error) {
|
|
||||||
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 int(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6HopLimit(fd, v int) error {
|
|
||||||
vv := int32(v)
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6Checksum(fd int) (bool, int, error) {
|
|
||||||
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, int(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6MulticastHopLimit(fd int) (int, error) {
|
|
||||||
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 int(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6MulticastHopLimit(fd, v int) error {
|
|
||||||
vv := int32(v)
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6MulticastInterface(fd int) (*net.Interface, error) {
|
|
||||||
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(int(v))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ifi, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6MulticastInterface(fd int, ifi *net.Interface) error {
|
|
||||||
var v int32
|
|
||||||
if ifi != nil {
|
|
||||||
v = int32(ifi.Index)
|
|
||||||
}
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, uintptr(unsafe.Pointer(&v)), 4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6MulticastLoopback(fd int) (bool, error) {
|
|
||||||
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 {
|
|
||||||
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 := sysMulticastReq{}
|
|
||||||
copy(mreq.IP[:], grp)
|
|
||||||
if ifi != nil {
|
|
||||||
mreq.IfIndex = uint32(ifi.Index)
|
|
||||||
}
|
|
||||||
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 := sysMulticastReq{}
|
|
||||||
copy(mreq.IP[:], grp)
|
|
||||||
if ifi != nil {
|
|
||||||
mreq.IfIndex = uint32(ifi.Index)
|
|
||||||
}
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptLeaveGroup, uintptr(unsafe.Pointer(&mreq)), sysSizeofMulticastReq))
|
|
||||||
}
|
|
116
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_windows.go
generated
vendored
116
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_windows.go
generated
vendored
@ -1,116 +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"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ipv6TrafficClass(fd syscall.Handle) (int, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return 0, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6TrafficClass(fd syscall.Handle, v int) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6HopLimit(fd syscall.Handle) (int, error) {
|
|
||||||
var v int32
|
|
||||||
l := int32(4)
|
|
||||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
|
||||||
return 0, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
return int(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6HopLimit(fd syscall.Handle, v int) error {
|
|
||||||
vv := int32(v)
|
|
||||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&vv)), 4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6Checksum(fd syscall.Handle) (bool, int, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return false, 0, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6MulticastHopLimit(fd syscall.Handle) (int, error) {
|
|
||||||
var v int32
|
|
||||||
l := int32(4)
|
|
||||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
|
||||||
return 0, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
return int(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6MulticastHopLimit(fd syscall.Handle, v int) error {
|
|
||||||
vv := int32(v)
|
|
||||||
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, sysSockoptMulticastInterface, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
|
||||||
return nil, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
if v == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
ifi, err := net.InterfaceByIndex(int(v))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ifi, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6MulticastInterface(fd syscall.Handle, ifi *net.Interface) error {
|
|
||||||
var v int32
|
|
||||||
if ifi != nil {
|
|
||||||
v = int32(ifi.Index)
|
|
||||||
}
|
|
||||||
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, sysSockoptMulticastLoopback, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
|
||||||
return false, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
return v == 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6MulticastLoopback(fd syscall.Handle, v bool) error {
|
|
||||||
vv := int32(boolint(v))
|
|
||||||
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 := sysMulticastReq{}
|
|
||||||
copy(mreq.IP[:], grp)
|
|
||||||
if ifi != nil {
|
|
||||||
mreq.IfIndex = uint32(ifi.Index)
|
|
||||||
}
|
|
||||||
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 := sysMulticastReq{}
|
|
||||||
copy(mreq.IP[:], grp)
|
|
||||||
if ifi != nil {
|
|
||||||
mreq.IfIndex = uint32(ifi.Index)
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return syscall.EWINDOWS
|
|
||||||
}
|
|
12
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_stub.go
generated
vendored
12
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_stub.go
generated
vendored
@ -1,12 +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 dragonfly plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
func ipv6PathMTU(fd int) (int, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
90
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_unix.go
generated
vendored
90
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_unix.go
generated
vendored
@ -1,90 +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 linux netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ipv6ReceiveTrafficClass(fd int) (bool, error) {
|
|
||||||
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 {
|
|
||||||
vv := int32(boolint(v))
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, uintptr(unsafe.Pointer(&vv)), 4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6ReceiveHopLimit(fd int) (bool, error) {
|
|
||||||
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 {
|
|
||||||
vv := int32(boolint(v))
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6ReceivePacketInfo(fd int) (bool, error) {
|
|
||||||
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 {
|
|
||||||
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))
|
|
||||||
}
|
|
62
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_windows.go
generated
vendored
62
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_windows.go
generated
vendored
@ -1,62 +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 "syscall"
|
|
||||||
|
|
||||||
func ipv6ReceiveTrafficClass(fd syscall.Handle) (bool, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return false, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6ReceiveTrafficClass(fd syscall.Handle, v bool) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6ReceiveHopLimit(fd syscall.Handle) (bool, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return false, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6ReceiveHopLimit(fd syscall.Handle, v bool) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6ReceivePacketInfo(fd syscall.Handle) (bool, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return false, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6ReceivePacketInfo(fd syscall.Handle, v bool) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6PathMTU(fd syscall.Handle) (int, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return 0, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6ReceivePathMTU(fd syscall.Handle) (bool, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return false, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6ReceivePathMTU(fd syscall.Handle, v bool) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipv6ICMPFilter(fd syscall.Handle) (*ICMPFilter, error) {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return nil, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIPv6ICMPFilter(fd syscall.Handle, f *ICMPFilter) error {
|
|
||||||
// TODO(mikio): Implement this
|
|
||||||
return syscall.EWINDOWS
|
|
||||||
}
|
|
136
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_test.go
generated
vendored
136
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_test.go
generated
vendored
@ -1,136 +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_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.net/ipv6"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var supportsIPv6 bool
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
if ln, err := net.Listen("tcp6", "[::1]:0"); err == nil {
|
|
||||||
ln.Close()
|
|
||||||
supportsIPv6 = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var condFatalf = func() func(*testing.T, string, ...interface{}) {
|
|
||||||
// A few APIs are not implemented yet on some platforms.
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin", "dragonfly", "plan9", "solaris", "windows":
|
|
||||||
return (*testing.T).Logf
|
|
||||||
}
|
|
||||||
return (*testing.T).Fatalf
|
|
||||||
}()
|
|
||||||
|
|
||||||
func TestConnInitiatorPathMTU(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.Listen failed: %v", err)
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
done := make(chan bool)
|
|
||||||
go acceptor(t, ln, done)
|
|
||||||
|
|
||||||
c, err := net.Dial("tcp6", ln.Addr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.Dial failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil {
|
|
||||||
condFatalf(t, "ipv6.Conn.PathMTU failed: %v", err)
|
|
||||||
} else {
|
|
||||||
t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu)
|
|
||||||
}
|
|
||||||
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConnResponderPathMTU(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.Listen failed: %v", err)
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
done := make(chan bool)
|
|
||||||
go connector(t, "tcp6", ln.Addr().String(), done)
|
|
||||||
|
|
||||||
c, err := ln.Accept()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.Accept failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil {
|
|
||||||
condFatalf(t, "ipv6.Conn.PathMTU failed: %v", err)
|
|
||||||
} else {
|
|
||||||
t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu)
|
|
||||||
}
|
|
||||||
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnChecksum(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")
|
|
||||||
}
|
|
||||||
if os.Getuid() != 0 {
|
|
||||||
t.Skip("must be root")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:89", "::") // OSPF for IPv6
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
offset := 12 // see RFC 5340
|
|
||||||
|
|
||||||
for _, toggle := range []bool{false, true} {
|
|
||||||
if err := p.SetChecksum(toggle, offset); err != nil {
|
|
||||||
if toggle {
|
|
||||||
t.Fatalf("ipv6.PacketConn.SetChecksum(%v, %v) failed: %v", toggle, offset, err)
|
|
||||||
} else {
|
|
||||||
// Some platforms never allow to disable the kernel
|
|
||||||
// checksum processing.
|
|
||||||
t.Logf("ipv6.PacketConn.SetChecksum(%v, %v) failed: %v", toggle, offset, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if on, offset, err := p.Checksum(); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.Checksum failed: %v", err)
|
|
||||||
} else {
|
|
||||||
t.Logf("kernel checksum processing enabled=%v, offset=%v", on, offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
23
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys.go
generated
vendored
23
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys.go
generated
vendored
@ -1,23 +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
|
|
||||||
|
|
||||||
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
48
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_bsd.go
generated
vendored
@ -1,48 +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 (
|
|
||||||
"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
54
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_darwin.go
generated
vendored
@ -1,54 +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"
|
|
||||||
"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
45
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_linux.go
generated
vendored
@ -1,45 +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"
|
|
||||||
"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
16
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_unix.go
generated
vendored
@ -1,16 +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 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
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_windows.go
generated
vendored
@ -1,33 +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"
|
|
||||||
"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
42
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.go
generated
vendored
@ -1,42 +0,0 @@
|
|||||||
// 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
56
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.s
generated
vendored
@ -1,56 +0,0 @@
|
|||||||
// 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
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit4_linux_386.go
generated
vendored
@ -1,15 +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 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
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit7_linux_386.go
generated
vendored
@ -1,15 +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 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
26
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_unix.go
generated
vendored
@ -1,26 +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 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
|
|
||||||
}
|
|
172
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicast_test.go
generated
vendored
172
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicast_test.go
generated
vendored
@ -1,172 +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_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"code.google.com/p/go.net/ipv6"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteUnicastUDP(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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
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.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteUnicastICMP(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")
|
|
||||||
}
|
|
||||||
if os.Getuid() != 0 {
|
|
||||||
t.Skip("must be root")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::1")
|
|
||||||
if err != nil {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Set(ipv6.ICMPTypeEchoReply, false)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
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(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.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
|
|
||||||
}
|
|
||||||
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(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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
101
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicastsockopt_test.go
generated
vendored
101
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicastsockopt_test.go
generated
vendored
@ -1,101 +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_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.net/ipv6"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestConnUnicastSocketOptions(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.Listen failed: %v", err)
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
done := make(chan bool)
|
|
||||||
go acceptor(t, ln, done)
|
|
||||||
|
|
||||||
c, err := net.Dial("tcp6", ln.Addr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.Dial failed: %v", err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
testUnicastSocketOptions(t, ipv6.NewConn(c))
|
|
||||||
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
var packetConnUnicastSocketOptionTests = []struct {
|
|
||||||
net, proto, addr string
|
|
||||||
}{
|
|
||||||
{"udp6", "", "[::1]:0"},
|
|
||||||
{"ip6", ":ipv6-icmp", "::1"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnUnicastSocketOptions(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range packetConnUnicastSocketOptionTests {
|
|
||||||
if tt.net == "ip6" && os.Getuid() != 0 {
|
|
||||||
t.Skip("must be root")
|
|
||||||
}
|
|
||||||
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("net.ListenPacket(%q, %q) failed: %v", tt.net+tt.proto, tt.addr, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
testUnicastSocketOptions(t, ipv6.NewPacketConn(c))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type testIPv6UnicastConn interface {
|
|
||||||
TrafficClass() (int, error)
|
|
||||||
SetTrafficClass(int) error
|
|
||||||
HopLimit() (int, error)
|
|
||||||
SetHopLimit(int) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func testUnicastSocketOptions(t *testing.T, c testIPv6UnicastConn) {
|
|
||||||
tclass := DiffServCS0 | NotECNTransport
|
|
||||||
if err := c.SetTrafficClass(tclass); err != nil {
|
|
||||||
t.Fatalf("ipv6.Conn.SetTrafficClass failed: %v", err)
|
|
||||||
}
|
|
||||||
if v, err := c.TrafficClass(); err != nil {
|
|
||||||
t.Fatalf("ipv6.Conn.TrafficClass failed: %v", err)
|
|
||||||
} else if v != tclass {
|
|
||||||
t.Fatalf("got unexpected traffic class %v; expected %v", v, tclass)
|
|
||||||
}
|
|
||||||
|
|
||||||
hoplim := 255
|
|
||||||
if err := c.SetHopLimit(hoplim); err != nil {
|
|
||||||
t.Fatalf("ipv6.Conn.SetHopLimit failed: %v", err)
|
|
||||||
}
|
|
||||||
if v, err := c.HopLimit(); err != nil {
|
|
||||||
t.Fatalf("ipv6.Conn.HopLimit failed: %v", err)
|
|
||||||
} else if v != hoplim {
|
|
||||||
t.Fatalf("got unexpected hop limit %v; expected %v", v, hoplim)
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,9 +9,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"code.google.com/p/go.net/ipv6"
|
|
||||||
|
|
||||||
"github.com/calmh/syncthing/buffers"
|
"github.com/calmh/syncthing/buffers"
|
||||||
|
"github.com/calmh/syncthing/mc"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -23,14 +23,10 @@ type Discoverer struct {
|
|||||||
ListenAddresses []string
|
ListenAddresses []string
|
||||||
BroadcastIntv time.Duration
|
BroadcastIntv time.Duration
|
||||||
ExtBroadcastIntv time.Duration
|
ExtBroadcastIntv time.Duration
|
||||||
|
beacon *mc.Beacon
|
||||||
conn *ipv6.PacketConn
|
|
||||||
intfs []*net.Interface
|
|
||||||
registry map[string][]string
|
registry map[string][]string
|
||||||
registryLock sync.RWMutex
|
registryLock sync.RWMutex
|
||||||
extServer string
|
extServer string
|
||||||
group *net.UDPAddr
|
|
||||||
|
|
||||||
localBroadcastTick <-chan time.Time
|
localBroadcastTick <-chan time.Time
|
||||||
forcedBroadcastTick chan time.Time
|
forcedBroadcastTick chan time.Time
|
||||||
}
|
}
|
||||||
@ -50,43 +46,9 @@ func NewDiscoverer(id string, addresses []string, extServer string) (*Discoverer
|
|||||||
ListenAddresses: addresses,
|
ListenAddresses: addresses,
|
||||||
BroadcastIntv: 30 * time.Second,
|
BroadcastIntv: 30 * time.Second,
|
||||||
ExtBroadcastIntv: 1800 * time.Second,
|
ExtBroadcastIntv: 1800 * time.Second,
|
||||||
|
beacon: mc.NewBeacon("239.21.0.25", 21025),
|
||||||
registry: make(map[string][]string),
|
registry: make(map[string][]string),
|
||||||
extServer: extServer,
|
extServer: extServer,
|
||||||
group: &net.UDPAddr{IP: net.ParseIP("ff02::2012:1025"), Port: AnnouncementPort},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen on a multicast socket. This enables sharing the socket, i.e.
|
|
||||||
// other instances of syncting on the same box can listen on the same
|
|
||||||
// group/port.
|
|
||||||
|
|
||||||
conn, err := net.ListenPacket("udp6", fmt.Sprintf("[ff02::]:%d", AnnouncementPort))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
disc.conn = ipv6.NewPacketConn(conn)
|
|
||||||
|
|
||||||
// Join the multicast group on as many interfaces as possible. Remember
|
|
||||||
// which those were.
|
|
||||||
|
|
||||||
intfs, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("discover/interfaces: %v; no local announcements", err)
|
|
||||||
conn.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, intf := range intfs {
|
|
||||||
intf := intf
|
|
||||||
addrs, err := intf.Addrs()
|
|
||||||
if err == nil && len(addrs) > 0 && intf.Flags&net.FlagMulticast != 0 && intf.Flags&net.FlagUp != 0 {
|
|
||||||
if err := disc.conn.JoinGroup(&intf, disc.group); err != nil {
|
|
||||||
if debug {
|
|
||||||
dlog.Printf("%v; not joining on %s", err, intf.Name)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
disc.intfs = append(disc.intfs, &intf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive announcements sent to the local multicast group.
|
// Receive announcements sent to the local multicast group.
|
||||||
@ -140,21 +102,9 @@ func (d *Discoverer) announcementPkt() []byte {
|
|||||||
|
|
||||||
func (d *Discoverer) sendLocalAnnouncements() {
|
func (d *Discoverer) sendLocalAnnouncements() {
|
||||||
var buf = d.announcementPkt()
|
var buf = d.announcementPkt()
|
||||||
var errCounter = 0
|
|
||||||
var err error
|
|
||||||
|
|
||||||
wcm := ipv6.ControlMessage{HopLimit: 1}
|
for {
|
||||||
for errCounter < maxErrors {
|
d.beacon.Send(buf)
|
||||||
for _, intf := range d.intfs {
|
|
||||||
wcm.IfIndex = intf.Index
|
|
||||||
if _, err = d.conn.WriteTo(buf, &wcm, d.group); err != nil {
|
|
||||||
log.Printf("discover/sendLocalAnnouncements: on %s: %v; no local announcement", intf.Name, err)
|
|
||||||
errCounter++
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
errCounter = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-d.localBroadcastTick:
|
case <-d.localBroadcastTick:
|
||||||
@ -196,26 +146,16 @@ func (d *Discoverer) sendExternalAnnouncements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discoverer) recvAnnouncements() {
|
func (d *Discoverer) recvAnnouncements() {
|
||||||
var buf = make([]byte, 1024)
|
for {
|
||||||
var errCounter = 0
|
buf, addr := d.beacon.Recv()
|
||||||
var err error
|
|
||||||
for errCounter < maxErrors {
|
|
||||||
n, _, addr, err := d.conn.ReadFrom(buf)
|
|
||||||
if err != nil {
|
|
||||||
errCounter++
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
dlog.Printf("read announcement:\n%s", hex.Dump(buf[:n]))
|
dlog.Printf("read announcement:\n%s", hex.Dump(buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
var pkt AnnounceV2
|
var pkt AnnounceV2
|
||||||
err = pkt.UnmarshalXDR(buf[:n])
|
err := pkt.UnmarshalXDR(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errCounter++
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,8 +163,6 @@ func (d *Discoverer) recvAnnouncements() {
|
|||||||
dlog.Printf("parsed announcement: %#v", pkt)
|
dlog.Printf("parsed announcement: %#v", pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
errCounter = 0
|
|
||||||
|
|
||||||
if pkt.NodeID != d.MyID {
|
if pkt.NodeID != d.MyID {
|
||||||
var addrs []string
|
var addrs []string
|
||||||
for _, a := range pkt.Addresses {
|
for _, a := range pkt.Addresses {
|
||||||
@ -252,7 +190,6 @@ func (d *Discoverer) recvAnnouncements() {
|
|||||||
d.registryLock.Unlock()
|
d.registryLock.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Println("discover/read: stopping due to too many errors:", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discoverer) externalLookup(node string) []string {
|
func (d *Discoverer) externalLookup(node string) []string {
|
||||||
|
91
mc/beacon.go
Normal file
91
mc/beacon.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package mc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type recv struct {
|
||||||
|
data []byte
|
||||||
|
src net.Addr
|
||||||
|
}
|
||||||
|
|
||||||
|
type Beacon struct {
|
||||||
|
group string
|
||||||
|
port int
|
||||||
|
conns []*net.UDPConn
|
||||||
|
inbox chan []byte
|
||||||
|
outbox chan recv
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBeacon(group string, port int) *Beacon {
|
||||||
|
b := &Beacon{
|
||||||
|
group: group,
|
||||||
|
port: port,
|
||||||
|
inbox: make(chan []byte),
|
||||||
|
outbox: make(chan recv),
|
||||||
|
}
|
||||||
|
go b.run()
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Beacon) Send(data []byte) {
|
||||||
|
b.inbox <- data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Beacon) Recv() ([]byte, net.Addr) {
|
||||||
|
recv := <-b.outbox
|
||||||
|
return recv.data, recv.src
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Beacon) run() {
|
||||||
|
group := &net.UDPAddr{IP: net.ParseIP(b.group), Port: b.port}
|
||||||
|
|
||||||
|
intfs, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, intf := range intfs {
|
||||||
|
intf := intf
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
dlog.Printf("trying interface %q", intf.Name)
|
||||||
|
}
|
||||||
|
conn, err := net.ListenMulticastUDP("udp4", &intf, group)
|
||||||
|
if err != nil {
|
||||||
|
if debug {
|
||||||
|
dlog.Printf("listen for multicast group on %q: %v", intf.Name, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
b.conns = append(b.conns, conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, conn := range b.conns {
|
||||||
|
conn := conn
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
var bs = make([]byte, 1500)
|
||||||
|
n, addr, err := conn.ReadFrom(bs)
|
||||||
|
if err != nil {
|
||||||
|
dlog.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.outbox <- recv{bs[:n], addr}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for bs := range b.inbox {
|
||||||
|
for _, conn := range b.conns {
|
||||||
|
_, err := conn.WriteTo(bs, group)
|
||||||
|
if err != nil {
|
||||||
|
dlog.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
12
mc/debug.go
Normal file
12
mc/debug.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package mc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
dlog = log.New(os.Stderr, "mc: ", log.Lmicroseconds|log.Lshortfile)
|
||||||
|
debug = strings.Contains(os.Getenv("STTRACE"), "mc")
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user