lvm: setupLV wait device + go mod

This commit is contained in:
Mikaël Cluseau
2019-02-05 09:36:11 +11:00
parent 10e72f18ae
commit c62ddaf2e0
134 changed files with 336 additions and 38985 deletions

View File

@ -1,93 +0,0 @@
// Copyright 2016 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 ipv4_test
import (
"net"
"runtime"
"testing"
"time"
"golang.org/x/net/bpf"
"golang.org/x/net/ipv4"
)
func TestBPF(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skipf("not supported on %s", runtime.GOOS)
}
l, err := net.ListenPacket("udp4", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
defer l.Close()
p := ipv4.NewPacketConn(l)
// This filter accepts UDP packets whose first payload byte is
// even.
prog, err := bpf.Assemble([]bpf.Instruction{
// Load the first byte of the payload (skipping UDP header).
bpf.LoadAbsolute{Off: 8, Size: 1},
// Select LSB of the byte.
bpf.ALUOpConstant{Op: bpf.ALUOpAnd, Val: 1},
// Byte is even?
bpf.JumpIf{Cond: bpf.JumpEqual, Val: 0, SkipFalse: 1},
// Accept.
bpf.RetConstant{Val: 4096},
// Ignore.
bpf.RetConstant{Val: 0},
})
if err != nil {
t.Fatalf("compiling BPF: %s", err)
}
if err = p.SetBPF(prog); err != nil {
t.Fatalf("attaching filter to Conn: %s", err)
}
s, err := net.Dial("udp4", l.LocalAddr().String())
if err != nil {
t.Fatal(err)
}
defer s.Close()
go func() {
for i := byte(0); i < 10; i++ {
s.Write([]byte{i})
}
}()
l.SetDeadline(time.Now().Add(2 * time.Second))
seen := make([]bool, 5)
for {
var b [512]byte
n, _, err := l.ReadFrom(b[:])
if err != nil {
t.Fatalf("reading from listener: %s", err)
}
if n != 1 {
t.Fatalf("unexpected packet length, want 1, got %d", n)
}
if b[0] >= 10 {
t.Fatalf("unexpected byte, want 0-9, got %d", b[0])
}
if b[0]%2 != 0 {
t.Fatalf("got odd byte %d, wanted only even bytes", b[0])
}
seen[b[0]/2] = true
seenAll := true
for _, v := range seen {
if !v {
seenAll = false
break
}
}
if seenAll {
break
}
}
}

View File

@ -1,21 +0,0 @@
// Copyright 2017 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 ipv4_test
import (
"testing"
"golang.org/x/net/ipv4"
)
func TestControlMessageParseWithFuzz(t *testing.T) {
var cm ipv4.ControlMessage
for _, fuzz := range []string{
"\f\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00",
"\f\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00",
} {
cm.Parse([]byte(fuzz))
}
}

View File

@ -1,224 +0,0 @@
// Copyright 2012 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 ipv4_test
import (
"fmt"
"log"
"net"
"os"
"runtime"
"time"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
)
func ExampleConn_markingTCP() {
ln, err := net.Listen("tcp", "0.0.0.0:1024")
if err != nil {
log.Fatal(err)
}
defer ln.Close()
for {
c, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
go func(c net.Conn) {
defer c.Close()
if c.RemoteAddr().(*net.TCPAddr).IP.To4() != nil {
p := ipv4.NewConn(c)
if err := p.SetTOS(0x28); err != nil { // DSCP AF11
log.Fatal(err)
}
if err := p.SetTTL(128); err != nil {
log.Fatal(err)
}
}
if _, err := c.Write([]byte("HELLO-R-U-THERE-ACK")); err != nil {
log.Fatal(err)
}
}(c)
}
}
func ExamplePacketConn_servingOneShotMulticastDNS() {
c, err := net.ListenPacket("udp4", "0.0.0.0:5353") // mDNS over UDP
if err != nil {
log.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
en0, err := net.InterfaceByName("en0")
if err != nil {
log.Fatal(err)
}
mDNSLinkLocal := net.UDPAddr{IP: net.IPv4(224, 0, 0, 251)}
if err := p.JoinGroup(en0, &mDNSLinkLocal); err != nil {
log.Fatal(err)
}
defer p.LeaveGroup(en0, &mDNSLinkLocal)
if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil {
log.Fatal(err)
}
b := make([]byte, 1500)
for {
_, cm, peer, err := p.ReadFrom(b)
if err != nil {
log.Fatal(err)
}
if !cm.Dst.IsMulticast() || !cm.Dst.Equal(mDNSLinkLocal.IP) {
continue
}
answers := []byte("FAKE-MDNS-ANSWERS") // fake mDNS answers, you need to implement this
if _, err := p.WriteTo(answers, nil, peer); err != nil {
log.Fatal(err)
}
}
}
func ExamplePacketConn_tracingIPPacketRoute() {
// Tracing an IP packet route to www.google.com.
const host = "www.google.com"
ips, err := net.LookupIP(host)
if err != nil {
log.Fatal(err)
}
var dst net.IPAddr
for _, ip := range ips {
if ip.To4() != nil {
dst.IP = ip
fmt.Printf("using %v for tracing an IP packet route to %s\n", dst.IP, host)
break
}
}
if dst.IP == nil {
log.Fatal("no A record found")
}
c, err := net.ListenPacket("ip4:1", "0.0.0.0") // ICMP for IPv4
if err != nil {
log.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
if err := p.SetControlMessage(ipv4.FlagTTL|ipv4.FlagSrc|ipv4.FlagDst|ipv4.FlagInterface, true); err != nil {
log.Fatal(err)
}
wm := icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff,
Data: []byte("HELLO-R-U-THERE"),
},
}
rb := make([]byte, 1500)
for i := 1; i <= 64; i++ { // up to 64 hops
wm.Body.(*icmp.Echo).Seq = i
wb, err := wm.Marshal(nil)
if err != nil {
log.Fatal(err)
}
if err := p.SetTTL(i); err != nil {
log.Fatal(err)
}
// In the real world usually there are several
// multiple traffic-engineered paths for each hop.
// You may need to probe a few times to each hop.
begin := time.Now()
if _, err := p.WriteTo(wb, nil, &dst); err != nil {
log.Fatal(err)
}
if err := p.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
n, cm, peer, err := p.ReadFrom(rb)
if err != nil {
if err, ok := err.(net.Error); ok && err.Timeout() {
fmt.Printf("%v\t*\n", i)
continue
}
log.Fatal(err)
}
rm, err := icmp.ParseMessage(1, rb[:n])
if err != nil {
log.Fatal(err)
}
rtt := time.Since(begin)
// In the real world you need to determine whether the
// received message is yours using ControlMessage.Src,
// ControlMessage.Dst, icmp.Echo.ID and icmp.Echo.Seq.
switch rm.Type {
case ipv4.ICMPTypeTimeExceeded:
names, _ := net.LookupAddr(peer.String())
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm)
case ipv4.ICMPTypeEchoReply:
names, _ := net.LookupAddr(peer.String())
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm)
return
default:
log.Printf("unknown ICMP message: %+v\n", rm)
}
}
}
func ExampleRawConn_advertisingOSPFHello() {
c, err := net.ListenPacket("ip4:89", "0.0.0.0") // OSPF for IPv4
if err != nil {
log.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
log.Fatal(err)
}
en0, err := net.InterfaceByName("en0")
if err != nil {
log.Fatal(err)
}
allSPFRouters := net.IPAddr{IP: net.IPv4(224, 0, 0, 5)}
if err := r.JoinGroup(en0, &allSPFRouters); err != nil {
log.Fatal(err)
}
defer r.LeaveGroup(en0, &allSPFRouters)
hello := make([]byte, 24) // fake hello data, you need to implement this
ospf := make([]byte, 24) // fake ospf header, you need to implement this
ospf[0] = 2 // version 2
ospf[1] = 1 // hello packet
ospf = append(ospf, hello...)
iph := &ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TOS: 0xc0, // DSCP CS6
TotalLen: ipv4.HeaderLen + len(ospf),
TTL: 1,
Protocol: 89,
Dst: allSPFRouters.IP.To4(),
}
var cm *ipv4.ControlMessage
switch runtime.GOOS {
case "darwin", "linux":
cm = &ipv4.ControlMessage{IfIndex: en0.Index}
default:
if err := r.SetMulticastInterface(en0); err != nil {
log.Fatal(err)
}
}
if err := r.WriteTo(iph, ospf, cm); err != nil {
log.Fatal(err)
}
}

View File

@ -1,228 +0,0 @@
// Copyright 2012 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 ipv4
import (
"bytes"
"encoding/binary"
"net"
"reflect"
"runtime"
"strings"
"testing"
"golang.org/x/net/internal/socket"
)
type headerTest struct {
wireHeaderFromKernel []byte
wireHeaderToKernel []byte
wireHeaderFromTradBSDKernel []byte
wireHeaderToTradBSDKernel []byte
wireHeaderFromFreeBSD10Kernel []byte
wireHeaderToFreeBSD10Kernel []byte
*Header
}
var headerLittleEndianTests = []headerTest{
// TODO(mikio): Add platform dependent wire header formats when
// we support new platforms.
{
wireHeaderFromKernel: []byte{
0x45, 0x01, 0xbe, 0xef,
0xca, 0xfe, 0x45, 0xdc,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
wireHeaderToKernel: []byte{
0x45, 0x01, 0xbe, 0xef,
0xca, 0xfe, 0x45, 0xdc,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
wireHeaderFromTradBSDKernel: []byte{
0x45, 0x01, 0xdb, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
wireHeaderToTradBSDKernel: []byte{
0x45, 0x01, 0xef, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
wireHeaderFromFreeBSD10Kernel: []byte{
0x45, 0x01, 0xef, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
wireHeaderToFreeBSD10Kernel: []byte{
0x45, 0x01, 0xef, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
Header: &Header{
Version: Version,
Len: HeaderLen,
TOS: 1,
TotalLen: 0xbeef,
ID: 0xcafe,
Flags: DontFragment,
FragOff: 1500,
TTL: 255,
Protocol: 1,
Checksum: 0xdead,
Src: net.IPv4(172, 16, 254, 254),
Dst: net.IPv4(192, 168, 0, 1),
},
},
// with option headers
{
wireHeaderFromKernel: []byte{
0x46, 0x01, 0xbe, 0xf3,
0xca, 0xfe, 0x45, 0xdc,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
0xff, 0xfe, 0xfe, 0xff,
},
wireHeaderToKernel: []byte{
0x46, 0x01, 0xbe, 0xf3,
0xca, 0xfe, 0x45, 0xdc,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
0xff, 0xfe, 0xfe, 0xff,
},
wireHeaderFromTradBSDKernel: []byte{
0x46, 0x01, 0xdb, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
0xff, 0xfe, 0xfe, 0xff,
},
wireHeaderToTradBSDKernel: []byte{
0x46, 0x01, 0xf3, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
0xff, 0xfe, 0xfe, 0xff,
},
wireHeaderFromFreeBSD10Kernel: []byte{
0x46, 0x01, 0xf3, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
0xff, 0xfe, 0xfe, 0xff,
},
wireHeaderToFreeBSD10Kernel: []byte{
0x46, 0x01, 0xf3, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
0xff, 0xfe, 0xfe, 0xff,
},
Header: &Header{
Version: Version,
Len: HeaderLen + 4,
TOS: 1,
TotalLen: 0xbef3,
ID: 0xcafe,
Flags: DontFragment,
FragOff: 1500,
TTL: 255,
Protocol: 1,
Checksum: 0xdead,
Src: net.IPv4(172, 16, 254, 254),
Dst: net.IPv4(192, 168, 0, 1),
Options: []byte{0xff, 0xfe, 0xfe, 0xff},
},
},
}
func TestMarshalHeader(t *testing.T) {
if socket.NativeEndian != binary.LittleEndian {
t.Skip("no test for non-little endian machine yet")
}
for _, tt := range headerLittleEndianTests {
b, err := tt.Header.Marshal()
if err != nil {
t.Fatal(err)
}
var wh []byte
switch runtime.GOOS {
case "darwin", "dragonfly", "netbsd":
wh = tt.wireHeaderToTradBSDKernel
case "freebsd":
switch {
case freebsdVersion < 1000000:
wh = tt.wireHeaderToTradBSDKernel
case 1000000 <= freebsdVersion && freebsdVersion < 1100000:
wh = tt.wireHeaderToFreeBSD10Kernel
default:
wh = tt.wireHeaderToKernel
}
default:
wh = tt.wireHeaderToKernel
}
if !bytes.Equal(b, wh) {
t.Fatalf("got %#v; want %#v", b, wh)
}
}
}
func TestParseHeader(t *testing.T) {
if socket.NativeEndian != binary.LittleEndian {
t.Skip("no test for big endian machine yet")
}
for _, tt := range headerLittleEndianTests {
var wh []byte
switch runtime.GOOS {
case "darwin", "dragonfly", "netbsd":
wh = tt.wireHeaderFromTradBSDKernel
case "freebsd":
switch {
case freebsdVersion < 1000000:
wh = tt.wireHeaderFromTradBSDKernel
case 1000000 <= freebsdVersion && freebsdVersion < 1100000:
wh = tt.wireHeaderFromFreeBSD10Kernel
default:
wh = tt.wireHeaderFromKernel
}
default:
wh = tt.wireHeaderFromKernel
}
h, err := ParseHeader(wh)
if err != nil {
t.Fatal(err)
}
if err := h.Parse(wh); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(h, tt.Header) {
t.Fatalf("got %#v; want %#v", h, tt.Header)
}
s := h.String()
if strings.Contains(s, ",") {
t.Fatalf("should be space-separated values: %s", s)
}
}
}

View File

@ -1,95 +0,0 @@
// Copyright 2014 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 ipv4_test
import (
"net"
"reflect"
"runtime"
"testing"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
var icmpStringTests = []struct {
in ipv4.ICMPType
out string
}{
{ipv4.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; want %s", s, tt.out)
}
}
}
func TestICMPFilter(t *testing.T) {
switch runtime.GOOS {
case "linux":
default:
t.Skipf("not supported on %s", runtime.GOOS)
}
var f ipv4.ICMPFilter
for _, toggle := range []bool{false, true} {
f.SetAll(toggle)
for _, typ := range []ipv4.ICMPType{
ipv4.ICMPTypeDestinationUnreachable,
ipv4.ICMPTypeEchoReply,
ipv4.ICMPTypeTimeExceeded,
ipv4.ICMPTypeParameterProblem,
} {
f.Accept(typ)
if f.WillBlock(typ) {
t.Errorf("ipv4.ICMPFilter.Set(%v, false) failed", typ)
}
f.Block(typ)
if !f.WillBlock(typ) {
t.Errorf("ipv4.ICMPFilter.Set(%v, true) failed", typ)
}
}
}
}
func TestSetICMPFilter(t *testing.T) {
switch runtime.GOOS {
case "linux":
default:
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
c, err := net.ListenPacket("ip4:icmp", "127.0.0.1")
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
var f ipv4.ICMPFilter
f.SetAll(true)
f.Accept(ipv4.ICMPTypeEcho)
f.Accept(ipv4.ICMPTypeEchoReply)
if err := p.SetICMPFilter(&f); err != nil {
t.Fatal(err)
}
kf, err := p.ICMPFilter()
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(kf, &f) {
t.Fatalf("got %#v; want %#v", kf, f)
}
}

View File

@ -1,334 +0,0 @@
// Copyright 2012 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 ipv4_test
import (
"bytes"
"net"
"os"
"runtime"
"testing"
"time"
"golang.org/x/net/icmp"
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
var packetConnReadWriteMulticastUDPTests = []struct {
addr string
grp, src *net.UDPAddr
}{
{"224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727
{"232.0.1.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
for _, tt := range packetConnReadWriteMulticastUDPTests {
c, err := net.ListenPacket("udp4", tt.addr)
if err != nil {
t.Fatal(err)
}
defer c.Close()
grp := *tt.grp
grp.Port = c.LocalAddr().(*net.UDPAddr).Port
p := ipv4.NewPacketConn(c)
defer p.Close()
if tt.src == nil {
if err := p.JoinGroup(ifi, &grp); err != nil {
t.Fatal(err)
}
defer p.LeaveGroup(ifi, &grp)
} else {
if err := p.JoinSourceSpecificGroup(ifi, &grp, tt.src); err != nil {
switch runtime.GOOS {
case "freebsd", "linux":
default: // platforms that don't support IGMPv2/3 fail here
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
defer p.LeaveSourceSpecificGroup(ifi, &grp, tt.src)
}
if err := p.SetMulticastInterface(ifi); err != nil {
t.Fatal(err)
}
if _, err := p.MulticastInterface(); err != nil {
t.Fatal(err)
}
if err := p.SetMulticastLoopback(true); err != nil {
t.Fatal(err)
}
if _, err := p.MulticastLoopback(); err != nil {
t.Fatal(err)
}
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
wb := []byte("HELLO-R-U-THERE")
for i, toggle := range []bool{true, false, true} {
if err := p.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
t.Fatal(err)
}
p.SetMulticastTTL(i + 1)
if n, err := p.WriteTo(wb, nil, &grp); err != nil {
t.Fatal(err)
} else if n != len(wb) {
t.Fatalf("got %v; want %v", n, len(wb))
}
rb := make([]byte, 128)
if n, _, _, err := p.ReadFrom(rb); err != nil {
t.Fatal(err)
} else if !bytes.Equal(rb[:n], wb) {
t.Fatalf("got %v; want %v", rb[:n], wb)
}
}
}
}
var packetConnReadWriteMulticastICMPTests = []struct {
grp, src *net.IPAddr
}{
{&net.IPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727
{&net.IPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
for _, tt := range packetConnReadWriteMulticastICMPTests {
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
defer p.Close()
if tt.src == nil {
if err := p.JoinGroup(ifi, tt.grp); err != nil {
t.Fatal(err)
}
defer p.LeaveGroup(ifi, tt.grp)
} else {
if err := p.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil {
switch runtime.GOOS {
case "freebsd", "linux":
default: // platforms that don't support IGMPv2/3 fail here
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
defer p.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src)
}
if err := p.SetMulticastInterface(ifi); err != nil {
t.Fatal(err)
}
if _, err := p.MulticastInterface(); err != nil {
t.Fatal(err)
}
if err := p.SetMulticastLoopback(true); err != nil {
t.Fatal(err)
}
if _, err := p.MulticastLoopback(); err != nil {
t.Fatal(err)
}
cf := ipv4.FlagDst | ipv4.FlagInterface
if runtime.GOOS != "solaris" {
// Solaris never allows to modify ICMP properties.
cf |= ipv4.FlagTTL
}
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
}).Marshal(nil)
if err != nil {
t.Fatal(err)
}
if err := p.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
t.Fatal(err)
}
p.SetMulticastTTL(i + 1)
if n, err := p.WriteTo(wb, nil, tt.grp); err != nil {
t.Fatal(err)
} else if n != len(wb) {
t.Fatalf("got %v; want %v", n, len(wb))
}
rb := make([]byte, 128)
if n, _, _, err := p.ReadFrom(rb); err != nil {
t.Fatal(err)
} else {
m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n])
if err != nil {
t.Fatal(err)
}
switch {
case m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1
case m.Type == ipv4.ICMPTypeEcho && m.Code == 0: // net.inet.icmp.bmcastecho=0
default:
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
}
}
}
}
}
var rawConnReadWriteMulticastICMPTests = []struct {
grp, src *net.IPAddr
}{
{&net.IPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727
{&net.IPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestRawConnReadWriteMulticastICMP(t *testing.T) {
if testing.Short() {
t.Skip("to avoid external network")
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
for _, tt := range rawConnReadWriteMulticastICMPTests {
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
defer r.Close()
if tt.src == nil {
if err := r.JoinGroup(ifi, tt.grp); err != nil {
t.Fatal(err)
}
defer r.LeaveGroup(ifi, tt.grp)
} else {
if err := r.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil {
switch runtime.GOOS {
case "freebsd", "linux":
default: // platforms that don't support IGMPv2/3 fail here
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
defer r.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src)
}
if err := r.SetMulticastInterface(ifi); err != nil {
t.Fatal(err)
}
if _, err := r.MulticastInterface(); err != nil {
t.Fatal(err)
}
if err := r.SetMulticastLoopback(true); err != nil {
t.Fatal(err)
}
if _, err := r.MulticastLoopback(); err != nil {
t.Fatal(err)
}
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
}).Marshal(nil)
if err != nil {
t.Fatal(err)
}
wh := &ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TOS: i + 1,
TotalLen: ipv4.HeaderLen + len(wb),
Protocol: 1,
Dst: tt.grp.IP,
}
if err := r.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
if err := r.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
t.Fatal(err)
}
r.SetMulticastTTL(i + 1)
if err := r.WriteTo(wh, wb, nil); err != nil {
t.Fatal(err)
}
rb := make([]byte, ipv4.HeaderLen+128)
if rh, b, _, err := r.ReadFrom(rb); err != nil {
t.Fatal(err)
} else {
m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
if err != nil {
t.Fatal(err)
}
switch {
case (rh.Dst.IsLoopback() || rh.Dst.IsLinkLocalUnicast() || rh.Dst.IsGlobalUnicast()) && m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1
case rh.Dst.IsMulticast() && m.Type == ipv4.ICMPTypeEcho && m.Code == 0: // net.inet.icmp.bmcastecho=0
default:
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
}
}
}
}
}

View File

@ -1,265 +0,0 @@
// Copyright 2012 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 ipv4_test
import (
"net"
"runtime"
"testing"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
var udpMultipleGroupListenerTests = []net.Addr{
&net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, // see RFC 4727
&net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)},
&net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)},
}
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
for _, gaddr := range udpMultipleGroupListenerTests {
c, err := net.ListenPacket("udp4", "0.0.0.0:0") // wildcard address with no reusable port
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
var mift []*net.Interface
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
for i, ifi := range ift {
if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
continue
}
if err := p.JoinGroup(&ifi, gaddr); err != nil {
t.Fatal(err)
}
mift = append(mift, &ift[i])
}
for _, ifi := range mift {
if err := p.LeaveGroup(ifi, gaddr); err != nil {
t.Fatal(err)
}
}
}
}
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
for _, gaddr := range udpMultipleGroupListenerTests {
c1, err := net.ListenPacket("udp4", "224.0.0.0:0") // wildcard address with reusable port
if err != nil {
t.Fatal(err)
}
defer c1.Close()
_, port, err := net.SplitHostPort(c1.LocalAddr().String())
if err != nil {
t.Fatal(err)
}
c2, err := net.ListenPacket("udp4", net.JoinHostPort("224.0.0.0", port)) // wildcard address with reusable port
if err != nil {
t.Fatal(err)
}
defer c2.Close()
var ps [2]*ipv4.PacketConn
ps[0] = ipv4.NewPacketConn(c1)
ps[1] = ipv4.NewPacketConn(c2)
var mift []*net.Interface
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
for i, ifi := range ift {
if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
continue
}
for _, p := range ps {
if err := p.JoinGroup(&ifi, gaddr); err != nil {
t.Fatal(err)
}
}
mift = append(mift, &ift[i])
}
for _, ifi := range mift {
for _, p := range ps {
if err := p.LeaveGroup(ifi, gaddr); err != nil {
t.Fatal(err)
}
}
}
}
}
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
type ml struct {
c *ipv4.PacketConn
ifi *net.Interface
}
var mlt []*ml
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
port := "0"
for i, ifi := range ift {
ip, ok := nettest.IsMulticastCapable("ip4", &ifi)
if !ok {
continue
}
c, err := net.ListenPacket("udp4", net.JoinHostPort(ip.String(), port)) // unicast address with non-reusable port
if err != nil {
// The listen may fail when the serivce is
// already in use, but it's fine because the
// purpose of this is not to test the
// bookkeeping of IP control block inside the
// kernel.
t.Log(err)
continue
}
defer c.Close()
if port == "0" {
_, port, err = net.SplitHostPort(c.LocalAddr().String())
if err != nil {
t.Fatal(err)
}
}
p := ipv4.NewPacketConn(c)
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
t.Fatal(err)
}
mlt = append(mlt, &ml{p, &ift[i]})
}
for _, m := range mlt {
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
t.Fatal(err)
}
}
}
func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") // wildcard address
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
var mift []*net.Interface
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
for i, ifi := range ift {
if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
continue
}
if err := r.JoinGroup(&ifi, &gaddr); err != nil {
t.Fatal(err)
}
mift = append(mift, &ift[i])
}
for _, ifi := range mift {
if err := r.LeaveGroup(ifi, &gaddr); err != nil {
t.Fatal(err)
}
}
}
func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
type ml struct {
c *ipv4.RawConn
ifi *net.Interface
}
var mlt []*ml
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
for i, ifi := range ift {
ip, ok := nettest.IsMulticastCapable("ip4", &ifi)
if !ok {
continue
}
c, err := net.ListenPacket("ip4:253", ip.String()) // unicast address
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
if err := r.JoinGroup(&ifi, &gaddr); err != nil {
t.Fatal(err)
}
mlt = append(mlt, &ml{r, &ift[i]})
}
for _, m := range mlt {
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
t.Fatal(err)
}
}
}

View File

@ -1,195 +0,0 @@
// Copyright 2012 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 ipv4_test
import (
"net"
"runtime"
"testing"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
var packetConnMulticastSocketOptionTests = []struct {
net, proto, addr string
grp, src net.Addr
}{
{"udp4", "", "224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, nil}, // see RFC 4727
{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727
{"udp4", "", "232.0.0.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 249)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestPacketConnMulticastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
m, ok := nettest.SupportsRawIPSocket()
for _, tt := range packetConnMulticastSocketOptionTests {
if tt.net == "ip4" && !ok {
t.Log(m)
continue
}
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
defer p.Close()
if tt.src == nil {
testMulticastSocketOptions(t, p, ifi, tt.grp)
} else {
testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
}
}
}
var rawConnMulticastSocketOptionTests = []struct {
grp, src net.Addr
}{
{&net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727
{&net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestRawConnMulticastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
for _, tt := range rawConnMulticastSocketOptionTests {
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
defer r.Close()
if tt.src == nil {
testMulticastSocketOptions(t, r, ifi, tt.grp)
} else {
testSourceSpecificMulticastSocketOptions(t, r, ifi, tt.grp, tt.src)
}
}
}
type testIPv4MulticastConn interface {
MulticastTTL() (int, error)
SetMulticastTTL(ttl int) error
MulticastLoopback() (bool, error)
SetMulticastLoopback(bool) error
JoinGroup(*net.Interface, net.Addr) error
LeaveGroup(*net.Interface, net.Addr) error
JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
}
func testMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp net.Addr) {
const ttl = 255
if err := c.SetMulticastTTL(ttl); err != nil {
t.Error(err)
return
}
if v, err := c.MulticastTTL(); err != nil {
t.Error(err)
return
} else if v != ttl {
t.Errorf("got %v; want %v", v, ttl)
return
}
for _, toggle := range []bool{true, false} {
if err := c.SetMulticastLoopback(toggle); err != nil {
t.Error(err)
return
}
if v, err := c.MulticastLoopback(); err != nil {
t.Error(err)
return
} else if v != toggle {
t.Errorf("got %v; want %v", v, toggle)
return
}
}
if err := c.JoinGroup(ifi, grp); err != nil {
t.Error(err)
return
}
if err := c.LeaveGroup(ifi, grp); err != nil {
t.Error(err)
return
}
}
func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp, src net.Addr) {
// MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
if err := c.JoinGroup(ifi, grp); err != nil {
t.Error(err)
return
}
if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
switch runtime.GOOS {
case "freebsd", "linux":
default: // platforms that don't support IGMPv2/3 fail here
t.Logf("not supported on %s", runtime.GOOS)
return
}
t.Error(err)
return
}
if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
t.Error(err)
return
}
if err := c.LeaveGroup(ifi, grp); err != nil {
t.Error(err)
return
}
// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
t.Error(err)
return
}
if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
t.Error(err)
return
}
// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
t.Error(err)
return
}
if err := c.LeaveGroup(ifi, grp); err != nil {
t.Error(err)
return
}
}

View File

@ -1,248 +0,0 @@
// Copyright 2012 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.9
package ipv4_test
import (
"bytes"
"fmt"
"net"
"runtime"
"strings"
"sync"
"testing"
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
b.Skipf("not supported on %s", runtime.GOOS)
}
payload := []byte("HELLO-R-U-THERE")
iph, err := (&ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TotalLen: ipv4.HeaderLen + len(payload),
TTL: 1,
Protocol: iana.ProtocolReserved,
Src: net.IPv4(192, 0, 2, 1),
Dst: net.IPv4(192, 0, 2, 254),
}).Marshal()
if err != nil {
b.Fatal(err)
}
greh := []byte{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}
datagram := append(greh, append(iph, payload...)...)
bb := make([]byte, 128)
cm := ipv4.ControlMessage{
Src: net.IPv4(127, 0, 0, 1),
}
if ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); ifi != nil {
cm.IfIndex = ifi.Index
}
b.Run("UDP", func(b *testing.B) {
c, err := nettest.NewLocalPacketListener("udp4")
if err != nil {
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
dst := c.LocalAddr()
cf := ipv4.FlagTTL | ipv4.FlagInterface
if err := p.SetControlMessage(cf, true); err != nil {
b.Fatal(err)
}
b.Run("Net", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := c.WriteTo(payload, dst); err != nil {
b.Fatal(err)
}
if _, _, err := c.ReadFrom(bb); err != nil {
b.Fatal(err)
}
}
})
b.Run("ToFrom", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := p.WriteTo(payload, &cm, dst); err != nil {
b.Fatal(err)
}
if _, _, _, err := p.ReadFrom(bb); err != nil {
b.Fatal(err)
}
}
})
})
b.Run("IP", func(b *testing.B) {
switch runtime.GOOS {
case "netbsd":
b.Skip("need to configure gre on netbsd")
case "openbsd":
b.Skip("net.inet.gre.allow=0 by default on openbsd")
}
c, err := net.ListenPacket(fmt.Sprintf("ip4:%d", iana.ProtocolGRE), "127.0.0.1")
if err != nil {
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
dst := c.LocalAddr()
cf := ipv4.FlagTTL | ipv4.FlagInterface
if err := p.SetControlMessage(cf, true); err != nil {
b.Fatal(err)
}
b.Run("Net", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := c.WriteTo(datagram, dst); err != nil {
b.Fatal(err)
}
if _, _, err := c.ReadFrom(bb); err != nil {
b.Fatal(err)
}
}
})
b.Run("ToFrom", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := p.WriteTo(datagram, &cm, dst); err != nil {
b.Fatal(err)
}
if _, _, _, err := p.ReadFrom(bb); err != nil {
b.Fatal(err)
}
}
})
})
}
func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
payload := []byte("HELLO-R-U-THERE")
iph, err := (&ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TotalLen: ipv4.HeaderLen + len(payload),
TTL: 1,
Protocol: iana.ProtocolReserved,
Src: net.IPv4(192, 0, 2, 1),
Dst: net.IPv4(192, 0, 2, 254),
}).Marshal()
if err != nil {
t.Fatal(err)
}
greh := []byte{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}
datagram := append(greh, append(iph, payload...)...)
t.Run("UDP", func(t *testing.T) {
c, err := nettest.NewLocalPacketListener("udp4")
if err != nil {
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
t.Run("ToFrom", func(t *testing.T) {
testPacketConnConcurrentReadWriteUnicast(t, p, payload, c.LocalAddr())
})
})
t.Run("IP", func(t *testing.T) {
switch runtime.GOOS {
case "netbsd":
t.Skip("need to configure gre on netbsd")
case "openbsd":
t.Skip("net.inet.gre.allow=0 by default on openbsd")
}
c, err := net.ListenPacket(fmt.Sprintf("ip4:%d", iana.ProtocolGRE), "127.0.0.1")
if err != nil {
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
t.Run("ToFrom", func(t *testing.T) {
testPacketConnConcurrentReadWriteUnicast(t, p, datagram, c.LocalAddr())
})
})
}
func testPacketConnConcurrentReadWriteUnicast(t *testing.T, p *ipv4.PacketConn, data []byte, dst net.Addr) {
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
cf := ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface
if err := p.SetControlMessage(cf, true); err != nil { // probe before test
if nettest.ProtocolNotSupported(err) {
t.Skipf("not supported on %s", runtime.GOOS)
}
t.Fatal(err)
}
var wg sync.WaitGroup
reader := func() {
defer wg.Done()
b := make([]byte, 128)
n, cm, _, err := p.ReadFrom(b)
if err != nil {
t.Error(err)
return
}
if !bytes.Equal(b[:n], data) {
t.Errorf("got %#v; want %#v", b[:n], data)
return
}
s := cm.String()
if strings.Contains(s, ",") {
t.Errorf("should be space-separated values: %s", s)
return
}
}
writer := func(toggle bool) {
defer wg.Done()
cm := ipv4.ControlMessage{
Src: net.IPv4(127, 0, 0, 1),
}
if ifi != nil {
cm.IfIndex = ifi.Index
}
if err := p.SetControlMessage(cf, toggle); err != nil {
t.Error(err)
return
}
n, err := p.WriteTo(data, &cm, dst)
if err != nil {
t.Error(err)
return
}
if n != len(data) {
t.Errorf("got %d; want %d", n, len(data))
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()
}

View File

@ -1,388 +0,0 @@
// Copyright 2017 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.9
package ipv4_test
import (
"bytes"
"fmt"
"net"
"runtime"
"strings"
"sync"
"testing"
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
b.Skipf("not supported on %s", runtime.GOOS)
}
payload := []byte("HELLO-R-U-THERE")
iph, err := (&ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TotalLen: ipv4.HeaderLen + len(payload),
TTL: 1,
Protocol: iana.ProtocolReserved,
Src: net.IPv4(192, 0, 2, 1),
Dst: net.IPv4(192, 0, 2, 254),
}).Marshal()
if err != nil {
b.Fatal(err)
}
greh := []byte{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}
datagram := append(greh, append(iph, payload...)...)
bb := make([]byte, 128)
cm := ipv4.ControlMessage{
Src: net.IPv4(127, 0, 0, 1),
}
if ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); ifi != nil {
cm.IfIndex = ifi.Index
}
b.Run("UDP", func(b *testing.B) {
c, err := nettest.NewLocalPacketListener("udp4")
if err != nil {
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
dst := c.LocalAddr()
cf := ipv4.FlagTTL | ipv4.FlagInterface
if err := p.SetControlMessage(cf, true); err != nil {
b.Fatal(err)
}
wms := []ipv4.Message{
{
Buffers: [][]byte{payload},
Addr: dst,
OOB: cm.Marshal(),
},
}
rms := []ipv4.Message{
{
Buffers: [][]byte{bb},
OOB: ipv4.NewControlMessage(cf),
},
}
b.Run("Net", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := c.WriteTo(payload, dst); err != nil {
b.Fatal(err)
}
if _, _, err := c.ReadFrom(bb); err != nil {
b.Fatal(err)
}
}
})
b.Run("ToFrom", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := p.WriteTo(payload, &cm, dst); err != nil {
b.Fatal(err)
}
if _, _, _, err := p.ReadFrom(bb); err != nil {
b.Fatal(err)
}
}
})
b.Run("Batch", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := p.WriteBatch(wms, 0); err != nil {
b.Fatal(err)
}
if _, err := p.ReadBatch(rms, 0); err != nil {
b.Fatal(err)
}
}
})
})
b.Run("IP", func(b *testing.B) {
switch runtime.GOOS {
case "netbsd":
b.Skip("need to configure gre on netbsd")
case "openbsd":
b.Skip("net.inet.gre.allow=0 by default on openbsd")
}
c, err := net.ListenPacket(fmt.Sprintf("ip4:%d", iana.ProtocolGRE), "127.0.0.1")
if err != nil {
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
dst := c.LocalAddr()
cf := ipv4.FlagTTL | ipv4.FlagInterface
if err := p.SetControlMessage(cf, true); err != nil {
b.Fatal(err)
}
wms := []ipv4.Message{
{
Buffers: [][]byte{datagram},
Addr: dst,
OOB: cm.Marshal(),
},
}
rms := []ipv4.Message{
{
Buffers: [][]byte{bb},
OOB: ipv4.NewControlMessage(cf),
},
}
b.Run("Net", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := c.WriteTo(datagram, dst); err != nil {
b.Fatal(err)
}
if _, _, err := c.ReadFrom(bb); err != nil {
b.Fatal(err)
}
}
})
b.Run("ToFrom", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := p.WriteTo(datagram, &cm, dst); err != nil {
b.Fatal(err)
}
if _, _, _, err := p.ReadFrom(bb); err != nil {
b.Fatal(err)
}
}
})
b.Run("Batch", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := p.WriteBatch(wms, 0); err != nil {
b.Fatal(err)
}
if _, err := p.ReadBatch(rms, 0); err != nil {
b.Fatal(err)
}
}
})
})
}
func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
payload := []byte("HELLO-R-U-THERE")
iph, err := (&ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TotalLen: ipv4.HeaderLen + len(payload),
TTL: 1,
Protocol: iana.ProtocolReserved,
Src: net.IPv4(192, 0, 2, 1),
Dst: net.IPv4(192, 0, 2, 254),
}).Marshal()
if err != nil {
t.Fatal(err)
}
greh := []byte{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}
datagram := append(greh, append(iph, payload...)...)
t.Run("UDP", func(t *testing.T) {
c, err := nettest.NewLocalPacketListener("udp4")
if err != nil {
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
t.Run("ToFrom", func(t *testing.T) {
testPacketConnConcurrentReadWriteUnicast(t, p, payload, c.LocalAddr(), false)
})
t.Run("Batch", func(t *testing.T) {
testPacketConnConcurrentReadWriteUnicast(t, p, payload, c.LocalAddr(), true)
})
})
t.Run("IP", func(t *testing.T) {
switch runtime.GOOS {
case "netbsd":
t.Skip("need to configure gre on netbsd")
case "openbsd":
t.Skip("net.inet.gre.allow=0 by default on openbsd")
}
c, err := net.ListenPacket(fmt.Sprintf("ip4:%d", iana.ProtocolGRE), "127.0.0.1")
if err != nil {
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
t.Run("ToFrom", func(t *testing.T) {
testPacketConnConcurrentReadWriteUnicast(t, p, datagram, c.LocalAddr(), false)
})
t.Run("Batch", func(t *testing.T) {
testPacketConnConcurrentReadWriteUnicast(t, p, datagram, c.LocalAddr(), true)
})
})
}
func testPacketConnConcurrentReadWriteUnicast(t *testing.T, p *ipv4.PacketConn, data []byte, dst net.Addr, batch bool) {
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
cf := ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface
if err := p.SetControlMessage(cf, true); err != nil { // probe before test
if nettest.ProtocolNotSupported(err) {
t.Skipf("not supported on %s", runtime.GOOS)
}
t.Fatal(err)
}
var wg sync.WaitGroup
reader := func() {
defer wg.Done()
b := make([]byte, 128)
n, cm, _, err := p.ReadFrom(b)
if err != nil {
t.Error(err)
return
}
if !bytes.Equal(b[:n], data) {
t.Errorf("got %#v; want %#v", b[:n], data)
return
}
s := cm.String()
if strings.Contains(s, ",") {
t.Errorf("should be space-separated values: %s", s)
return
}
}
batchReader := func() {
defer wg.Done()
ms := []ipv4.Message{
{
Buffers: [][]byte{make([]byte, 128)},
OOB: ipv4.NewControlMessage(cf),
},
}
n, err := p.ReadBatch(ms, 0)
if err != nil {
t.Error(err)
return
}
if n != len(ms) {
t.Errorf("got %d; want %d", n, len(ms))
return
}
var cm ipv4.ControlMessage
if err := cm.Parse(ms[0].OOB[:ms[0].NN]); err != nil {
t.Error(err)
return
}
var b []byte
if _, ok := dst.(*net.IPAddr); ok {
var h ipv4.Header
if err := h.Parse(ms[0].Buffers[0][:ms[0].N]); err != nil {
t.Error(err)
return
}
b = ms[0].Buffers[0][h.Len:ms[0].N]
} else {
b = ms[0].Buffers[0][:ms[0].N]
}
if !bytes.Equal(b, data) {
t.Errorf("got %#v; want %#v", b, data)
return
}
s := cm.String()
if strings.Contains(s, ",") {
t.Errorf("should be space-separated values: %s", s)
return
}
}
writer := func(toggle bool) {
defer wg.Done()
cm := ipv4.ControlMessage{
Src: net.IPv4(127, 0, 0, 1),
}
if ifi != nil {
cm.IfIndex = ifi.Index
}
if err := p.SetControlMessage(cf, toggle); err != nil {
t.Error(err)
return
}
n, err := p.WriteTo(data, &cm, dst)
if err != nil {
t.Error(err)
return
}
if n != len(data) {
t.Errorf("got %d; want %d", n, len(data))
return
}
}
batchWriter := func(toggle bool) {
defer wg.Done()
cm := ipv4.ControlMessage{
Src: net.IPv4(127, 0, 0, 1),
}
if ifi != nil {
cm.IfIndex = ifi.Index
}
if err := p.SetControlMessage(cf, toggle); err != nil {
t.Error(err)
return
}
ms := []ipv4.Message{
{
Buffers: [][]byte{data},
OOB: cm.Marshal(),
Addr: dst,
},
}
n, err := p.WriteBatch(ms, 0)
if err != nil {
t.Error(err)
return
}
if n != len(ms) {
t.Errorf("got %d; want %d", n, len(ms))
return
}
if ms[0].N != len(data) {
t.Errorf("got %d; want %d", ms[0].N, len(data))
return
}
}
const N = 10
wg.Add(N)
for i := 0; i < N; i++ {
if batch {
go batchReader()
} else {
go reader()
}
}
wg.Add(2 * N)
for i := 0; i < 2*N; i++ {
if batch {
go batchWriter(i%2 != 0)
} else {
go writer(i%2 != 0)
}
}
wg.Add(N)
for i := 0; i < N; i++ {
if batch {
go batchReader()
} else {
go reader()
}
}
wg.Wait()
}

View File

@ -1,140 +0,0 @@
// Copyright 2012 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 ipv4_test
import (
"bytes"
"net"
"runtime"
"strings"
"sync"
"testing"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
func BenchmarkReadWriteUnicast(b *testing.B) {
c, err := nettest.NewLocalPacketListener("udp4")
if err != nil {
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
}
defer c.Close()
dst := c.LocalAddr()
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
b.Run("NetUDP", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := c.WriteTo(wb, dst); err != nil {
b.Fatal(err)
}
if _, _, err := c.ReadFrom(rb); err != nil {
b.Fatal(err)
}
}
})
b.Run("IPv4UDP", func(b *testing.B) {
p := ipv4.NewPacketConn(c)
cf := ipv4.FlagTTL | ipv4.FlagInterface
if err := p.SetControlMessage(cf, true); err != nil {
b.Fatal(err)
}
cm := ipv4.ControlMessage{TTL: 1}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi != nil {
cm.IfIndex = ifi.Index
}
for i := 0; i < b.N; i++ {
if _, err := p.WriteTo(wb, &cm, dst); err != nil {
b.Fatal(err)
}
if _, _, _, err := p.ReadFrom(rb); err != nil {
b.Fatal(err)
}
}
})
}
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
c, err := nettest.NewLocalPacketListener("udp4")
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
defer p.Close()
dst := c.LocalAddr()
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
cf := ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface
wb := []byte("HELLO-R-U-THERE")
if err := p.SetControlMessage(cf, true); err != nil { // probe before test
if nettest.ProtocolNotSupported(err) {
t.Skipf("not supported on %s", runtime.GOOS)
}
t.Fatal(err)
}
var wg sync.WaitGroup
reader := func() {
defer wg.Done()
rb := make([]byte, 128)
if n, cm, _, err := p.ReadFrom(rb); err != nil {
t.Error(err)
return
} else if !bytes.Equal(rb[:n], wb) {
t.Errorf("got %v; want %v", rb[:n], wb)
return
} else {
s := cm.String()
if strings.Contains(s, ",") {
t.Errorf("should be space-separated values: %s", s)
}
}
}
writer := func(toggle bool) {
defer wg.Done()
cm := ipv4.ControlMessage{
Src: net.IPv4(127, 0, 0, 1),
}
if ifi != nil {
cm.IfIndex = ifi.Index
}
if err := p.SetControlMessage(cf, toggle); err != nil {
t.Error(err)
return
}
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
t.Error(err)
return
} else if n != len(wb) {
t.Errorf("got %d; want %d", n, len(wb))
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()
}

View File

@ -1,247 +0,0 @@
// Copyright 2012 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 ipv4_test
import (
"bytes"
"net"
"os"
"runtime"
"testing"
"time"
"golang.org/x/net/icmp"
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
c, err := nettest.NewLocalPacketListener("udp4")
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
defer p.Close()
dst := c.LocalAddr()
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
wb := []byte("HELLO-R-U-THERE")
for i, toggle := range []bool{true, false, true} {
if err := p.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
p.SetTTL(i + 1)
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if n, err := p.WriteTo(wb, nil, dst); err != nil {
t.Fatal(err)
} else if n != len(wb) {
t.Fatalf("got %v; want %v", n, len(wb))
}
rb := make([]byte, 128)
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if n, _, _, err := p.ReadFrom(rb); err != nil {
t.Fatal(err)
} else if !bytes.Equal(rb[:n], wb) {
t.Fatalf("got %v; want %v", rb[:n], wb)
}
}
}
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
if err != nil {
t.Fatal(err)
}
p := ipv4.NewPacketConn(c)
defer p.Close()
cf := ipv4.FlagDst | ipv4.FlagInterface
if runtime.GOOS != "solaris" {
// Solaris never allows to modify ICMP properties.
cf |= ipv4.FlagTTL
}
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
}).Marshal(nil)
if err != nil {
t.Fatal(err)
}
if err := p.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
p.SetTTL(i + 1)
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if n, err := p.WriteTo(wb, nil, dst); err != nil {
t.Fatal(err)
} else if n != len(wb) {
t.Fatalf("got %v; want %v", n, len(wb))
}
rb := make([]byte, 128)
loop:
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if n, _, _, err := p.ReadFrom(rb); err != nil {
switch runtime.GOOS {
case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
} else {
m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n])
if err != nil {
t.Fatal(err)
}
if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
// On Linux we must handle own sent packets.
goto loop
}
if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
}
}
}
}
func TestRawConnReadWriteUnicastICMP(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
if err != nil {
t.Fatal(err)
}
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
defer r.Close()
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
}).Marshal(nil)
if err != nil {
t.Fatal(err)
}
wh := &ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TOS: i + 1,
TotalLen: ipv4.HeaderLen + len(wb),
TTL: i + 1,
Protocol: 1,
Dst: dst.IP,
}
if err := r.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
if err := r.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if err := r.WriteTo(wh, wb, nil); err != nil {
t.Fatal(err)
}
rb := make([]byte, ipv4.HeaderLen+128)
loop:
if err := r.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if _, b, _, err := r.ReadFrom(rb); err != nil {
switch runtime.GOOS {
case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
} else {
m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
if err != nil {
t.Fatal(err)
}
if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
// On Linux we must handle own sent packets.
goto loop
}
if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
}
}
}
}

View File

@ -1,148 +0,0 @@
// Copyright 2012 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 ipv4_test
import (
"net"
"runtime"
"testing"
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
func TestConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
ln, err := net.Listen("tcp4", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
defer ln.Close()
errc := make(chan error, 1)
go func() {
c, err := ln.Accept()
if err != nil {
errc <- err
return
}
errc <- c.Close()
}()
c, err := net.Dial("tcp4", ln.Addr().String())
if err != nil {
t.Fatal(err)
}
defer c.Close()
testUnicastSocketOptions(t, ipv4.NewConn(c))
if err := <-errc; err != nil {
t.Errorf("server: %v", err)
}
}
var packetConnUnicastSocketOptionTests = []struct {
net, proto, addr string
}{
{"udp4", "", "127.0.0.1:0"},
{"ip4", ":icmp", "127.0.0.1"},
}
func TestPacketConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
m, ok := nettest.SupportsRawIPSocket()
for _, tt := range packetConnUnicastSocketOptionTests {
if tt.net == "ip4" && !ok {
t.Log(m)
continue
}
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
if err != nil {
t.Fatal(err)
}
defer c.Close()
testUnicastSocketOptions(t, ipv4.NewPacketConn(c))
}
}
func TestRawConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
c, err := net.ListenPacket("ip4:icmp", "127.0.0.1")
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
testUnicastSocketOptions(t, r)
}
type testIPv4UnicastConn interface {
TOS() (int, error)
SetTOS(int) error
TTL() (int, error)
SetTTL(int) error
}
func testUnicastSocketOptions(t *testing.T, c testIPv4UnicastConn) {
tos := iana.DiffServCS0 | iana.NotECNTransport
switch runtime.GOOS {
case "windows":
// IP_TOS option is supported on Windows 8 and beyond.
t.Skipf("not supported on %s", runtime.GOOS)
}
if err := c.SetTOS(tos); err != nil {
t.Fatal(err)
}
if v, err := c.TOS(); err != nil {
t.Fatal(err)
} else if v != tos {
t.Fatalf("got %v; want %v", v, tos)
}
const ttl = 255
if err := c.SetTTL(ttl); err != nil {
t.Fatal(err)
}
if v, err := c.TTL(); err != nil {
t.Fatal(err)
} else if v != ttl {
t.Fatalf("got %v; want %v", v, ttl)
}
}