lvm: setupLV wait device + go mod
This commit is contained in:
parent
10e72f18ae
commit
c62ddaf2e0
@ -144,6 +144,16 @@ func setupLV(volume config.VolumeDef) {
|
|||||||
run("lvcreate", "-L", volume.Size, "-n", volume.Name, "storage")
|
run("lvcreate", "-L", volume.Size, "-n", volume.Name, "storage")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wait the device link
|
||||||
|
devPath := "/dev/storage/" + volume.Name
|
||||||
|
for i := 0; i < 300; i++ {
|
||||||
|
_, err := os.Stat(devPath)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
args := make([]string, 0)
|
args := make([]string, 0)
|
||||||
|
|
||||||
switch volume.FS {
|
switch volume.FS {
|
||||||
@ -153,5 +163,5 @@ func setupLV(volume config.VolumeDef) {
|
|||||||
args = append(args, "-F")
|
args = append(args, "-F")
|
||||||
}
|
}
|
||||||
|
|
||||||
run("mkfs."+volume.FS, append(args, "/dev/storage/"+volume.Name)...)
|
run("mkfs."+volume.FS, append(args, devPath)...)
|
||||||
}
|
}
|
||||||
|
3
go.mod
3
go.mod
@ -2,7 +2,8 @@ module novit.nc/direktil/inits
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/sparrc/go-ping v0.0.0-20160208162908-416e72114cd1
|
github.com/sparrc/go-ping v0.0.0-20160208162908-416e72114cd1
|
||||||
golang.org/x/net v0.0.0-20180706051357-32a936f46389
|
golang.org/x/net v0.0.0-20180706051357-32a936f46389 // indirect
|
||||||
golang.org/x/sys v0.0.0-20180709060233-1b2967e3c290
|
golang.org/x/sys v0.0.0-20180709060233-1b2967e3c290
|
||||||
|
gopkg.in/yaml.v2 v2.2.1
|
||||||
novit.nc/direktil/pkg v0.0.0-20180706230842-852aa03280f9
|
novit.nc/direktil/pkg v0.0.0-20180706230842-852aa03280f9
|
||||||
)
|
)
|
||||||
|
7
go.sum
Normal file
7
go.sum
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
github.com/sparrc/go-ping v0.0.0-20160208162908-416e72114cd1/go.mod h1:eMyUVp6f/5jnzM+3zahzl7q6UXLbgSc3MKg/+ow9QW0=
|
||||||
|
github.com/ulikunitz/xz v0.5.4/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||||
|
golang.org/x/net v0.0.0-20180706051357-32a936f46389/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/sys v0.0.0-20180709060233-1b2967e3c290/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
novit.nc/direktil/pkg v0.0.0-20180706230842-852aa03280f9/go.mod h1:rbcL+fuxazzipTdJV8t9MW39YsdaK3pSvvhTdI9SXsc=
|
266
vendor/github.com/sparrc/go-ping/ping_test.go
generated
vendored
266
vendor/github.com/sparrc/go-ping/ping_test.go
generated
vendored
@ -1,266 +0,0 @@
|
|||||||
package ping
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"runtime/debug"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNewPingerValid(t *testing.T) {
|
|
||||||
p, err := NewPinger("www.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertEqualStrings(t, "www.google.com", p.Addr())
|
|
||||||
// DNS names should resolve into IP addresses
|
|
||||||
AssertNotEqualStrings(t, "www.google.com", p.IPAddr().String())
|
|
||||||
AssertTrue(t, isIPv4(p.IPAddr().IP))
|
|
||||||
AssertFalse(t, p.Privileged())
|
|
||||||
// Test that SetPrivileged works
|
|
||||||
p.SetPrivileged(true)
|
|
||||||
AssertTrue(t, p.Privileged())
|
|
||||||
// Test setting to ipv4 address
|
|
||||||
err = p.SetAddr("www.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv4(p.IPAddr().IP))
|
|
||||||
// Test setting to ipv6 address
|
|
||||||
err = p.SetAddr("ipv6.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv6(p.IPAddr().IP))
|
|
||||||
|
|
||||||
p, err = NewPinger("localhost")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertEqualStrings(t, "localhost", p.Addr())
|
|
||||||
// DNS names should resolve into IP addresses
|
|
||||||
AssertNotEqualStrings(t, "localhost", p.IPAddr().String())
|
|
||||||
AssertTrue(t, isIPv4(p.IPAddr().IP))
|
|
||||||
AssertFalse(t, p.Privileged())
|
|
||||||
// Test that SetPrivileged works
|
|
||||||
p.SetPrivileged(true)
|
|
||||||
AssertTrue(t, p.Privileged())
|
|
||||||
// Test setting to ipv4 address
|
|
||||||
err = p.SetAddr("www.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv4(p.IPAddr().IP))
|
|
||||||
// Test setting to ipv6 address
|
|
||||||
err = p.SetAddr("ipv6.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv6(p.IPAddr().IP))
|
|
||||||
|
|
||||||
p, err = NewPinger("127.0.0.1")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertEqualStrings(t, "127.0.0.1", p.Addr())
|
|
||||||
AssertTrue(t, isIPv4(p.IPAddr().IP))
|
|
||||||
AssertFalse(t, p.Privileged())
|
|
||||||
// Test that SetPrivileged works
|
|
||||||
p.SetPrivileged(true)
|
|
||||||
AssertTrue(t, p.Privileged())
|
|
||||||
// Test setting to ipv4 address
|
|
||||||
err = p.SetAddr("www.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv4(p.IPAddr().IP))
|
|
||||||
// Test setting to ipv6 address
|
|
||||||
err = p.SetAddr("ipv6.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv6(p.IPAddr().IP))
|
|
||||||
|
|
||||||
p, err = NewPinger("ipv6.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertEqualStrings(t, "ipv6.google.com", p.Addr())
|
|
||||||
// DNS names should resolve into IP addresses
|
|
||||||
AssertNotEqualStrings(t, "ipv6.google.com", p.IPAddr().String())
|
|
||||||
AssertTrue(t, isIPv6(p.IPAddr().IP))
|
|
||||||
AssertFalse(t, p.Privileged())
|
|
||||||
// Test that SetPrivileged works
|
|
||||||
p.SetPrivileged(true)
|
|
||||||
AssertTrue(t, p.Privileged())
|
|
||||||
// Test setting to ipv4 address
|
|
||||||
err = p.SetAddr("www.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv4(p.IPAddr().IP))
|
|
||||||
// Test setting to ipv6 address
|
|
||||||
err = p.SetAddr("ipv6.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv6(p.IPAddr().IP))
|
|
||||||
|
|
||||||
// ipv6 localhost:
|
|
||||||
p, err = NewPinger("::1")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertEqualStrings(t, "::1", p.Addr())
|
|
||||||
AssertTrue(t, isIPv6(p.IPAddr().IP))
|
|
||||||
AssertFalse(t, p.Privileged())
|
|
||||||
// Test that SetPrivileged works
|
|
||||||
p.SetPrivileged(true)
|
|
||||||
AssertTrue(t, p.Privileged())
|
|
||||||
// Test setting to ipv4 address
|
|
||||||
err = p.SetAddr("www.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv4(p.IPAddr().IP))
|
|
||||||
// Test setting to ipv6 address
|
|
||||||
err = p.SetAddr("ipv6.google.com")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertTrue(t, isIPv6(p.IPAddr().IP))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewPingerInvalid(t *testing.T) {
|
|
||||||
_, err := NewPinger("127.0.0.0.1")
|
|
||||||
AssertError(t, err, "127.0.0.0.1")
|
|
||||||
|
|
||||||
_, err = NewPinger("127..0.0.1")
|
|
||||||
AssertError(t, err, "127..0.0.1")
|
|
||||||
|
|
||||||
_, err = NewPinger("wtf")
|
|
||||||
AssertError(t, err, "wtf")
|
|
||||||
|
|
||||||
_, err = NewPinger(":::1")
|
|
||||||
AssertError(t, err, ":::1")
|
|
||||||
|
|
||||||
_, err = NewPinger("ipv5.google.com")
|
|
||||||
AssertError(t, err, "ipv5.google.com")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetIPAddr(t *testing.T) {
|
|
||||||
googleaddr, err := net.ResolveIPAddr("ip", "www.google.com")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Can't resolve www.google.com, can't run tests")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a localhost ipv4 pinger
|
|
||||||
p, err := NewPinger("localhost")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertEqualStrings(t, "localhost", p.Addr())
|
|
||||||
|
|
||||||
// set IPAddr to google
|
|
||||||
p.SetIPAddr(googleaddr)
|
|
||||||
AssertEqualStrings(t, googleaddr.String(), p.Addr())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStatisticsSunny(t *testing.T) {
|
|
||||||
// Create a localhost ipv4 pinger
|
|
||||||
p, err := NewPinger("localhost")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertEqualStrings(t, "localhost", p.Addr())
|
|
||||||
|
|
||||||
p.PacketsSent = 10
|
|
||||||
p.PacketsRecv = 10
|
|
||||||
p.rtts = []time.Duration{
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
}
|
|
||||||
|
|
||||||
stats := p.Statistics()
|
|
||||||
if stats.PacketsRecv != 10 {
|
|
||||||
t.Errorf("Expected %v, got %v", 10, stats.PacketsRecv)
|
|
||||||
}
|
|
||||||
if stats.PacketsSent != 10 {
|
|
||||||
t.Errorf("Expected %v, got %v", 10, stats.PacketsSent)
|
|
||||||
}
|
|
||||||
if stats.PacketLoss != 0 {
|
|
||||||
t.Errorf("Expected %v, got %v", 0, stats.PacketLoss)
|
|
||||||
}
|
|
||||||
if stats.MinRtt != time.Duration(1000) {
|
|
||||||
t.Errorf("Expected %v, got %v", time.Duration(1000), stats.MinRtt)
|
|
||||||
}
|
|
||||||
if stats.MaxRtt != time.Duration(1000) {
|
|
||||||
t.Errorf("Expected %v, got %v", time.Duration(1000), stats.MaxRtt)
|
|
||||||
}
|
|
||||||
if stats.AvgRtt != time.Duration(1000) {
|
|
||||||
t.Errorf("Expected %v, got %v", time.Duration(1000), stats.AvgRtt)
|
|
||||||
}
|
|
||||||
if stats.StdDevRtt != time.Duration(0) {
|
|
||||||
t.Errorf("Expected %v, got %v", time.Duration(0), stats.StdDevRtt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStatisticsLossy(t *testing.T) {
|
|
||||||
// Create a localhost ipv4 pinger
|
|
||||||
p, err := NewPinger("localhost")
|
|
||||||
AssertNoError(t, err)
|
|
||||||
AssertEqualStrings(t, "localhost", p.Addr())
|
|
||||||
|
|
||||||
p.PacketsSent = 20
|
|
||||||
p.PacketsRecv = 10
|
|
||||||
p.rtts = []time.Duration{
|
|
||||||
time.Duration(10),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(10000),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(800),
|
|
||||||
time.Duration(1000),
|
|
||||||
time.Duration(40),
|
|
||||||
time.Duration(100000),
|
|
||||||
time.Duration(1000),
|
|
||||||
}
|
|
||||||
|
|
||||||
stats := p.Statistics()
|
|
||||||
if stats.PacketsRecv != 10 {
|
|
||||||
t.Errorf("Expected %v, got %v", 10, stats.PacketsRecv)
|
|
||||||
}
|
|
||||||
if stats.PacketsSent != 20 {
|
|
||||||
t.Errorf("Expected %v, got %v", 20, stats.PacketsSent)
|
|
||||||
}
|
|
||||||
if stats.PacketLoss != 50 {
|
|
||||||
t.Errorf("Expected %v, got %v", 50, stats.PacketLoss)
|
|
||||||
}
|
|
||||||
if stats.MinRtt != time.Duration(10) {
|
|
||||||
t.Errorf("Expected %v, got %v", time.Duration(10), stats.MinRtt)
|
|
||||||
}
|
|
||||||
if stats.MaxRtt != time.Duration(100000) {
|
|
||||||
t.Errorf("Expected %v, got %v", time.Duration(100000), stats.MaxRtt)
|
|
||||||
}
|
|
||||||
if stats.AvgRtt != time.Duration(11585) {
|
|
||||||
t.Errorf("Expected %v, got %v", time.Duration(11585), stats.AvgRtt)
|
|
||||||
}
|
|
||||||
if stats.StdDevRtt != time.Duration(29603) {
|
|
||||||
t.Errorf("Expected %v, got %v", time.Duration(29603), stats.StdDevRtt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test helpers
|
|
||||||
func AssertNoError(t *testing.T, err error) {
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Expected No Error but got %s, Stack:\n%s",
|
|
||||||
err, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func AssertError(t *testing.T, err error, info string) {
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("Expected Error but got %s, %s, Stack:\n%s",
|
|
||||||
err, info, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func AssertEqualStrings(t *testing.T, expected, actual string) {
|
|
||||||
if expected != actual {
|
|
||||||
t.Errorf("Expected %s, got %s, Stack:\n%s",
|
|
||||||
expected, actual, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func AssertNotEqualStrings(t *testing.T, expected, actual string) {
|
|
||||||
if expected == actual {
|
|
||||||
t.Errorf("Expected %s, got %s, Stack:\n%s",
|
|
||||||
expected, actual, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func AssertTrue(t *testing.T, b bool) {
|
|
||||||
if !b {
|
|
||||||
t.Errorf("Expected True, got False, Stack:\n%s", string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func AssertFalse(t *testing.T, b bool) {
|
|
||||||
if b {
|
|
||||||
t.Errorf("Expected False, got True, Stack:\n%s", string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}
|
|
33
vendor/github.com/ulikunitz/xz/bits_test.go
generated
vendored
33
vendor/github.com/ulikunitz/xz/bits_test.go
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package xz
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestUvarint(t *testing.T) {
|
|
||||||
tests := []uint64{0, 0x80, 0x100, 0xffffffff, 0x100000000, 1<<64 - 1}
|
|
||||||
p := make([]byte, 10)
|
|
||||||
for _, u := range tests {
|
|
||||||
p = p[:10]
|
|
||||||
n := putUvarint(p, u)
|
|
||||||
if n < 1 {
|
|
||||||
t.Fatalf("putUvarint returned %d", n)
|
|
||||||
}
|
|
||||||
r := bytes.NewReader(p[:n])
|
|
||||||
x, m, err := readUvarint(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("readUvarint returned %s", err)
|
|
||||||
}
|
|
||||||
if m != n {
|
|
||||||
t.Fatalf("readUvarint read %d bytes; want %d", m, n)
|
|
||||||
}
|
|
||||||
if x != u {
|
|
||||||
t.Fatalf("readUvarint returned 0x%x; want 0x%x", x, u)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
142
vendor/github.com/ulikunitz/xz/format_test.go
generated
vendored
142
vendor/github.com/ulikunitz/xz/format_test.go
generated
vendored
@ -1,142 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package xz
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestHeader(t *testing.T) {
|
|
||||||
h := header{flags: CRC32}
|
|
||||||
data, err := h.MarshalBinary()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("MarshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
var g header
|
|
||||||
if err = g.UnmarshalBinary(data); err != nil {
|
|
||||||
t.Fatalf("UnmarshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
if g != h {
|
|
||||||
t.Fatalf("unmarshalled %#v; want %#v", g, h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFooter(t *testing.T) {
|
|
||||||
f := footer{indexSize: 64, flags: CRC32}
|
|
||||||
data, err := f.MarshalBinary()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("MarshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
var g footer
|
|
||||||
if err = g.UnmarshalBinary(data); err != nil {
|
|
||||||
t.Fatalf("UnmarshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
if g != f {
|
|
||||||
t.Fatalf("unmarshalled %#v; want %#v", g, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRecord(t *testing.T) {
|
|
||||||
r := record{1234567, 10000}
|
|
||||||
p, err := r.MarshalBinary()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("MarshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
n := len(p)
|
|
||||||
buf := bytes.NewReader(p)
|
|
||||||
g, m, err := readRecord(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("readFrom error %s", err)
|
|
||||||
}
|
|
||||||
if m != n {
|
|
||||||
t.Fatalf("read %d bytes; wrote %d", m, n)
|
|
||||||
}
|
|
||||||
if g.unpaddedSize != r.unpaddedSize {
|
|
||||||
t.Fatalf("got unpaddedSize %d; want %d", g.unpaddedSize,
|
|
||||||
r.unpaddedSize)
|
|
||||||
}
|
|
||||||
if g.uncompressedSize != r.uncompressedSize {
|
|
||||||
t.Fatalf("got uncompressedSize %d; want %d", g.uncompressedSize,
|
|
||||||
r.uncompressedSize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIndex(t *testing.T) {
|
|
||||||
records := []record{{1234, 1}, {2345, 2}}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
n, err := writeIndex(&buf, records)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("writeIndex error %s", err)
|
|
||||||
}
|
|
||||||
if n != int64(buf.Len()) {
|
|
||||||
t.Fatalf("writeIndex returned %d; want %d", n, buf.Len())
|
|
||||||
}
|
|
||||||
|
|
||||||
// indicator
|
|
||||||
c, err := buf.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("buf.ReadByte error %s", err)
|
|
||||||
}
|
|
||||||
if c != 0 {
|
|
||||||
t.Fatalf("indicator %d; want %d", c, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
g, m, err := readIndexBody(&buf)
|
|
||||||
if err != nil {
|
|
||||||
for i, r := range g {
|
|
||||||
t.Logf("records[%d] %v", i, r)
|
|
||||||
}
|
|
||||||
t.Fatalf("readIndexBody error %s", err)
|
|
||||||
}
|
|
||||||
if m != n-1 {
|
|
||||||
t.Fatalf("readIndexBody returned %d; want %d", m, n-1)
|
|
||||||
}
|
|
||||||
for i, rec := range records {
|
|
||||||
if g[i] != rec {
|
|
||||||
t.Errorf("records[%d] is %v; want %v", i, g[i], rec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBlockHeader(t *testing.T) {
|
|
||||||
h := blockHeader{
|
|
||||||
compressedSize: 1234,
|
|
||||||
uncompressedSize: -1,
|
|
||||||
filters: []filter{&lzmaFilter{4096}},
|
|
||||||
}
|
|
||||||
data, err := h.MarshalBinary()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("MarshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := bytes.NewReader(data)
|
|
||||||
g, n, err := readBlockHeader(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("readBlockHeader error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(data) {
|
|
||||||
t.Fatalf("readBlockHeader returns %d bytes; want %d", n,
|
|
||||||
len(data))
|
|
||||||
}
|
|
||||||
if g.compressedSize != h.compressedSize {
|
|
||||||
t.Errorf("got compressedSize %d; want %d",
|
|
||||||
g.compressedSize, h.compressedSize)
|
|
||||||
}
|
|
||||||
if g.uncompressedSize != h.uncompressedSize {
|
|
||||||
t.Errorf("got uncompressedSize %d; want %d",
|
|
||||||
g.uncompressedSize, h.uncompressedSize)
|
|
||||||
}
|
|
||||||
if len(g.filters) != len(h.filters) {
|
|
||||||
t.Errorf("got len(filters) %d; want %d",
|
|
||||||
len(g.filters), len(h.filters))
|
|
||||||
}
|
|
||||||
glf := g.filters[0].(*lzmaFilter)
|
|
||||||
hlf := h.filters[0].(*lzmaFilter)
|
|
||||||
if glf.dictCap != hlf.dictCap {
|
|
||||||
t.Errorf("got dictCap %d; want %d", glf.dictCap, hlf.dictCap)
|
|
||||||
}
|
|
||||||
}
|
|
30
vendor/github.com/ulikunitz/xz/internal/hash/cyclic_poly_test.go
generated
vendored
30
vendor/github.com/ulikunitz/xz/internal/hash/cyclic_poly_test.go
generated
vendored
@ -1,30 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package hash
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestCyclicPolySimple(t *testing.T) {
|
|
||||||
p := []byte("abcde")
|
|
||||||
r := NewCyclicPoly(4)
|
|
||||||
h2 := Hashes(r, p)
|
|
||||||
for i, h := range h2 {
|
|
||||||
w := Hashes(r, p[i:i+4])[0]
|
|
||||||
t.Logf("%d h=%#016x w=%#016x", i, h, w)
|
|
||||||
if h != w {
|
|
||||||
t.Errorf("rolling hash %d: %#016x; want %#016x",
|
|
||||||
i, h, w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkCyclicPoly(b *testing.B) {
|
|
||||||
p := makeBenchmarkBytes(4096)
|
|
||||||
r := NewCyclicPoly(4)
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
Hashes(r, p)
|
|
||||||
}
|
|
||||||
}
|
|
42
vendor/github.com/ulikunitz/xz/internal/hash/rabin_karp_test.go
generated
vendored
42
vendor/github.com/ulikunitz/xz/internal/hash/rabin_karp_test.go
generated
vendored
@ -1,42 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package hash
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestRabinKarpSimple(t *testing.T) {
|
|
||||||
p := []byte("abcde")
|
|
||||||
r := NewRabinKarp(4)
|
|
||||||
h2 := Hashes(r, p)
|
|
||||||
for i, h := range h2 {
|
|
||||||
w := Hashes(r, p[i:i+4])[0]
|
|
||||||
t.Logf("%d h=%#016x w=%#016x", i, h, w)
|
|
||||||
if h != w {
|
|
||||||
t.Errorf("rolling hash %d: %#016x; want %#016x",
|
|
||||||
i, h, w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeBenchmarkBytes(n int) []byte {
|
|
||||||
rnd := rand.New(rand.NewSource(42))
|
|
||||||
p := make([]byte, n)
|
|
||||||
for i := range p {
|
|
||||||
p[i] = byte(rnd.Uint32())
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkRabinKarp(b *testing.B) {
|
|
||||||
p := makeBenchmarkBytes(4096)
|
|
||||||
r := NewRabinKarp(4)
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
Hashes(r, p)
|
|
||||||
}
|
|
||||||
}
|
|
17590
vendor/github.com/ulikunitz/xz/internal/randtxt/englm3.go
generated
vendored
17590
vendor/github.com/ulikunitz/xz/internal/randtxt/englm3.go
generated
vendored
File diff suppressed because it is too large
Load Diff
82
vendor/github.com/ulikunitz/xz/internal/randtxt/groupreader.go
generated
vendored
82
vendor/github.com/ulikunitz/xz/internal/randtxt/groupreader.go
generated
vendored
@ -1,82 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package randtxt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GroupReader groups the incoming text in groups of 5, whereby the
|
|
||||||
// number of groups per line can be controlled.
|
|
||||||
type GroupReader struct {
|
|
||||||
R io.ByteReader
|
|
||||||
GroupsPerLine int
|
|
||||||
off int64
|
|
||||||
eof bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewGroupReader creates a new group reader.
|
|
||||||
func NewGroupReader(r io.Reader) *GroupReader {
|
|
||||||
return &GroupReader{R: bufio.NewReader(r)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read formats the data provided by the internal reader in groups of 5
|
|
||||||
// characters. If GroupsPerLine hasn't been initialized 8 groups per
|
|
||||||
// line will be produced.
|
|
||||||
func (r *GroupReader) Read(p []byte) (n int, err error) {
|
|
||||||
if r.eof {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
groupsPerLine := r.GroupsPerLine
|
|
||||||
if groupsPerLine < 1 {
|
|
||||||
groupsPerLine = 8
|
|
||||||
}
|
|
||||||
lineLen := int64(groupsPerLine * 6)
|
|
||||||
var c byte
|
|
||||||
for i := range p {
|
|
||||||
switch {
|
|
||||||
case r.off%lineLen == lineLen-1:
|
|
||||||
if i+1 == len(p) && len(p) > 1 {
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
c = '\n'
|
|
||||||
case r.off%6 == 5:
|
|
||||||
if i+1 == len(p) && len(p) > 1 {
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
c = ' '
|
|
||||||
default:
|
|
||||||
c, err = r.R.ReadByte()
|
|
||||||
if err == io.EOF {
|
|
||||||
r.eof = true
|
|
||||||
if i > 0 {
|
|
||||||
switch p[i-1] {
|
|
||||||
case ' ':
|
|
||||||
p[i-1] = '\n'
|
|
||||||
fallthrough
|
|
||||||
case '\n':
|
|
||||||
return i, io.EOF
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p[i] = '\n'
|
|
||||||
return i + 1, io.EOF
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case c == ' ':
|
|
||||||
c = '_'
|
|
||||||
case !unicode.IsPrint(rune(c)):
|
|
||||||
c = '-'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p[i] = c
|
|
||||||
r.off++
|
|
||||||
}
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
185
vendor/github.com/ulikunitz/xz/internal/randtxt/probs.go
generated
vendored
185
vendor/github.com/ulikunitz/xz/internal/randtxt/probs.go
generated
vendored
@ -1,185 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package randtxt supports the generation of random text using a
|
|
||||||
// trigram model for the English language.
|
|
||||||
package randtxt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
"math/rand"
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ngram stores an entry from the language model.
|
|
||||||
type ngram struct {
|
|
||||||
s string
|
|
||||||
lgP float64
|
|
||||||
lgQ float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// ngrams represents a slice of ngram values and is used to represent a
|
|
||||||
// language model.
|
|
||||||
type ngrams []ngram
|
|
||||||
|
|
||||||
func (s ngrams) Len() int { return len(s) }
|
|
||||||
func (s ngrams) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
||||||
func (s ngrams) Less(i, j int) bool { return s[i].s < s[j].s }
|
|
||||||
|
|
||||||
// Sorts the language model in the sequence of their ngrams.
|
|
||||||
func (s ngrams) Sort() { sort.Sort(s) }
|
|
||||||
|
|
||||||
// Search is looking for an ngram or the position where it would be
|
|
||||||
// inserted.
|
|
||||||
func (s ngrams) Search(g string) int {
|
|
||||||
return sort.Search(len(s), func(k int) bool { return s[k].s >= g })
|
|
||||||
}
|
|
||||||
|
|
||||||
// prob represents a string, usually an ngram, and a probability value.
|
|
||||||
type prob struct {
|
|
||||||
s string
|
|
||||||
p float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// probs is a slice of prob values that can be sorted and searched.
|
|
||||||
type probs []prob
|
|
||||||
|
|
||||||
func (s probs) Len() int { return len(s) }
|
|
||||||
func (s probs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
||||||
func (s probs) Less(i, j int) bool { return s[i].s < s[j].s }
|
|
||||||
|
|
||||||
// SortByNgram sorts the probs slice by ngram, field s.
|
|
||||||
func (s probs) SortByNgram() { sort.Sort(s) }
|
|
||||||
|
|
||||||
// SortsByProb sorts the probs slice by probability, field p.
|
|
||||||
func (s probs) SortByProb() { sort.Sort(byProb{s}) }
|
|
||||||
|
|
||||||
// SearchNgram searches for an ngram or the position where it would be
|
|
||||||
// inserted.
|
|
||||||
func (s probs) SearchNgram(g string) int {
|
|
||||||
return sort.Search(len(s), func(k int) bool { return s[k].s >= g })
|
|
||||||
}
|
|
||||||
|
|
||||||
// SearchProb searches ngrams for a specific probability or where it
|
|
||||||
// would be inserted.
|
|
||||||
func (s probs) SearchProb(p float64) int {
|
|
||||||
return sort.Search(len(s), func(k int) bool { return s[k].p >= p })
|
|
||||||
}
|
|
||||||
|
|
||||||
// byProb is used to sort probs slice by probability, field p.
|
|
||||||
type byProb struct {
|
|
||||||
probs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s byProb) Less(i, j int) bool {
|
|
||||||
return s.probs[i].p < s.probs[j].p
|
|
||||||
}
|
|
||||||
|
|
||||||
// cdf can be used to setup a cumulative distribution function
|
|
||||||
// represented by a probs slice. We should have returned an actual
|
|
||||||
// function.
|
|
||||||
func cdf(n int, p func(i int) prob) probs {
|
|
||||||
prs := make(probs, n)
|
|
||||||
sum := 0.0
|
|
||||||
for i := range prs {
|
|
||||||
pr := p(i)
|
|
||||||
sum += pr.p
|
|
||||||
prs[i] = pr
|
|
||||||
}
|
|
||||||
q := 1.0 / sum
|
|
||||||
x := 0.0
|
|
||||||
for i, pr := range prs {
|
|
||||||
x += pr.p * q
|
|
||||||
if x > 1.0 {
|
|
||||||
x = 1.0
|
|
||||||
}
|
|
||||||
prs[i].p = x
|
|
||||||
}
|
|
||||||
if !sort.IsSorted(byProb{prs}) {
|
|
||||||
panic("cdf not sorted")
|
|
||||||
}
|
|
||||||
return prs
|
|
||||||
}
|
|
||||||
|
|
||||||
// pCDFOfLM converts a language model into a cumulative distribution
|
|
||||||
// function represented by probs.
|
|
||||||
func pCDFOfLM(lm ngrams) probs {
|
|
||||||
return cdf(len(lm), func(i int) prob {
|
|
||||||
return prob{lm[i].s, math.Exp2(lm[i].lgP)}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// cCDF converts a ngrams slice into a cumulative distribution function
|
|
||||||
// using the conditional probability lgQ.
|
|
||||||
func cCDF(s ngrams) probs {
|
|
||||||
return cdf(len(s), func(i int) prob {
|
|
||||||
return prob{s[i].s, math.Exp2(s[i].lgQ)}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// comap contains a map of conditional distribution function for the
|
|
||||||
// last character.
|
|
||||||
type comap map[string]probs
|
|
||||||
|
|
||||||
// comapOfLM converts a language model in a map of conditional
|
|
||||||
// distribution functions.
|
|
||||||
func comapOfLM(lm ngrams) comap {
|
|
||||||
if !sort.IsSorted(lm) {
|
|
||||||
panic("lm is not sorted")
|
|
||||||
}
|
|
||||||
m := make(comap, 26*26)
|
|
||||||
for i := 0; i < len(lm); {
|
|
||||||
j := i
|
|
||||||
g := lm[i].s
|
|
||||||
g2 := g[:2]
|
|
||||||
z := g2 + "Z"
|
|
||||||
i = lm.Search(z)
|
|
||||||
if i >= len(lm) || lm[i].s != z {
|
|
||||||
panic("unexpected search result")
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
m[g2] = cCDF(lm[j:i])
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigram returns the trigram with prefix g2 using a probability value
|
|
||||||
// in the range [0.0,1.0).
|
|
||||||
func (c comap) trigram(g2 string, p float64) string {
|
|
||||||
prs := c[g2]
|
|
||||||
i := prs.SearchProb(p)
|
|
||||||
return prs[i].s
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// CDF for normal probabilities
|
|
||||||
pcdf = pCDFOfLM(englm3)
|
|
||||||
// map of two letter conditionals
|
|
||||||
cmap = comapOfLM(englm3)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reader generates a stream of text of uppercase letters with trigrams
|
|
||||||
// distributed according to a language model of the English language.
|
|
||||||
type Reader struct {
|
|
||||||
rnd *rand.Rand
|
|
||||||
g3 string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewReader creates a new reader. The argument src must create a uniformly
|
|
||||||
// distributed stream of random values.
|
|
||||||
func NewReader(src rand.Source) *Reader {
|
|
||||||
rnd := rand.New(src)
|
|
||||||
i := pcdf.SearchProb(rnd.Float64())
|
|
||||||
return &Reader{rnd, pcdf[i].s}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads random text. The Read function will always return len(p)
|
|
||||||
// bytes and will never return an error.
|
|
||||||
func (r *Reader) Read(p []byte) (n int, err error) {
|
|
||||||
for i := range p {
|
|
||||||
r.g3 = cmap.trigram(r.g3[1:], r.rnd.Float64())
|
|
||||||
p[i] = r.g3[2]
|
|
||||||
}
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
37
vendor/github.com/ulikunitz/xz/internal/randtxt/probs_test.go
generated
vendored
37
vendor/github.com/ulikunitz/xz/internal/randtxt/probs_test.go
generated
vendored
@ -1,37 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package randtxt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
"math/rand"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestReader(t *testing.T) {
|
|
||||||
lr := io.LimitReader(NewReader(rand.NewSource(13)), 195)
|
|
||||||
pretty := NewGroupReader(lr)
|
|
||||||
scanner := bufio.NewScanner(pretty)
|
|
||||||
for scanner.Scan() {
|
|
||||||
t.Log(scanner.Text())
|
|
||||||
}
|
|
||||||
if err := scanner.Err(); err != nil {
|
|
||||||
t.Fatalf("scanner error %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestComap(t *testing.T) {
|
|
||||||
prs := cmap["TH"]
|
|
||||||
for _, p := range prs[3:6] {
|
|
||||||
t.Logf("%v", p)
|
|
||||||
}
|
|
||||||
p := 0.2
|
|
||||||
x := cmap.trigram("TH", p)
|
|
||||||
if x != "THE" {
|
|
||||||
t.Fatalf("cmap.trigram(%q, %.1f) returned %q; want %q",
|
|
||||||
"TH", p, x, "THE")
|
|
||||||
}
|
|
||||||
}
|
|
107
vendor/github.com/ulikunitz/xz/lzma/bintree_test.go
generated
vendored
107
vendor/github.com/ulikunitz/xz/lzma/bintree_test.go
generated
vendored
@ -1,107 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"math/rand"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ulikunitz/xz/internal/randtxt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBinTree_Find(t *testing.T) {
|
|
||||||
bt, err := newBinTree(30)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
const s = "Klopp feiert mit Liverpool seinen hoechsten SiegSieg"
|
|
||||||
n, err := io.WriteString(bt, s)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriteString error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(s) {
|
|
||||||
t.Fatalf("WriteString returned %d; want %d", n, len(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dump info writes the complete tree
|
|
||||||
if err = bt.dump(os.Stdout); err != nil {
|
|
||||||
t.Fatalf("bt.dump error %s", err)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
tests := []string{"Sieg", "Sieb", "Simu"}
|
|
||||||
for _, c := range tests {
|
|
||||||
x := xval([]byte(c))
|
|
||||||
a, b := bt.search(bt.root, x)
|
|
||||||
t.Logf("%q: a, b == %d, %d", c, a, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBinTree_PredSucc(t *testing.T) {
|
|
||||||
bt, err := newBinTree(30)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
const s = "Klopp feiert mit Liverpool seinen hoechsten Sieg."
|
|
||||||
n, err := io.WriteString(bt, s)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriteString error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(s) {
|
|
||||||
t.Fatalf("WriteString returned %d; want %d", n, len(s))
|
|
||||||
}
|
|
||||||
for v := bt.min(bt.root); v != null; v = bt.succ(v) {
|
|
||||||
t.Log(dumpX(bt.node[v].x))
|
|
||||||
}
|
|
||||||
t.Log("")
|
|
||||||
for v := bt.max(bt.root); v != null; v = bt.pred(v) {
|
|
||||||
t.Log(dumpX(bt.node[v].x))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBinTree_Cycle(t *testing.T) {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
w, err := Writer2Config{
|
|
||||||
DictCap: 4096,
|
|
||||||
Matcher: BinaryTree,
|
|
||||||
}.NewWriter2(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
// const txtlen = 1024
|
|
||||||
const txtlen = 10000
|
|
||||||
io.CopyN(buf, randtxt.NewReader(rand.NewSource(42)), txtlen)
|
|
||||||
txt := buf.String()
|
|
||||||
buf.Reset()
|
|
||||||
n, err := io.Copy(w, strings.NewReader(txt))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Compressing copy error %s", err)
|
|
||||||
}
|
|
||||||
if n != txtlen {
|
|
||||||
t.Fatalf("Compressing data length %d; want %d", n, txtlen)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("buf.Len() %d", buf.Len())
|
|
||||||
r, err := Reader2Config{DictCap: 4096}.NewReader2(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
out := new(bytes.Buffer)
|
|
||||||
n, err = io.Copy(out, r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Decompressing copy error %s after %d bytes", err, n)
|
|
||||||
}
|
|
||||||
if n != txtlen {
|
|
||||||
t.Fatalf("Decompression data length %d; want %d", n, txtlen)
|
|
||||||
}
|
|
||||||
if txt != out.String() {
|
|
||||||
t.Fatal("decompressed data differs from original")
|
|
||||||
}
|
|
||||||
}
|
|
230
vendor/github.com/ulikunitz/xz/lzma/buffer_test.go
generated
vendored
230
vendor/github.com/ulikunitz/xz/lzma/buffer_test.go
generated
vendored
@ -1,230 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBuffer_Write(t *testing.T) {
|
|
||||||
buf := newBuffer(10)
|
|
||||||
b := []byte("1234567890")
|
|
||||||
for i := range b {
|
|
||||||
n, err := buf.Write(b[i : i+1])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("buf.Write(b[%d:%d]) error %s", i, i+1, err)
|
|
||||||
}
|
|
||||||
if n != 1 {
|
|
||||||
t.Fatalf("buf.Write(b[%d:%d]) returned %d; want %d",
|
|
||||||
i, i+1, n, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const c = 8
|
|
||||||
n, err := buf.Discard(c)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Discard error %s", err)
|
|
||||||
}
|
|
||||||
if n != c {
|
|
||||||
t.Fatalf("Discard returned %d; want %d", n, c)
|
|
||||||
}
|
|
||||||
n, err = buf.Write(b)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("Write length exceed returned no error; n %d", n)
|
|
||||||
}
|
|
||||||
if n != c {
|
|
||||||
t.Fatalf("Write length exceeding returned %d; want %d", n, c)
|
|
||||||
}
|
|
||||||
n, err = buf.Discard(4)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Discard error %s", err)
|
|
||||||
}
|
|
||||||
if n != 4 {
|
|
||||||
t.Fatalf("Discard returned %d; want %d", n, 4)
|
|
||||||
}
|
|
||||||
n, err = buf.Write(b[:3])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("buf.Write(b[:3]) error %s; n %d", err, n)
|
|
||||||
}
|
|
||||||
if n != 3 {
|
|
||||||
t.Fatalf("buf.Write(b[:3]) returned %d; want %d", n, 3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBuffer_Buffered_Available(t *testing.T) {
|
|
||||||
buf := newBuffer(19)
|
|
||||||
b := []byte("0123456789")
|
|
||||||
var err error
|
|
||||||
if _, err = buf.Write(b); err != nil {
|
|
||||||
t.Fatalf("buf.Write(b) error %s", err)
|
|
||||||
}
|
|
||||||
if n := buf.Buffered(); n != 10 {
|
|
||||||
t.Fatalf("buf.Buffered() returns %d; want %d", n, 10)
|
|
||||||
}
|
|
||||||
if _, err = buf.Discard(8); err != nil {
|
|
||||||
t.Fatalf("buf.Discard(8) error %s", err)
|
|
||||||
}
|
|
||||||
if _, err = buf.Write(b[:7]); err != nil {
|
|
||||||
t.Fatalf("buf.Write(b[:7]) error %s", err)
|
|
||||||
}
|
|
||||||
if n := buf.Buffered(); n != 9 {
|
|
||||||
t.Fatalf("buf.Buffered() returns %d; want %d", n, 9)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBuffer_Read(t *testing.T) {
|
|
||||||
buf := newBuffer(10)
|
|
||||||
b := []byte("0123456789")
|
|
||||||
var err error
|
|
||||||
if _, err = buf.Write(b); err != nil {
|
|
||||||
t.Fatalf("buf.Write(b) error %s", err)
|
|
||||||
}
|
|
||||||
p := make([]byte, 8)
|
|
||||||
n, err := buf.Read(p)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("buf.Read(p) error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(p) {
|
|
||||||
t.Fatalf("buf.Read(p) returned %d; want %d", n, len(p))
|
|
||||||
}
|
|
||||||
if !bytes.Equal(p, b[:8]) {
|
|
||||||
t.Fatalf("buf.Read(p) put %s into p; want %s", p, b[:8])
|
|
||||||
}
|
|
||||||
if _, err = buf.Write(b[:7]); err != nil {
|
|
||||||
t.Fatalf("buf.Write(b[:7]) error %s", err)
|
|
||||||
}
|
|
||||||
q := make([]byte, 7)
|
|
||||||
n, err = buf.Read(q)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("buf.Read(q) error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(q) {
|
|
||||||
t.Fatalf("buf.Read(q) returns %d; want %d", n, len(q))
|
|
||||||
}
|
|
||||||
c := []byte("8901234")
|
|
||||||
if !bytes.Equal(q, c) {
|
|
||||||
t.Fatalf("buf.Read(q) put %s into q; want %s", q, c)
|
|
||||||
}
|
|
||||||
if _, err := buf.Write(b[7:]); err != nil {
|
|
||||||
t.Fatalf("buf.Write(b[7:]) error %s", err)
|
|
||||||
}
|
|
||||||
if _, err := buf.Write(b[:2]); err != nil {
|
|
||||||
t.Fatalf("buf.Write(b[:2]) error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("buf.rear %d buf.front %d", buf.rear, buf.front)
|
|
||||||
r := make([]byte, 2)
|
|
||||||
n, err = buf.Read(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("buf.Read(r) error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(r) {
|
|
||||||
t.Fatalf("buf.Read(r) returns %d; want %d", n, len(r))
|
|
||||||
}
|
|
||||||
d := []byte("56")
|
|
||||||
if !bytes.Equal(r, d) {
|
|
||||||
t.Fatalf("buf.Read(r) put %s into r; want %s", r, d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBuffer_Discard(t *testing.T) {
|
|
||||||
buf := newBuffer(10)
|
|
||||||
b := []byte("0123456789")
|
|
||||||
var err error
|
|
||||||
if _, err = buf.Write(b); err != nil {
|
|
||||||
t.Fatalf("buf.Write(b) error %s", err)
|
|
||||||
}
|
|
||||||
n, err := buf.Discard(11)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("buf.Discard(11) didn't return error")
|
|
||||||
}
|
|
||||||
if n != 10 {
|
|
||||||
t.Fatalf("buf.Discard(11) returned %d; want %d", n, 10)
|
|
||||||
}
|
|
||||||
if _, err := buf.Write(b); err != nil {
|
|
||||||
t.Fatalf("buf.Write(b) #2 error %s", err)
|
|
||||||
}
|
|
||||||
n, err = buf.Discard(10)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("buf.Discard(10) error %s", err)
|
|
||||||
}
|
|
||||||
if n != 10 {
|
|
||||||
t.Fatalf("buf.Discard(11) returned %d; want %d", n, 10)
|
|
||||||
}
|
|
||||||
if _, err := buf.Write(b[:4]); err != nil {
|
|
||||||
t.Fatalf("buf.Write(b[:4]) error %s", err)
|
|
||||||
}
|
|
||||||
n, err = buf.Discard(1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("buf.Discard(1) error %s", err)
|
|
||||||
}
|
|
||||||
if n != 1 {
|
|
||||||
t.Fatalf("buf.Discard(1) returned %d; want %d", n, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBuffer_Discard_error(t *testing.T) {
|
|
||||||
buf := newBuffer(10)
|
|
||||||
n, err := buf.Discard(-1)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("buf.Discard(-1) didn't return an error")
|
|
||||||
}
|
|
||||||
if n != 0 {
|
|
||||||
t.Fatalf("buf.Discard(-1) returned %d; want %d", n, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPrefixLen(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
a, b []byte
|
|
||||||
k int
|
|
||||||
}{
|
|
||||||
{[]byte("abcde"), []byte("abc"), 3},
|
|
||||||
{[]byte("abc"), []byte("uvw"), 0},
|
|
||||||
{[]byte(""), []byte("uvw"), 0},
|
|
||||||
{[]byte("abcde"), []byte("abcuvw"), 3},
|
|
||||||
}
|
|
||||||
for _, c := range tests {
|
|
||||||
k := prefixLen(c.a, c.b)
|
|
||||||
if k != c.k {
|
|
||||||
t.Errorf("prefixLen(%q,%q) returned %d; want %d",
|
|
||||||
c.a, c.b, k, c.k)
|
|
||||||
}
|
|
||||||
k = prefixLen(c.b, c.a)
|
|
||||||
if k != c.k {
|
|
||||||
t.Errorf("prefixLen(%q,%q) returned %d; want %d",
|
|
||||||
c.b, c.a, k, c.k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMatchLen(t *testing.T) {
|
|
||||||
buf := newBuffer(13)
|
|
||||||
const s = "abcaba"
|
|
||||||
_, err := io.WriteString(buf, s)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriteString error %s", err)
|
|
||||||
}
|
|
||||||
_, err = io.WriteString(buf, s)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriteString error %s", err)
|
|
||||||
}
|
|
||||||
if _, err = buf.Discard(12); err != nil {
|
|
||||||
t.Fatalf("buf.Discard(6) error %s", err)
|
|
||||||
}
|
|
||||||
_, err = io.WriteString(buf, s)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriteString error %s", err)
|
|
||||||
}
|
|
||||||
tests := []struct{ d, n int }{{1, 1}, {3, 2}, {6, 6}, {5, 0}, {2, 0}}
|
|
||||||
for _, c := range tests {
|
|
||||||
n := buf.matchLen(c.d, []byte(s))
|
|
||||||
if n != c.n {
|
|
||||||
t.Errorf(
|
|
||||||
"MatchLen(%d,[]byte(%q)) returned %d; want %d",
|
|
||||||
c.d, s, n, c.n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
59
vendor/github.com/ulikunitz/xz/lzma/decoder_test.go
generated
vendored
59
vendor/github.com/ulikunitz/xz/lzma/decoder_test.go
generated
vendored
@ -1,59 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDecoder(t *testing.T) {
|
|
||||||
filename := "fox.lzma"
|
|
||||||
want := "The quick brown fox jumps over the lazy dog.\n"
|
|
||||||
for i := 0; i < 2; i++ {
|
|
||||||
f, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("os.Open(%q) error %s", filename, err)
|
|
||||||
}
|
|
||||||
p := make([]byte, 13)
|
|
||||||
_, err = io.ReadFull(f, p)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("io.ReadFull error %s", err)
|
|
||||||
}
|
|
||||||
props, err := PropertiesForCode(p[0])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("p[0] error %s", err)
|
|
||||||
}
|
|
||||||
state := newState(props)
|
|
||||||
const capacity = 0x800000
|
|
||||||
dict, err := newDecoderDict(capacity)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("newDecoderDict: error %s", err)
|
|
||||||
}
|
|
||||||
size := int64(-1)
|
|
||||||
if i > 0 {
|
|
||||||
size = int64(len(want))
|
|
||||||
}
|
|
||||||
br := bufio.NewReader(f)
|
|
||||||
r, err := newDecoder(br, state, dict, size)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("newDecoder error %s", err)
|
|
||||||
}
|
|
||||||
bytes, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("[%d] ReadAll error %s", i, err)
|
|
||||||
}
|
|
||||||
if err = f.Close(); err != nil {
|
|
||||||
t.Fatalf("Close error %s", err)
|
|
||||||
}
|
|
||||||
got := string(bytes)
|
|
||||||
if got != want {
|
|
||||||
t.Fatalf("read %q; but want %q", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
33
vendor/github.com/ulikunitz/xz/lzma/decoderdict_test.go
generated
vendored
33
vendor/github.com/ulikunitz/xz/lzma/decoderdict_test.go
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func peek(d *decoderDict) []byte {
|
|
||||||
p := make([]byte, d.buffered())
|
|
||||||
k, err := d.peek(p)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Errorf("peek: "+
|
|
||||||
"Read returned unexpected error %s", err))
|
|
||||||
}
|
|
||||||
if k != len(p) {
|
|
||||||
panic(fmt.Errorf("peek: "+
|
|
||||||
"Read returned %d; wanted %d", k, len(p)))
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewDecoderDict(t *testing.T) {
|
|
||||||
if _, err := newDecoderDict(0); err == nil {
|
|
||||||
t.Fatalf("no error for zero dictionary capacity")
|
|
||||||
}
|
|
||||||
if _, err := newDecoderDict(8); err != nil {
|
|
||||||
t.Fatalf("error %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
151
vendor/github.com/ulikunitz/xz/lzma/encoder_test.go
generated
vendored
151
vendor/github.com/ulikunitz/xz/lzma/encoder_test.go
generated
vendored
@ -1,151 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"math/rand"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ulikunitz/xz/internal/randtxt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var testString = `LZMA decoder test example
|
|
||||||
=========================
|
|
||||||
! LZMA ! Decoder ! TEST !
|
|
||||||
=========================
|
|
||||||
! TEST ! LZMA ! Decoder !
|
|
||||||
=========================
|
|
||||||
---- Test Line 1 --------
|
|
||||||
=========================
|
|
||||||
---- Test Line 2 --------
|
|
||||||
=========================
|
|
||||||
=== End of test file ====
|
|
||||||
=========================
|
|
||||||
`
|
|
||||||
|
|
||||||
func cycle(t *testing.T, n int) {
|
|
||||||
t.Logf("cycle(t,%d)", n)
|
|
||||||
if n > len(testString) {
|
|
||||||
t.Fatalf("cycle: n=%d larger than len(testString)=%d", n,
|
|
||||||
len(testString))
|
|
||||||
}
|
|
||||||
const dictCap = MinDictCap
|
|
||||||
m, err := newHashTable(dictCap, 4)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
encoderDict, err := newEncoderDict(dictCap, dictCap+1024, m)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
props := Properties{2, 0, 2}
|
|
||||||
if err := props.verify(); err != nil {
|
|
||||||
t.Fatalf("properties error %s", err)
|
|
||||||
}
|
|
||||||
state := newState(props)
|
|
||||||
var buf bytes.Buffer
|
|
||||||
w, err := newEncoder(&buf, state, encoderDict, eosMarker)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("newEncoder error %s", err)
|
|
||||||
}
|
|
||||||
orig := []byte(testString)[:n]
|
|
||||||
t.Logf("len(orig) %d", len(orig))
|
|
||||||
k, err := w.Write(orig)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("w.Write error %s", err)
|
|
||||||
}
|
|
||||||
if k != len(orig) {
|
|
||||||
t.Fatalf("w.Write returned %d; want %d", k, len(orig))
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("buf.Len() %d len(orig) %d", buf.Len(), len(orig))
|
|
||||||
decoderDict, err := newDecoderDict(dictCap)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("newDecoderDict error %s", err)
|
|
||||||
}
|
|
||||||
state.Reset()
|
|
||||||
r, err := newDecoder(&buf, state, decoderDict, -1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("newDecoder error %s", err)
|
|
||||||
}
|
|
||||||
decoded, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadAll(lr) error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("decoded: %s", decoded)
|
|
||||||
if len(orig) != len(decoded) {
|
|
||||||
t.Fatalf("length decoded is %d; want %d", len(decoded),
|
|
||||||
len(orig))
|
|
||||||
}
|
|
||||||
if !bytes.Equal(orig, decoded) {
|
|
||||||
t.Fatalf("decoded file differs from original")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEncoderCycle1(t *testing.T) {
|
|
||||||
cycle(t, len(testString))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEncoderCycle2(t *testing.T) {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
const txtlen = 50000
|
|
||||||
io.CopyN(buf, randtxt.NewReader(rand.NewSource(42)), txtlen)
|
|
||||||
txt := buf.String()
|
|
||||||
buf.Reset()
|
|
||||||
const dictCap = MinDictCap
|
|
||||||
m, err := newHashTable(dictCap, 4)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
encoderDict, err := newEncoderDict(dictCap, dictCap+1024, m)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
props := Properties{3, 0, 2}
|
|
||||||
if err := props.verify(); err != nil {
|
|
||||||
t.Fatalf("properties error %s", err)
|
|
||||||
}
|
|
||||||
state := newState(props)
|
|
||||||
lbw := &LimitedByteWriter{BW: buf, N: 100}
|
|
||||||
w, err := newEncoder(lbw, state, encoderDict, 0)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewEncoder error %s", err)
|
|
||||||
}
|
|
||||||
_, err = io.WriteString(w, txt)
|
|
||||||
if err != nil && err != ErrLimit {
|
|
||||||
t.Fatalf("WriteString error %s", err)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
n := w.Compressed()
|
|
||||||
txt = txt[:n]
|
|
||||||
decoderDict, err := newDecoderDict(dictCap)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewDecoderDict error %s", err)
|
|
||||||
}
|
|
||||||
state.Reset()
|
|
||||||
r, err := newDecoder(buf, state, decoderDict, n)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewDecoder error %s", err)
|
|
||||||
}
|
|
||||||
out := new(bytes.Buffer)
|
|
||||||
if _, err = io.Copy(out, r); err != nil {
|
|
||||||
t.Fatalf("decompress copy error %s", err)
|
|
||||||
}
|
|
||||||
got := out.String()
|
|
||||||
t.Logf("%s", got)
|
|
||||||
if len(got) != int(n) {
|
|
||||||
t.Fatalf("len(got) %d; want %d", len(got), n)
|
|
||||||
}
|
|
||||||
if got != txt {
|
|
||||||
t.Fatalf("got and txt differ")
|
|
||||||
}
|
|
||||||
}
|
|
47
vendor/github.com/ulikunitz/xz/lzma/hashtable_test.go
generated
vendored
47
vendor/github.com/ulikunitz/xz/lzma/hashtable_test.go
generated
vendored
@ -1,47 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestHashTable(t *testing.T) {
|
|
||||||
ht, err := newHashTable(32, 2)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("newHashTable: error %s", err)
|
|
||||||
}
|
|
||||||
// 01234567890123456
|
|
||||||
s := "abcabcdefghijklmn"
|
|
||||||
n, err := ht.Write([]byte(s))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ht.Write: error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(s) {
|
|
||||||
t.Fatalf("ht.Write returned %d; want %d", n, len(s))
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
s string
|
|
||||||
w string
|
|
||||||
}{
|
|
||||||
{"ab", "[3 0]"},
|
|
||||||
{"bc", "[4 1]"},
|
|
||||||
{"ca", "[2]"},
|
|
||||||
{"xx", "[]"},
|
|
||||||
{"gh", "[9]"},
|
|
||||||
{"mn", "[15]"},
|
|
||||||
}
|
|
||||||
distances := make([]int64, 20)
|
|
||||||
for _, c := range tests {
|
|
||||||
distances := distances[:20]
|
|
||||||
k := ht.Matches([]byte(c.s), distances)
|
|
||||||
distances = distances[:k]
|
|
||||||
o := fmt.Sprintf("%v", distances)
|
|
||||||
if o != c.w {
|
|
||||||
t.Errorf("%s: offsets %s; want %s", c.s, o, c.w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
153
vendor/github.com/ulikunitz/xz/lzma/header2_test.go
generated
vendored
153
vendor/github.com/ulikunitz/xz/lzma/header2_test.go
generated
vendored
@ -1,153 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestChunkTypeString(t *testing.T) {
|
|
||||||
tests := [...]struct {
|
|
||||||
c chunkType
|
|
||||||
s string
|
|
||||||
}{
|
|
||||||
{cEOS, "EOS"},
|
|
||||||
{cUD, "UD"},
|
|
||||||
{cU, "U"},
|
|
||||||
{cL, "L"},
|
|
||||||
{cLR, "LR"},
|
|
||||||
{cLRN, "LRN"},
|
|
||||||
{cLRND, "LRND"},
|
|
||||||
}
|
|
||||||
for _, c := range tests {
|
|
||||||
s := fmt.Sprintf("%v", c.c)
|
|
||||||
if s != c.s {
|
|
||||||
t.Errorf("got %s; want %s", s, c.s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHeaderChunkType(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
h byte
|
|
||||||
c chunkType
|
|
||||||
}{
|
|
||||||
{h: 0, c: cEOS},
|
|
||||||
{h: 1, c: cUD},
|
|
||||||
{h: 2, c: cU},
|
|
||||||
{h: 1<<7 | 0x1f, c: cL},
|
|
||||||
{h: 1<<7 | 1<<5 | 0x1f, c: cLR},
|
|
||||||
{h: 1<<7 | 1<<6 | 0x1f, c: cLRN},
|
|
||||||
{h: 1<<7 | 1<<6 | 1<<5 | 0x1f, c: cLRND},
|
|
||||||
{h: 1<<7 | 1<<6 | 1<<5, c: cLRND},
|
|
||||||
}
|
|
||||||
if _, err := headerChunkType(3); err == nil {
|
|
||||||
t.Fatalf("headerChunkType(%d) got %v; want %v",
|
|
||||||
3, err, errHeaderByte)
|
|
||||||
}
|
|
||||||
for _, tc := range tests {
|
|
||||||
c, err := headerChunkType(tc.h)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("headerChunkType error %s", err)
|
|
||||||
}
|
|
||||||
if c != tc.c {
|
|
||||||
t.Errorf("got %s; want %s", c, tc.c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHeaderLen(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
c chunkType
|
|
||||||
n int
|
|
||||||
}{
|
|
||||||
{cEOS, 1}, {cU, 3}, {cUD, 3}, {cL, 5}, {cLR, 5}, {cLRN, 6},
|
|
||||||
{cLRND, 6},
|
|
||||||
}
|
|
||||||
for _, tc := range tests {
|
|
||||||
n := headerLen(tc.c)
|
|
||||||
if n != tc.n {
|
|
||||||
t.Errorf("header length for %s %d; want %d",
|
|
||||||
tc.c, n, tc.n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func chunkHeaderSamples(t *testing.T) []chunkHeader {
|
|
||||||
props := Properties{LC: 3, LP: 0, PB: 2}
|
|
||||||
headers := make([]chunkHeader, 0, 12)
|
|
||||||
for c := cEOS; c <= cLRND; c++ {
|
|
||||||
var h chunkHeader
|
|
||||||
h.ctype = c
|
|
||||||
if c >= cUD {
|
|
||||||
h.uncompressed = 0x0304
|
|
||||||
}
|
|
||||||
if c >= cL {
|
|
||||||
h.compressed = 0x0201
|
|
||||||
}
|
|
||||||
if c >= cLRN {
|
|
||||||
h.props = props
|
|
||||||
}
|
|
||||||
headers = append(headers, h)
|
|
||||||
}
|
|
||||||
return headers
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChunkHeaderMarshalling(t *testing.T) {
|
|
||||||
for _, h := range chunkHeaderSamples(t) {
|
|
||||||
data, err := h.MarshalBinary()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("MarshalBinary for %v error %s", h, err)
|
|
||||||
}
|
|
||||||
var g chunkHeader
|
|
||||||
if err = g.UnmarshalBinary(data); err != nil {
|
|
||||||
t.Fatalf("UnmarshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
if g != h {
|
|
||||||
t.Fatalf("got %v; want %v", g, h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadChunkHeader(t *testing.T) {
|
|
||||||
for _, h := range chunkHeaderSamples(t) {
|
|
||||||
data, err := h.MarshalBinary()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("MarshalBinary for %v error %s", h, err)
|
|
||||||
}
|
|
||||||
r := bytes.NewReader(data)
|
|
||||||
g, err := readChunkHeader(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("readChunkHeader for %v error %s", h, err)
|
|
||||||
}
|
|
||||||
if *g != h {
|
|
||||||
t.Fatalf("got %v; want %v", g, h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadEOS(t *testing.T) {
|
|
||||||
var b [1]byte
|
|
||||||
r := bytes.NewReader(b[:])
|
|
||||||
h, err := readChunkHeader(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("readChunkHeader error %s", err)
|
|
||||||
}
|
|
||||||
if h.ctype != cEOS {
|
|
||||||
t.Errorf("ctype got %s; want %s", h.ctype, cEOS)
|
|
||||||
}
|
|
||||||
if h.compressed != 0 {
|
|
||||||
t.Errorf("compressed got %d; want %d", h.compressed, 0)
|
|
||||||
}
|
|
||||||
if h.uncompressed != 0 {
|
|
||||||
t.Errorf("uncompressed got %d; want %d", h.uncompressed, 0)
|
|
||||||
}
|
|
||||||
wantProps := Properties{}
|
|
||||||
if h.props != wantProps {
|
|
||||||
t.Errorf("props got %v; want %v", h.props, wantProps)
|
|
||||||
}
|
|
||||||
}
|
|
52
vendor/github.com/ulikunitz/xz/lzma/header_test.go
generated
vendored
52
vendor/github.com/ulikunitz/xz/lzma/header_test.go
generated
vendored
@ -1,52 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestHeaderMarshalling(t *testing.T) {
|
|
||||||
tests := []header{
|
|
||||||
{properties: Properties{3, 0, 2}, dictCap: 8 * 1024 * 1024,
|
|
||||||
size: -1},
|
|
||||||
{properties: Properties{4, 3, 3}, dictCap: 4096,
|
|
||||||
size: 10},
|
|
||||||
}
|
|
||||||
for _, h := range tests {
|
|
||||||
data, err := h.marshalBinary()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("marshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
var g header
|
|
||||||
if err = g.unmarshalBinary(data); err != nil {
|
|
||||||
t.Fatalf("unmarshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
if h != g {
|
|
||||||
t.Errorf("got header %#v; want %#v", g, h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidHeader(t *testing.T) {
|
|
||||||
tests := []header{
|
|
||||||
{properties: Properties{3, 0, 2}, dictCap: 8 * 1024 * 1024,
|
|
||||||
size: -1},
|
|
||||||
{properties: Properties{4, 3, 3}, dictCap: 4096,
|
|
||||||
size: 10},
|
|
||||||
}
|
|
||||||
for _, h := range tests {
|
|
||||||
data, err := h.marshalBinary()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("marshalBinary error %s", err)
|
|
||||||
}
|
|
||||||
if !ValidHeader(data) {
|
|
||||||
t.Errorf("ValidHeader returns false for header %v;"+
|
|
||||||
" want true", h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const a = "1234567890123"
|
|
||||||
if ValidHeader([]byte(a)) {
|
|
||||||
t.Errorf("ValidHeader returns true for %s; want false", a)
|
|
||||||
}
|
|
||||||
}
|
|
312
vendor/github.com/ulikunitz/xz/lzma/reader_test.go
generated
vendored
312
vendor/github.com/ulikunitz/xz/lzma/reader_test.go
generated
vendored
@ -1,312 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
"testing/iotest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNewReader(t *testing.T) {
|
|
||||||
f, err := os.Open("examples/a.lzma")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("open examples/a.lzma: %s", err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
_, err = NewReader(bufio.NewReader(f))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
dirname = "examples"
|
|
||||||
origname = "a.txt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func readOrigFile(t *testing.T) []byte {
|
|
||||||
orig, err := ioutil.ReadFile(filepath.Join(dirname, origname))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadFile: %s", err)
|
|
||||||
}
|
|
||||||
return orig
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDecodeFile(t *testing.T, filename string, orig []byte) {
|
|
||||||
pathname := filepath.Join(dirname, filename)
|
|
||||||
f, err := os.Open(pathname)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Open(%q): %s", pathname, err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err = f.Close(); err != nil {
|
|
||||||
t.Fatalf("f.Close() error %s", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
t.Logf("file %s opened", filename)
|
|
||||||
l, err := NewReader(bufio.NewReader(f))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader: %s", err)
|
|
||||||
}
|
|
||||||
decoded, err := ioutil.ReadAll(l)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadAll: %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("%s", decoded)
|
|
||||||
if len(orig) != len(decoded) {
|
|
||||||
t.Fatalf("length decoded is %d; want %d",
|
|
||||||
len(decoded), len(orig))
|
|
||||||
}
|
|
||||||
if !bytes.Equal(orig, decoded) {
|
|
||||||
t.Fatalf("decoded file differs from original")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaderSimple(t *testing.T) {
|
|
||||||
// DebugOn(os.Stderr)
|
|
||||||
// defer DebugOff()
|
|
||||||
|
|
||||||
testDecodeFile(t, "a.lzma", readOrigFile(t))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaderAll(t *testing.T) {
|
|
||||||
dirname := "examples"
|
|
||||||
dir, err := os.Open(dirname)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Open: %s", err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := dir.Close(); err != nil {
|
|
||||||
t.Fatalf("dir.Close() error %s", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
all, err := dir.Readdirnames(0)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Readdirnames: %s", err)
|
|
||||||
}
|
|
||||||
// filter now all file with the pattern "a*.lzma"
|
|
||||||
files := make([]string, 0, len(all))
|
|
||||||
for _, fn := range all {
|
|
||||||
match, err := filepath.Match("a*.lzma", fn)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Match: %s", err)
|
|
||||||
}
|
|
||||||
if match {
|
|
||||||
files = append(files, fn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.Log("files:", files)
|
|
||||||
orig := readOrigFile(t)
|
|
||||||
// actually test the files
|
|
||||||
for _, fn := range files {
|
|
||||||
testDecodeFile(t, fn, orig)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
func Example_reader() {
|
|
||||||
f, err := os.Open("fox.lzma")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
// no need for defer; Fatal calls os.Exit(1) that doesn't execute deferred functions
|
|
||||||
r, err := NewReader(bufio.NewReader(f))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
_, err = io.Copy(os.Stdout, r)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := f.Close(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
// Output:
|
|
||||||
// The quick brown fox jumps over the lazy dog.
|
|
||||||
}
|
|
||||||
|
|
||||||
type wrapTest struct {
|
|
||||||
name string
|
|
||||||
wrap func(io.Reader) io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *wrapTest) testFile(t *testing.T, filename string, orig []byte) {
|
|
||||||
pathname := filepath.Join(dirname, filename)
|
|
||||||
f, err := os.Open(pathname)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Open(\"%s\"): %s", pathname, err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := f.Close(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
t.Logf("%s file %s opened", w.name, filename)
|
|
||||||
l, err := NewReader(w.wrap(f))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s NewReader: %s", w.name, err)
|
|
||||||
}
|
|
||||||
decoded, err := ioutil.ReadAll(l)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s ReadAll: %s", w.name, err)
|
|
||||||
}
|
|
||||||
t.Logf("%s", decoded)
|
|
||||||
if len(orig) != len(decoded) {
|
|
||||||
t.Fatalf("%s length decoded is %d; want %d",
|
|
||||||
w.name, len(decoded), len(orig))
|
|
||||||
}
|
|
||||||
if !bytes.Equal(orig, decoded) {
|
|
||||||
t.Fatalf("%s decoded file differs from original", w.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaderWrap(t *testing.T) {
|
|
||||||
tests := [...]wrapTest{
|
|
||||||
{"DataErrReader", iotest.DataErrReader},
|
|
||||||
{"HalfReader", iotest.HalfReader},
|
|
||||||
{"OneByteReader", iotest.OneByteReader},
|
|
||||||
// TimeOutReader would require buffer
|
|
||||||
}
|
|
||||||
orig := readOrigFile(t)
|
|
||||||
for _, tst := range tests {
|
|
||||||
tst.testFile(t, "a.lzma", orig)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaderBadFiles(t *testing.T) {
|
|
||||||
dirname := "examples"
|
|
||||||
dir, err := os.Open(dirname)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Open: %s", err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := dir.Close(); err != nil {
|
|
||||||
t.Fatalf("dir.Close() error %s", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
all, err := dir.Readdirnames(0)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Readdirnames: %s", err)
|
|
||||||
}
|
|
||||||
// filter now all file with the pattern "bad*.lzma"
|
|
||||||
files := make([]string, 0, len(all))
|
|
||||||
for _, fn := range all {
|
|
||||||
match, err := filepath.Match("bad*.lzma", fn)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Match: %s", err)
|
|
||||||
}
|
|
||||||
if match {
|
|
||||||
files = append(files, fn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.Log("files:", files)
|
|
||||||
for _, filename := range files {
|
|
||||||
pathname := filepath.Join(dirname, filename)
|
|
||||||
f, err := os.Open(pathname)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Open(\"%s\"): %s", pathname, err)
|
|
||||||
}
|
|
||||||
defer func(f *os.File) {
|
|
||||||
if err := f.Close(); err != nil {
|
|
||||||
t.Fatalf("f.Close() error %s", err)
|
|
||||||
}
|
|
||||||
}(f)
|
|
||||||
t.Logf("file %s opened", filename)
|
|
||||||
l, err := NewReader(f)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader: %s", err)
|
|
||||||
}
|
|
||||||
decoded, err := ioutil.ReadAll(l)
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("ReadAll for %s: no error", filename)
|
|
||||||
t.Logf("%s", decoded)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Logf("%s: error %s", filename, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type repReader byte
|
|
||||||
|
|
||||||
func (r repReader) Read(p []byte) (n int, err error) {
|
|
||||||
for i := range p {
|
|
||||||
p[i] = byte(r)
|
|
||||||
}
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRepReader(c byte, n int64) *io.LimitedReader {
|
|
||||||
return &io.LimitedReader{R: repReader(c), N: n}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCodeReader(r io.Reader) *io.PipeReader {
|
|
||||||
pr, pw := io.Pipe()
|
|
||||||
go func() {
|
|
||||||
bw := bufio.NewWriter(pw)
|
|
||||||
lw, err := NewWriter(bw)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
if _, err = io.Copy(lw, r); err != nil {
|
|
||||||
log.Fatalf("io.Copy error %s", err)
|
|
||||||
}
|
|
||||||
if err = lw.Close(); err != nil {
|
|
||||||
log.Fatalf("lw.Close error %s", err)
|
|
||||||
}
|
|
||||||
if err = bw.Flush(); err != nil {
|
|
||||||
log.Fatalf("bw.Flush() error %s", err)
|
|
||||||
}
|
|
||||||
if err = pw.CloseWithError(io.EOF); err != nil {
|
|
||||||
log.Fatalf("pw.CloseWithError(io.EOF) error %s", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return pr
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaderErrAgain(t *testing.T) {
|
|
||||||
lengths := []int64{0, 128, 1024, 4095, 4096, 4097, 8191, 8192, 8193}
|
|
||||||
buf := make([]byte, 128)
|
|
||||||
const c = 'A'
|
|
||||||
for _, n := range lengths {
|
|
||||||
t.Logf("n: %d", n)
|
|
||||||
pr := newCodeReader(newRepReader(c, n))
|
|
||||||
r, err := NewReader(pr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader(pr) error %s", err)
|
|
||||||
}
|
|
||||||
k := int64(0)
|
|
||||||
for {
|
|
||||||
m, err := r.Read(buf)
|
|
||||||
k += int64(m)
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("r.Read(buf) error %s", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if m > len(buf) {
|
|
||||||
t.Fatalf("r.Read(buf) %d; want <= %d", m,
|
|
||||||
len(buf))
|
|
||||||
}
|
|
||||||
for i, b := range buf[:m] {
|
|
||||||
if b != c {
|
|
||||||
t.Fatalf("buf[%d]=%c; want %c", i, b,
|
|
||||||
c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if k != n {
|
|
||||||
t.Errorf("Read %d bytes; want %d", k, n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
109
vendor/github.com/ulikunitz/xz/lzma/writer2_test.go
generated
vendored
109
vendor/github.com/ulikunitz/xz/lzma/writer2_test.go
generated
vendored
@ -1,109 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"math/rand"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ulikunitz/xz/internal/randtxt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestWriter2(t *testing.T) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
w, err := Writer2Config{DictCap: 4096}.NewWriter2(&buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
n, err := w.Write([]byte{'a'})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("w.Write([]byte{'a'}) error %s", err)
|
|
||||||
}
|
|
||||||
if n != 1 {
|
|
||||||
t.Fatalf("w.Write([]byte{'a'}) returned %d; want %d", n, 1)
|
|
||||||
}
|
|
||||||
if err = w.Flush(); err != nil {
|
|
||||||
t.Fatalf("w.Flush() error %s", err)
|
|
||||||
}
|
|
||||||
// check that double Flush doesn't write another chunk
|
|
||||||
if err = w.Flush(); err != nil {
|
|
||||||
t.Fatalf("w.Flush() error %s", err)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close() error %s", err)
|
|
||||||
}
|
|
||||||
p := buf.Bytes()
|
|
||||||
want := []byte{1, 0, 0, 'a', 0}
|
|
||||||
if !bytes.Equal(p, want) {
|
|
||||||
t.Fatalf("bytes written %#v; want %#v", p, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCycle1(t *testing.T) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
w, err := Writer2Config{DictCap: 4096}.NewWriter2(&buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
n, err := w.Write([]byte{'a'})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("w.Write([]byte{'a'}) error %s", err)
|
|
||||||
}
|
|
||||||
if n != 1 {
|
|
||||||
t.Fatalf("w.Write([]byte{'a'}) returned %d; want %d", n, 1)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close() error %s", err)
|
|
||||||
}
|
|
||||||
r, err := Reader2Config{DictCap: 4096}.NewReader2(&buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
p := make([]byte, 3)
|
|
||||||
n, err = r.Read(p)
|
|
||||||
t.Logf("n %d error %v", n, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCycle2(t *testing.T) {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
w, err := Writer2Config{DictCap: 4096}.NewWriter2(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
// const txtlen = 1024
|
|
||||||
const txtlen = 2100000
|
|
||||||
io.CopyN(buf, randtxt.NewReader(rand.NewSource(42)), txtlen)
|
|
||||||
txt := buf.String()
|
|
||||||
buf.Reset()
|
|
||||||
n, err := io.Copy(w, strings.NewReader(txt))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Compressing copy error %s", err)
|
|
||||||
}
|
|
||||||
if n != txtlen {
|
|
||||||
t.Fatalf("Compressing data length %d; want %d", n, txtlen)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("buf.Len() %d", buf.Len())
|
|
||||||
r, err := Reader2Config{DictCap: 4096}.NewReader2(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
out := new(bytes.Buffer)
|
|
||||||
n, err = io.Copy(out, r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Decompressing copy error %s after %d bytes", err, n)
|
|
||||||
}
|
|
||||||
if n != txtlen {
|
|
||||||
t.Fatalf("Decompression data length %d; want %d", n, txtlen)
|
|
||||||
}
|
|
||||||
if txt != out.String() {
|
|
||||||
t.Fatal("decompressed data differs from original")
|
|
||||||
}
|
|
||||||
}
|
|
249
vendor/github.com/ulikunitz/xz/lzma/writer_test.go
generated
vendored
249
vendor/github.com/ulikunitz/xz/lzma/writer_test.go
generated
vendored
@ -1,249 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package lzma
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"math/rand"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ulikunitz/xz/internal/randtxt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestWriterCycle(t *testing.T) {
|
|
||||||
orig := readOrigFile(t)
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
w, err := NewWriter(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewWriter: error %s", err)
|
|
||||||
}
|
|
||||||
n, err := w.Write(orig)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("w.Write error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(orig) {
|
|
||||||
t.Fatalf("w.Write returned %d; want %d", n, len(orig))
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("buf.Len() %d len(orig) %d", buf.Len(), len(orig))
|
|
||||||
if buf.Len() > len(orig) {
|
|
||||||
t.Errorf("buf.Len()=%d bigger then len(orig)=%d", buf.Len(),
|
|
||||||
len(orig))
|
|
||||||
}
|
|
||||||
lr, err := NewReader(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
decoded, err := ioutil.ReadAll(lr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadAll(lr) error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("%s", decoded)
|
|
||||||
if len(orig) != len(decoded) {
|
|
||||||
t.Fatalf("length decoded is %d; want %d", len(decoded),
|
|
||||||
len(orig))
|
|
||||||
}
|
|
||||||
if !bytes.Equal(orig, decoded) {
|
|
||||||
t.Fatalf("decoded file differs from original")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWriterLongData(t *testing.T) {
|
|
||||||
const (
|
|
||||||
seed = 49
|
|
||||||
size = 82237
|
|
||||||
)
|
|
||||||
r := io.LimitReader(randtxt.NewReader(rand.NewSource(seed)), size)
|
|
||||||
txt, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadAll error %s", err)
|
|
||||||
}
|
|
||||||
if len(txt) != size {
|
|
||||||
t.Fatalf("ReadAll read %d bytes; want %d", len(txt), size)
|
|
||||||
}
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
w, err := WriterConfig{DictCap: 0x4000}.NewWriter(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriterConfig.NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
n, err := w.Write(txt)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("w.Write error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(txt) {
|
|
||||||
t.Fatalf("w.Write wrote %d bytes; want %d", n, size)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("compressed length %d", buf.Len())
|
|
||||||
lr, err := NewReader(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
txtRead, err := ioutil.ReadAll(lr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadAll(lr) error %s", err)
|
|
||||||
}
|
|
||||||
if len(txtRead) != size {
|
|
||||||
t.Fatalf("ReadAll(lr) returned %d bytes; want %d",
|
|
||||||
len(txtRead), size)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(txtRead, txt) {
|
|
||||||
t.Fatal("ReadAll(lr) returned txt differs from origin")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWriter_Size(t *testing.T) {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
w, err := WriterConfig{Size: 10, EOSMarker: true}.NewWriter(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriterConfig.NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
q := []byte{'a'}
|
|
||||||
for i := 0; i < 9; i++ {
|
|
||||||
n, err := w.Write(q)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("w.Write error %s", err)
|
|
||||||
}
|
|
||||||
if n != 1 {
|
|
||||||
t.Fatalf("w.Write returned %d; want %d", n, 1)
|
|
||||||
}
|
|
||||||
q[0]++
|
|
||||||
}
|
|
||||||
if err := w.Close(); err != errSize {
|
|
||||||
t.Fatalf("expected errSize, but got %v", err)
|
|
||||||
}
|
|
||||||
n, err := w.Write(q)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("w.Write error %s", err)
|
|
||||||
}
|
|
||||||
if n != 1 {
|
|
||||||
t.Fatalf("w.Write returned %d; want %d", n, 1)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("compressed size %d", buf.Len())
|
|
||||||
r, err := NewReader(buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
b, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadAll error %s", err)
|
|
||||||
}
|
|
||||||
s := string(b)
|
|
||||||
want := "abcdefghij"
|
|
||||||
if s != want {
|
|
||||||
t.Fatalf("read %q, want %q", s, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The example uses the buffered reader and writer from package bufio.
|
|
||||||
func Example_writer() {
|
|
||||||
pr, pw := io.Pipe()
|
|
||||||
go func() {
|
|
||||||
bw := bufio.NewWriter(pw)
|
|
||||||
w, err := NewWriter(bw)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
input := []byte("The quick brown fox jumps over the lazy dog.")
|
|
||||||
if _, err = w.Write(input); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
// reader waits for the data
|
|
||||||
if err = bw.Flush(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
r, err := NewReader(pr)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
_, err = io.Copy(os.Stdout, r)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
// Output:
|
|
||||||
// The quick brown fox jumps over the lazy dog.
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkReader(b *testing.B) {
|
|
||||||
const (
|
|
||||||
seed = 49
|
|
||||||
size = 50000
|
|
||||||
)
|
|
||||||
r := io.LimitReader(randtxt.NewReader(rand.NewSource(seed)), size)
|
|
||||||
txt, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("ReadAll error %s", err)
|
|
||||||
}
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
w, err := WriterConfig{DictCap: 0x4000}.NewWriter(buf)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("WriterConfig{}.NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
if _, err = w.Write(txt); err != nil {
|
|
||||||
b.Fatalf("w.Write error %s", err)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
b.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
data, err := ioutil.ReadAll(buf)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("ReadAll error %s", err)
|
|
||||||
}
|
|
||||||
b.SetBytes(int64(len(txt)))
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
lr, err := NewReader(bytes.NewReader(data))
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
if _, err = ioutil.ReadAll(lr); err != nil {
|
|
||||||
b.Fatalf("ReadAll(lr) error %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkWriter(b *testing.B) {
|
|
||||||
const (
|
|
||||||
seed = 49
|
|
||||||
size = 50000
|
|
||||||
)
|
|
||||||
r := io.LimitReader(randtxt.NewReader(rand.NewSource(seed)), size)
|
|
||||||
txt, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("ReadAll error %s", err)
|
|
||||||
}
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
b.SetBytes(int64(len(txt)))
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
buf.Reset()
|
|
||||||
w, err := WriterConfig{DictCap: 0x4000}.NewWriter(buf)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
if _, err = w.Write(txt); err != nil {
|
|
||||||
b.Fatalf("w.Write error %s", err)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
b.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
81
vendor/github.com/ulikunitz/xz/reader_test.go
generated
vendored
81
vendor/github.com/ulikunitz/xz/reader_test.go
generated
vendored
@ -1,81 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package xz
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestReaderSimple(t *testing.T) {
|
|
||||||
const file = "fox.xz"
|
|
||||||
xz, err := os.Open(file)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("os.Open(%q) error %s", file, err)
|
|
||||||
}
|
|
||||||
r, err := NewReader(xz)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
var buf bytes.Buffer
|
|
||||||
if _, err = io.Copy(&buf, r); err != nil {
|
|
||||||
t.Fatalf("io.Copy error %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaderSingleStream(t *testing.T) {
|
|
||||||
data, err := ioutil.ReadFile("fox.xz")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadFile error %s", err)
|
|
||||||
}
|
|
||||||
xz := bytes.NewReader(data)
|
|
||||||
rc := ReaderConfig{SingleStream: true}
|
|
||||||
r, err := rc.NewReader(xz)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
var buf bytes.Buffer
|
|
||||||
if _, err = io.Copy(&buf, r); err != nil {
|
|
||||||
t.Fatalf("io.Copy error %s", err)
|
|
||||||
}
|
|
||||||
buf.Reset()
|
|
||||||
data = append(data, 0)
|
|
||||||
xz = bytes.NewReader(data)
|
|
||||||
r, err = rc.NewReader(xz)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
if _, err = io.Copy(&buf, r); err != errUnexpectedData {
|
|
||||||
t.Fatalf("io.Copy returned %v; want %v", err, errUnexpectedData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaaderMultipleStreams(t *testing.T) {
|
|
||||||
data, err := ioutil.ReadFile("fox.xz")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadFile error %s", err)
|
|
||||||
}
|
|
||||||
m := make([]byte, 0, 4*len(data)+4*4)
|
|
||||||
m = append(m, data...)
|
|
||||||
m = append(m, data...)
|
|
||||||
m = append(m, 0, 0, 0, 0)
|
|
||||||
m = append(m, data...)
|
|
||||||
m = append(m, 0, 0, 0, 0)
|
|
||||||
m = append(m, 0, 0, 0, 0)
|
|
||||||
m = append(m, data...)
|
|
||||||
m = append(m, 0, 0, 0, 0)
|
|
||||||
xz := bytes.NewReader(m)
|
|
||||||
r, err := NewReader(xz)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
var buf bytes.Buffer
|
|
||||||
if _, err = io.Copy(&buf, r); err != nil {
|
|
||||||
t.Fatalf("io.Copy error %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
138
vendor/github.com/ulikunitz/xz/writer_test.go
generated
vendored
138
vendor/github.com/ulikunitz/xz/writer_test.go
generated
vendored
@ -1,138 +0,0 @@
|
|||||||
// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package xz
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"math/rand"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ulikunitz/xz/internal/randtxt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestWriter(t *testing.T) {
|
|
||||||
const text = "The quick brown fox jumps over the lazy dog."
|
|
||||||
var buf bytes.Buffer
|
|
||||||
w, err := NewWriter(&buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
n, err := io.WriteString(w, text)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriteString error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(text) {
|
|
||||||
t.Fatalf("Writestring wrote %d bytes; want %d", n, len(text))
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
var out bytes.Buffer
|
|
||||||
r, err := NewReader(&buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
if _, err = io.Copy(&out, r); err != nil {
|
|
||||||
t.Fatalf("io.Copy error %s", err)
|
|
||||||
}
|
|
||||||
s := out.String()
|
|
||||||
if s != text {
|
|
||||||
t.Fatalf("reader decompressed to %q; want %q", s, text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIssue12(t *testing.T) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
w, err := NewWriter(&buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
r, err := NewReader(&buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
var out bytes.Buffer
|
|
||||||
if _, err = io.Copy(&out, r); err != nil {
|
|
||||||
t.Fatalf("io.Copy error %s", err)
|
|
||||||
}
|
|
||||||
s := out.String()
|
|
||||||
if s != "" {
|
|
||||||
t.Fatalf("reader decompressed to %q; want %q", s, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Example() {
|
|
||||||
const text = "The quick brown fox jumps over the lazy dog."
|
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
// compress text
|
|
||||||
w, err := NewWriter(&buf)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
if _, err := io.WriteString(w, text); err != nil {
|
|
||||||
log.Fatalf("WriteString error %s", err)
|
|
||||||
}
|
|
||||||
if err := w.Close(); err != nil {
|
|
||||||
log.Fatalf("w.Close error %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// decompress buffer and write result to stdout
|
|
||||||
r, err := NewReader(&buf)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
if _, err = io.Copy(os.Stdout, r); err != nil {
|
|
||||||
log.Fatalf("io.Copy error %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// The quick brown fox jumps over the lazy dog.
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWriter2(t *testing.T) {
|
|
||||||
const txtlen = 1023
|
|
||||||
var buf bytes.Buffer
|
|
||||||
io.CopyN(&buf, randtxt.NewReader(rand.NewSource(41)), txtlen)
|
|
||||||
txt := buf.String()
|
|
||||||
|
|
||||||
buf.Reset()
|
|
||||||
w, err := NewWriter(&buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewWriter error %s", err)
|
|
||||||
}
|
|
||||||
n, err := io.WriteString(w, txt)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriteString error %s", err)
|
|
||||||
}
|
|
||||||
if n != len(txt) {
|
|
||||||
t.Fatalf("WriteString wrote %d bytes; want %d", n, len(txt))
|
|
||||||
}
|
|
||||||
if err = w.Close(); err != nil {
|
|
||||||
t.Fatalf("Close error %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("buf.Len() %d", buf.Len())
|
|
||||||
r, err := NewReader(&buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewReader error %s", err)
|
|
||||||
}
|
|
||||||
var out bytes.Buffer
|
|
||||||
k, err := io.Copy(&out, r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Decompressing copy error %s after %d bytes", err, n)
|
|
||||||
}
|
|
||||||
if k != txtlen {
|
|
||||||
t.Fatalf("Decompression data length %d; want %d", k, txtlen)
|
|
||||||
}
|
|
||||||
if txt != out.String() {
|
|
||||||
t.Fatal("decompressed data differs from original")
|
|
||||||
}
|
|
||||||
}
|
|
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code refers to The Go Authors for copyright purposes.
|
||||||
|
# The master list of authors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code was written by the Go contributors.
|
||||||
|
# The master list of contributors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/CONTRIBUTORS.
|
27
vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
525
vendor/golang.org/x/net/bpf/instructions_test.go
generated
vendored
525
vendor/golang.org/x/net/bpf/instructions_test.go
generated
vendored
@ -1,525 +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 bpf
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a direct translation of the program in
|
|
||||||
// testdata/all_instructions.txt.
|
|
||||||
var allInstructions = []Instruction{
|
|
||||||
LoadConstant{Dst: RegA, Val: 42},
|
|
||||||
LoadConstant{Dst: RegX, Val: 42},
|
|
||||||
|
|
||||||
LoadScratch{Dst: RegA, N: 3},
|
|
||||||
LoadScratch{Dst: RegX, N: 3},
|
|
||||||
|
|
||||||
LoadAbsolute{Off: 42, Size: 1},
|
|
||||||
LoadAbsolute{Off: 42, Size: 2},
|
|
||||||
LoadAbsolute{Off: 42, Size: 4},
|
|
||||||
|
|
||||||
LoadIndirect{Off: 42, Size: 1},
|
|
||||||
LoadIndirect{Off: 42, Size: 2},
|
|
||||||
LoadIndirect{Off: 42, Size: 4},
|
|
||||||
|
|
||||||
LoadMemShift{Off: 42},
|
|
||||||
|
|
||||||
LoadExtension{Num: ExtLen},
|
|
||||||
LoadExtension{Num: ExtProto},
|
|
||||||
LoadExtension{Num: ExtType},
|
|
||||||
LoadExtension{Num: ExtRand},
|
|
||||||
|
|
||||||
StoreScratch{Src: RegA, N: 3},
|
|
||||||
StoreScratch{Src: RegX, N: 3},
|
|
||||||
|
|
||||||
ALUOpConstant{Op: ALUOpAdd, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpSub, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpMul, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpDiv, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpOr, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpAnd, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpShiftLeft, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpShiftRight, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpMod, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpXor, Val: 42},
|
|
||||||
|
|
||||||
ALUOpX{Op: ALUOpAdd},
|
|
||||||
ALUOpX{Op: ALUOpSub},
|
|
||||||
ALUOpX{Op: ALUOpMul},
|
|
||||||
ALUOpX{Op: ALUOpDiv},
|
|
||||||
ALUOpX{Op: ALUOpOr},
|
|
||||||
ALUOpX{Op: ALUOpAnd},
|
|
||||||
ALUOpX{Op: ALUOpShiftLeft},
|
|
||||||
ALUOpX{Op: ALUOpShiftRight},
|
|
||||||
ALUOpX{Op: ALUOpMod},
|
|
||||||
ALUOpX{Op: ALUOpXor},
|
|
||||||
|
|
||||||
NegateA{},
|
|
||||||
|
|
||||||
Jump{Skip: 10},
|
|
||||||
JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 8, SkipFalse: 9},
|
|
||||||
JumpIf{Cond: JumpNotEqual, Val: 42, SkipTrue: 8},
|
|
||||||
JumpIf{Cond: JumpLessThan, Val: 42, SkipTrue: 7},
|
|
||||||
JumpIf{Cond: JumpLessOrEqual, Val: 42, SkipTrue: 6},
|
|
||||||
JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 4, SkipFalse: 5},
|
|
||||||
JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 3, SkipFalse: 4},
|
|
||||||
JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 2, SkipFalse: 3},
|
|
||||||
|
|
||||||
TAX{},
|
|
||||||
TXA{},
|
|
||||||
|
|
||||||
RetA{},
|
|
||||||
RetConstant{Val: 42},
|
|
||||||
}
|
|
||||||
var allInstructionsExpected = "testdata/all_instructions.bpf"
|
|
||||||
|
|
||||||
// Check that we produce the same output as the canonical bpf_asm
|
|
||||||
// linux kernel tool.
|
|
||||||
func TestInterop(t *testing.T) {
|
|
||||||
out, err := Assemble(allInstructions)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("assembly of allInstructions program failed: %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("Assembled program is %d instructions long", len(out))
|
|
||||||
|
|
||||||
bs, err := ioutil.ReadFile(allInstructionsExpected)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("reading %s: %s", allInstructionsExpected, err)
|
|
||||||
}
|
|
||||||
// First statement is the number of statements, last statement is
|
|
||||||
// empty. We just ignore both and rely on slice length.
|
|
||||||
stmts := strings.Split(string(bs), ",")
|
|
||||||
if len(stmts)-2 != len(out) {
|
|
||||||
t.Fatalf("test program lengths don't match: %s has %d, Go implementation has %d", allInstructionsExpected, len(stmts)-2, len(allInstructions))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, stmt := range stmts[1 : len(stmts)-2] {
|
|
||||||
nums := strings.Split(stmt, " ")
|
|
||||||
if len(nums) != 4 {
|
|
||||||
t.Fatalf("malformed instruction %d in %s: %s", i+1, allInstructionsExpected, stmt)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := out[i]
|
|
||||||
|
|
||||||
op, err := strconv.ParseUint(nums[0], 10, 16)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("malformed opcode %s in instruction %d of %s", nums[0], i+1, allInstructionsExpected)
|
|
||||||
}
|
|
||||||
if actual.Op != uint16(op) {
|
|
||||||
t.Errorf("opcode mismatch on instruction %d (%#v): got 0x%02x, want 0x%02x", i+1, allInstructions[i], actual.Op, op)
|
|
||||||
}
|
|
||||||
|
|
||||||
jt, err := strconv.ParseUint(nums[1], 10, 8)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("malformed jt offset %s in instruction %d of %s", nums[1], i+1, allInstructionsExpected)
|
|
||||||
}
|
|
||||||
if actual.Jt != uint8(jt) {
|
|
||||||
t.Errorf("jt mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.Jt, jt)
|
|
||||||
}
|
|
||||||
|
|
||||||
jf, err := strconv.ParseUint(nums[2], 10, 8)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("malformed jf offset %s in instruction %d of %s", nums[2], i+1, allInstructionsExpected)
|
|
||||||
}
|
|
||||||
if actual.Jf != uint8(jf) {
|
|
||||||
t.Errorf("jf mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.Jf, jf)
|
|
||||||
}
|
|
||||||
|
|
||||||
k, err := strconv.ParseUint(nums[3], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("malformed constant %s in instruction %d of %s", nums[3], i+1, allInstructionsExpected)
|
|
||||||
}
|
|
||||||
if actual.K != uint32(k) {
|
|
||||||
t.Errorf("constant mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.K, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that assembly and disassembly match each other.
|
|
||||||
func TestAsmDisasm(t *testing.T) {
|
|
||||||
prog1, err := Assemble(allInstructions)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("assembly of allInstructions program failed: %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("Assembled program is %d instructions long", len(prog1))
|
|
||||||
|
|
||||||
got, allDecoded := Disassemble(prog1)
|
|
||||||
if !allDecoded {
|
|
||||||
t.Errorf("Disassemble(Assemble(allInstructions)) produced unrecognized instructions:")
|
|
||||||
for i, inst := range got {
|
|
||||||
if r, ok := inst.(RawInstruction); ok {
|
|
||||||
t.Logf(" insn %d, %#v --> %#v", i+1, allInstructions[i], r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(allInstructions) != len(got) {
|
|
||||||
t.Fatalf("disassembly changed program size: %d insns before, %d insns after", len(allInstructions), len(got))
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(allInstructions, got) {
|
|
||||||
t.Errorf("program mutated by disassembly:")
|
|
||||||
for i := range got {
|
|
||||||
if !reflect.DeepEqual(allInstructions[i], got[i]) {
|
|
||||||
t.Logf(" insn %d, s: %#v, p1: %#v, got: %#v", i+1, allInstructions[i], prog1[i], got[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type InvalidInstruction struct{}
|
|
||||||
|
|
||||||
func (a InvalidInstruction) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{}, fmt.Errorf("Invalid Instruction")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a InvalidInstruction) String() string {
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestString(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
instruction Instruction
|
|
||||||
assembler string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
instruction: LoadConstant{Dst: RegA, Val: 42},
|
|
||||||
assembler: "ld #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadConstant{Dst: RegX, Val: 42},
|
|
||||||
assembler: "ldx #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadConstant{Dst: 0xffff, Val: 42},
|
|
||||||
assembler: "unknown instruction: bpf.LoadConstant{Dst:0xffff, Val:0x2a}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadScratch{Dst: RegA, N: 3},
|
|
||||||
assembler: "ld M[3]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadScratch{Dst: RegX, N: 3},
|
|
||||||
assembler: "ldx M[3]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadScratch{Dst: 0xffff, N: 3},
|
|
||||||
assembler: "unknown instruction: bpf.LoadScratch{Dst:0xffff, N:3}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 42, Size: 1},
|
|
||||||
assembler: "ldb [42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 42, Size: 2},
|
|
||||||
assembler: "ldh [42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 42, Size: 4},
|
|
||||||
assembler: "ld [42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 42, Size: -1},
|
|
||||||
assembler: "unknown instruction: bpf.LoadAbsolute{Off:0x2a, Size:-1}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadIndirect{Off: 42, Size: 1},
|
|
||||||
assembler: "ldb [x + 42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadIndirect{Off: 42, Size: 2},
|
|
||||||
assembler: "ldh [x + 42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadIndirect{Off: 42, Size: 4},
|
|
||||||
assembler: "ld [x + 42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadIndirect{Off: 42, Size: -1},
|
|
||||||
assembler: "unknown instruction: bpf.LoadIndirect{Off:0x2a, Size:-1}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadMemShift{Off: 42},
|
|
||||||
assembler: "ldx 4*([42]&0xf)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtLen},
|
|
||||||
assembler: "ld #len",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtProto},
|
|
||||||
assembler: "ld #proto",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtType},
|
|
||||||
assembler: "ld #type",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtPayloadOffset},
|
|
||||||
assembler: "ld #poff",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtInterfaceIndex},
|
|
||||||
assembler: "ld #ifidx",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtNetlinkAttr},
|
|
||||||
assembler: "ld #nla",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtNetlinkAttrNested},
|
|
||||||
assembler: "ld #nlan",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtMark},
|
|
||||||
assembler: "ld #mark",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtQueue},
|
|
||||||
assembler: "ld #queue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtLinkLayerType},
|
|
||||||
assembler: "ld #hatype",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtRXHash},
|
|
||||||
assembler: "ld #rxhash",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtCPUID},
|
|
||||||
assembler: "ld #cpu",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtVLANTag},
|
|
||||||
assembler: "ld #vlan_tci",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtVLANTagPresent},
|
|
||||||
assembler: "ld #vlan_avail",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtVLANProto},
|
|
||||||
assembler: "ld #vlan_tpid",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtRand},
|
|
||||||
assembler: "ld #rand",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 0xfffff038, Size: 4},
|
|
||||||
assembler: "ld #rand",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: 0xfff},
|
|
||||||
assembler: "unknown instruction: bpf.LoadExtension{Num:4095}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: StoreScratch{Src: RegA, N: 3},
|
|
||||||
assembler: "st M[3]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: StoreScratch{Src: RegX, N: 3},
|
|
||||||
assembler: "stx M[3]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: StoreScratch{Src: 0xffff, N: 3},
|
|
||||||
assembler: "unknown instruction: bpf.StoreScratch{Src:0xffff, N:3}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpAdd, Val: 42},
|
|
||||||
assembler: "add #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpSub, Val: 42},
|
|
||||||
assembler: "sub #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpMul, Val: 42},
|
|
||||||
assembler: "mul #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpDiv, Val: 42},
|
|
||||||
assembler: "div #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpOr, Val: 42},
|
|
||||||
assembler: "or #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpAnd, Val: 42},
|
|
||||||
assembler: "and #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpShiftLeft, Val: 42},
|
|
||||||
assembler: "lsh #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpShiftRight, Val: 42},
|
|
||||||
assembler: "rsh #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpMod, Val: 42},
|
|
||||||
assembler: "mod #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpXor, Val: 42},
|
|
||||||
assembler: "xor #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: 0xffff, Val: 42},
|
|
||||||
assembler: "unknown instruction: bpf.ALUOpConstant{Op:0xffff, Val:0x2a}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpAdd},
|
|
||||||
assembler: "add x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpSub},
|
|
||||||
assembler: "sub x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpMul},
|
|
||||||
assembler: "mul x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpDiv},
|
|
||||||
assembler: "div x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpOr},
|
|
||||||
assembler: "or x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpAnd},
|
|
||||||
assembler: "and x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpShiftLeft},
|
|
||||||
assembler: "lsh x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpShiftRight},
|
|
||||||
assembler: "rsh x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpMod},
|
|
||||||
assembler: "mod x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpXor},
|
|
||||||
assembler: "xor x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: 0xffff},
|
|
||||||
assembler: "unknown instruction: bpf.ALUOpX{Op:0xffff}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: NegateA{},
|
|
||||||
assembler: "neg",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: Jump{Skip: 10},
|
|
||||||
assembler: "ja 10",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 8, SkipFalse: 9},
|
|
||||||
assembler: "jeq #42,8,9",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 8},
|
|
||||||
assembler: "jeq #42,8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpEqual, Val: 42, SkipFalse: 8},
|
|
||||||
assembler: "jneq #42,8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpNotEqual, Val: 42, SkipTrue: 8},
|
|
||||||
assembler: "jneq #42,8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpLessThan, Val: 42, SkipTrue: 7},
|
|
||||||
assembler: "jlt #42,7",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpLessOrEqual, Val: 42, SkipTrue: 6},
|
|
||||||
assembler: "jle #42,6",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 4, SkipFalse: 5},
|
|
||||||
assembler: "jgt #42,4,5",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 4},
|
|
||||||
assembler: "jgt #42,4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 3, SkipFalse: 4},
|
|
||||||
assembler: "jge #42,3,4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 3},
|
|
||||||
assembler: "jge #42,3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 2, SkipFalse: 3},
|
|
||||||
assembler: "jset #42,2,3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 2},
|
|
||||||
assembler: "jset #42,2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpBitsNotSet, Val: 42, SkipTrue: 2, SkipFalse: 3},
|
|
||||||
assembler: "jset #42,3,2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpBitsNotSet, Val: 42, SkipTrue: 2},
|
|
||||||
assembler: "jset #42,0,2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: 0xffff, Val: 42, SkipTrue: 1, SkipFalse: 2},
|
|
||||||
assembler: "unknown instruction: bpf.JumpIf{Cond:0xffff, Val:0x2a, SkipTrue:0x1, SkipFalse:0x2}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: TAX{},
|
|
||||||
assembler: "tax",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: TXA{},
|
|
||||||
assembler: "txa",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: RetA{},
|
|
||||||
assembler: "ret a",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: RetConstant{Val: 42},
|
|
||||||
assembler: "ret #42",
|
|
||||||
},
|
|
||||||
// Invalid instruction
|
|
||||||
{
|
|
||||||
instruction: InvalidInstruction{},
|
|
||||||
assembler: "unknown instruction: bpf.InvalidInstruction{}",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
|
||||||
if input, ok := testCase.instruction.(fmt.Stringer); ok {
|
|
||||||
got := input.String()
|
|
||||||
if got != testCase.assembler {
|
|
||||||
t.Errorf("String did not return expected assembler notation, expected: %s, got: %s", testCase.assembler, got)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.Errorf("Instruction %#v is not a fmt.Stringer", testCase.instruction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
1
vendor/golang.org/x/net/bpf/testdata/all_instructions.bpf
generated
vendored
1
vendor/golang.org/x/net/bpf/testdata/all_instructions.bpf
generated
vendored
@ -1 +0,0 @@
|
|||||||
50,0 0 0 42,1 0 0 42,96 0 0 3,97 0 0 3,48 0 0 42,40 0 0 42,32 0 0 42,80 0 0 42,72 0 0 42,64 0 0 42,177 0 0 42,128 0 0 0,32 0 0 4294963200,32 0 0 4294963204,32 0 0 4294963256,2 0 0 3,3 0 0 3,4 0 0 42,20 0 0 42,36 0 0 42,52 0 0 42,68 0 0 42,84 0 0 42,100 0 0 42,116 0 0 42,148 0 0 42,164 0 0 42,12 0 0 0,28 0 0 0,44 0 0 0,60 0 0 0,76 0 0 0,92 0 0 0,108 0 0 0,124 0 0 0,156 0 0 0,172 0 0 0,132 0 0 0,5 0 0 10,21 8 9 42,21 0 8 42,53 0 7 42,37 0 6 42,37 4 5 42,53 3 4 42,69 2 3 42,7 0 0 0,135 0 0 0,22 0 0 0,6 0 0 0,
|
|
79
vendor/golang.org/x/net/bpf/testdata/all_instructions.txt
generated
vendored
79
vendor/golang.org/x/net/bpf/testdata/all_instructions.txt
generated
vendored
@ -1,79 +0,0 @@
|
|||||||
# This filter is compiled to all_instructions.bpf by the `bpf_asm`
|
|
||||||
# tool, which can be found in the linux kernel source tree under
|
|
||||||
# tools/net.
|
|
||||||
|
|
||||||
# Load immediate
|
|
||||||
ld #42
|
|
||||||
ldx #42
|
|
||||||
|
|
||||||
# Load scratch
|
|
||||||
ld M[3]
|
|
||||||
ldx M[3]
|
|
||||||
|
|
||||||
# Load absolute
|
|
||||||
ldb [42]
|
|
||||||
ldh [42]
|
|
||||||
ld [42]
|
|
||||||
|
|
||||||
# Load indirect
|
|
||||||
ldb [x + 42]
|
|
||||||
ldh [x + 42]
|
|
||||||
ld [x + 42]
|
|
||||||
|
|
||||||
# Load IPv4 header length
|
|
||||||
ldx 4*([42]&0xf)
|
|
||||||
|
|
||||||
# Run extension function
|
|
||||||
ld #len
|
|
||||||
ld #proto
|
|
||||||
ld #type
|
|
||||||
ld #rand
|
|
||||||
|
|
||||||
# Store scratch
|
|
||||||
st M[3]
|
|
||||||
stx M[3]
|
|
||||||
|
|
||||||
# A <op> constant
|
|
||||||
add #42
|
|
||||||
sub #42
|
|
||||||
mul #42
|
|
||||||
div #42
|
|
||||||
or #42
|
|
||||||
and #42
|
|
||||||
lsh #42
|
|
||||||
rsh #42
|
|
||||||
mod #42
|
|
||||||
xor #42
|
|
||||||
|
|
||||||
# A <op> X
|
|
||||||
add x
|
|
||||||
sub x
|
|
||||||
mul x
|
|
||||||
div x
|
|
||||||
or x
|
|
||||||
and x
|
|
||||||
lsh x
|
|
||||||
rsh x
|
|
||||||
mod x
|
|
||||||
xor x
|
|
||||||
|
|
||||||
# !A
|
|
||||||
neg
|
|
||||||
|
|
||||||
# Jumps
|
|
||||||
ja end
|
|
||||||
jeq #42,prev,end
|
|
||||||
jne #42,end
|
|
||||||
jlt #42,end
|
|
||||||
jle #42,end
|
|
||||||
jgt #42,prev,end
|
|
||||||
jge #42,prev,end
|
|
||||||
jset #42,prev,end
|
|
||||||
|
|
||||||
# Register transfers
|
|
||||||
tax
|
|
||||||
txa
|
|
||||||
|
|
||||||
# Returns
|
|
||||||
prev: ret a
|
|
||||||
end: ret #42
|
|
512
vendor/golang.org/x/net/bpf/vm_aluop_test.go
generated
vendored
512
vendor/golang.org/x/net/bpf/vm_aluop_test.go
generated
vendored
@ -1,512 +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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMALUOpAdd(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpAdd,
|
|
||||||
Val: 3,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
8, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 3, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpSub(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.TAX{},
|
|
||||||
bpf.ALUOpX{
|
|
||||||
Op: bpf.ALUOpSub,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpMul(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpMul,
|
|
||||||
Val: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
6, 2, 3, 4,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpDiv(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpDiv,
|
|
||||||
Val: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
20, 2, 3, 4,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpDivByZeroALUOpConstant(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpDiv,
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot divide by zero using ALUOpConstant" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpDivByZeroALUOpX(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load byte 0 into X
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.TAX{},
|
|
||||||
// Load byte 1 into A
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 9,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Attempt to perform 1/0
|
|
||||||
bpf.ALUOpX{
|
|
||||||
Op: bpf.ALUOpDiv,
|
|
||||||
},
|
|
||||||
// Return 4 bytes if program does not terminate
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 3, 4,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpOr(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpOr,
|
|
||||||
Val: 0x01,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x10, 0x03, 0x04,
|
|
||||||
0x05, 0x06, 0x07, 0x08,
|
|
||||||
0x09, 0xff,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 9, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpAnd(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpAnd,
|
|
||||||
Val: 0x0019,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xaa, 0x09,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpShiftLeft(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpShiftLeft,
|
|
||||||
Val: 0x01,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 0x02,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x01, 0xaa,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpShiftRight(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpShiftRight,
|
|
||||||
Val: 0x01,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 0x04,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x08, 0xff, 0xff,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpMod(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpMod,
|
|
||||||
Val: 20,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
30, 0, 0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpModByZeroALUOpConstant(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpMod,
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot divide by zero using ALUOpConstant" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpModByZeroALUOpX(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load byte 0 into X
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.TAX{},
|
|
||||||
// Load byte 1 into A
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 9,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Attempt to perform 1%0
|
|
||||||
bpf.ALUOpX{
|
|
||||||
Op: bpf.ALUOpMod,
|
|
||||||
},
|
|
||||||
// Return 4 bytes if program does not terminate
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 3, 4,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpXor(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpXor,
|
|
||||||
Val: 0x0a,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 0x01,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x0b, 0x00, 0x00, 0x00,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpUnknown(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpAdd,
|
|
||||||
Val: 1,
|
|
||||||
},
|
|
||||||
// Verify that an unknown operation is a no-op
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: 100,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 0x02,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
192
vendor/golang.org/x/net/bpf/vm_bpf_test.go
generated
vendored
192
vendor/golang.org/x/net/bpf/vm_bpf_test.go
generated
vendored
@ -1,192 +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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A virtualMachine is a BPF virtual machine which can process an
|
|
||||||
// input packet against a BPF program and render a verdict.
|
|
||||||
type virtualMachine interface {
|
|
||||||
Run(in []byte) (int, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// canUseOSVM indicates if the OS BPF VM is available on this platform.
|
|
||||||
func canUseOSVM() bool {
|
|
||||||
// OS BPF VM can only be used on platforms where x/net/ipv4 supports
|
|
||||||
// attaching a BPF program to a socket.
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "linux":
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// All BPF tests against both the Go VM and OS VM are assumed to
|
|
||||||
// be used with a UDP socket. As a result, the entire contents
|
|
||||||
// of a UDP datagram is sent through the BPF program, but only
|
|
||||||
// the body after the UDP header will ever be returned in output.
|
|
||||||
|
|
||||||
// testVM sets up a Go BPF VM, and if available, a native OS BPF VM
|
|
||||||
// for integration testing.
|
|
||||||
func testVM(t *testing.T, filter []bpf.Instruction) (virtualMachine, func(), error) {
|
|
||||||
goVM, err := bpf.NewVM(filter)
|
|
||||||
if err != nil {
|
|
||||||
// Some tests expect an error, so this error must be returned
|
|
||||||
// instead of fatally exiting the test
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
mvm := &multiVirtualMachine{
|
|
||||||
goVM: goVM,
|
|
||||||
|
|
||||||
t: t,
|
|
||||||
}
|
|
||||||
|
|
||||||
// If available, add the OS VM for tests which verify that both the Go
|
|
||||||
// VM and OS VM have exactly the same output for the same input program
|
|
||||||
// and packet.
|
|
||||||
done := func() {}
|
|
||||||
if canUseOSVM() {
|
|
||||||
osVM, osVMDone := testOSVM(t, filter)
|
|
||||||
done = func() { osVMDone() }
|
|
||||||
mvm.osVM = osVM
|
|
||||||
}
|
|
||||||
|
|
||||||
return mvm, done, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// udpHeaderLen is the length of a UDP header.
|
|
||||||
const udpHeaderLen = 8
|
|
||||||
|
|
||||||
// A multiVirtualMachine is a virtualMachine which can call out to both the Go VM
|
|
||||||
// and the native OS VM, if the OS VM is available.
|
|
||||||
type multiVirtualMachine struct {
|
|
||||||
goVM virtualMachine
|
|
||||||
osVM virtualMachine
|
|
||||||
|
|
||||||
t *testing.T
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mvm *multiVirtualMachine) Run(in []byte) (int, error) {
|
|
||||||
if len(in) < udpHeaderLen {
|
|
||||||
mvm.t.Fatalf("input must be at least length of UDP header (%d), got: %d",
|
|
||||||
udpHeaderLen, len(in))
|
|
||||||
}
|
|
||||||
|
|
||||||
// All tests have a UDP header as part of input, because the OS VM
|
|
||||||
// packets always will. For the Go VM, this output is trimmed before
|
|
||||||
// being sent back to tests.
|
|
||||||
goOut, goErr := mvm.goVM.Run(in)
|
|
||||||
if goOut >= udpHeaderLen {
|
|
||||||
goOut -= udpHeaderLen
|
|
||||||
}
|
|
||||||
|
|
||||||
// If Go output is larger than the size of the packet, packet filtering
|
|
||||||
// interop tests must trim the output bytes to the length of the packet.
|
|
||||||
// The BPF VM should not do this on its own, as other uses of it do
|
|
||||||
// not trim the output byte count.
|
|
||||||
trim := len(in) - udpHeaderLen
|
|
||||||
if goOut > trim {
|
|
||||||
goOut = trim
|
|
||||||
}
|
|
||||||
|
|
||||||
// When the OS VM is not available, process using the Go VM alone
|
|
||||||
if mvm.osVM == nil {
|
|
||||||
return goOut, goErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// The OS VM will apply its own UDP header, so remove the pseudo header
|
|
||||||
// that the Go VM needs.
|
|
||||||
osOut, err := mvm.osVM.Run(in[udpHeaderLen:])
|
|
||||||
if err != nil {
|
|
||||||
mvm.t.Fatalf("error while running OS VM: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify both VMs return same number of bytes
|
|
||||||
var mismatch bool
|
|
||||||
if goOut != osOut {
|
|
||||||
mismatch = true
|
|
||||||
mvm.t.Logf("output byte count does not match:\n- go: %v\n- os: %v", goOut, osOut)
|
|
||||||
}
|
|
||||||
|
|
||||||
if mismatch {
|
|
||||||
mvm.t.Fatal("Go BPF and OS BPF packet outputs do not match")
|
|
||||||
}
|
|
||||||
|
|
||||||
return goOut, goErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// An osVirtualMachine is a virtualMachine which uses the OS's BPF VM for
|
|
||||||
// processing BPF programs.
|
|
||||||
type osVirtualMachine struct {
|
|
||||||
l net.PacketConn
|
|
||||||
s net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
// testOSVM creates a virtualMachine which uses the OS's BPF VM by injecting
|
|
||||||
// packets into a UDP listener with a BPF program attached to it.
|
|
||||||
func testOSVM(t *testing.T, filter []bpf.Instruction) (virtualMachine, func()) {
|
|
||||||
l, err := net.ListenPacket("udp4", "127.0.0.1:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to open OS VM UDP listener: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
prog, err := bpf.Assemble(filter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to compile BPF program: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p := ipv4.NewPacketConn(l)
|
|
||||||
if err = p.SetBPF(prog); err != nil {
|
|
||||||
t.Fatalf("failed to attach BPF program to listener: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s, err := net.Dial("udp4", l.LocalAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to dial connection to listener: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
done := func() {
|
|
||||||
_ = s.Close()
|
|
||||||
_ = l.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
return &osVirtualMachine{
|
|
||||||
l: l,
|
|
||||||
s: s,
|
|
||||||
}, done
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run sends the input bytes into the OS's BPF VM and returns its verdict.
|
|
||||||
func (vm *osVirtualMachine) Run(in []byte) (int, error) {
|
|
||||||
go func() {
|
|
||||||
_, _ = vm.s.Write(in)
|
|
||||||
}()
|
|
||||||
|
|
||||||
vm.l.SetDeadline(time.Now().Add(50 * time.Millisecond))
|
|
||||||
|
|
||||||
var b [512]byte
|
|
||||||
n, _, err := vm.l.ReadFrom(b[:])
|
|
||||||
if err != nil {
|
|
||||||
// A timeout indicates that BPF filtered out the packet, and thus,
|
|
||||||
// no input should be returned.
|
|
||||||
if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
|
49
vendor/golang.org/x/net/bpf/vm_extension_test.go
generated
vendored
49
vendor/golang.org/x/net/bpf/vm_extension_test.go
generated
vendored
@ -1,49 +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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMLoadExtensionNotImplemented(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadExtension{
|
|
||||||
Num: 100,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "extension 100 not implemented" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadExtensionExtLen(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadExtension{
|
|
||||||
Num: bpf.ExtLen,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
380
vendor/golang.org/x/net/bpf/vm_jump_test.go
generated
vendored
380
vendor/golang.org/x/net/bpf/vm_jump_test.go
generated
vendored
@ -1,380 +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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMJumpOne(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.Jump{
|
|
||||||
Skip: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpOutOfProgram(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.Jump{
|
|
||||||
Skip: 1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot jump 1 instructions; jumping past program bounds" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfTrueOutOfProgram(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
SkipTrue: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot jump 2 instructions in true case; jumping past program bounds" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfFalseOutOfProgram(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
SkipFalse: 3,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot jump 3 instructions in false case; jumping past program bounds" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 1,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfNotEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpNotEqual,
|
|
||||||
Val: 1,
|
|
||||||
SkipFalse: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfGreaterThan(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpGreaterThan,
|
|
||||||
Val: 0x00010202,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfLessThan(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpLessThan,
|
|
||||||
Val: 0xff010203,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfGreaterOrEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpGreaterOrEqual,
|
|
||||||
Val: 0x00010203,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfLessOrEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpLessOrEqual,
|
|
||||||
Val: 0xff010203,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfBitsSet(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpBitsSet,
|
|
||||||
Val: 0x1122,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 10,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x01, 0x02,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfBitsNotSet(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpBitsNotSet,
|
|
||||||
Val: 0x1221,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 10,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x01, 0x02,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
246
vendor/golang.org/x/net/bpf/vm_load_test.go
generated
vendored
246
vendor/golang.org/x/net/bpf/vm_load_test.go
generated
vendored
@ -1,246 +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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMLoadAbsoluteOffsetOutOfBounds(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 100,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadAbsoluteOffsetPlusSizeOutOfBounds(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadAbsoluteBadInstructionSize(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Size: 5,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid load byte length 0" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadConstantOK(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
bpf.TXA{},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadIndirectOutOfBounds(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadIndirect{
|
|
||||||
Off: 100,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadMemShiftOutOfBounds(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadMemShift{
|
|
||||||
Off: 100,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
dhcp4Port = 53
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMLoadMemShiftLoadIndirectNoResult(t *testing.T) {
|
|
||||||
vm, in, done := testDHCPv4(t)
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
// Append mostly empty UDP header with incorrect DHCPv4 port
|
|
||||||
in = append(in, []byte{
|
|
||||||
0, 0,
|
|
||||||
0, dhcp4Port + 1,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
}...)
|
|
||||||
|
|
||||||
out, err := vm.Run(in)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadMemShiftLoadIndirectOK(t *testing.T) {
|
|
||||||
vm, in, done := testDHCPv4(t)
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
// Append mostly empty UDP header with correct DHCPv4 port
|
|
||||||
in = append(in, []byte{
|
|
||||||
0, 0,
|
|
||||||
0, dhcp4Port,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
}...)
|
|
||||||
|
|
||||||
out, err := vm.Run(in)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := len(in)-8, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDHCPv4(t *testing.T) (virtualMachine, []byte, func()) {
|
|
||||||
// DHCPv4 test data courtesy of David Anderson:
|
|
||||||
// https://github.com/google/netboot/blob/master/dhcp4/conn_linux.go#L59-L70
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load IPv4 packet length
|
|
||||||
bpf.LoadMemShift{Off: 8},
|
|
||||||
// Get UDP dport
|
|
||||||
bpf.LoadIndirect{Off: 8 + 2, Size: 2},
|
|
||||||
// Correct dport?
|
|
||||||
bpf.JumpIf{Cond: bpf.JumpEqual, Val: dhcp4Port, SkipFalse: 1},
|
|
||||||
// Accept
|
|
||||||
bpf.RetConstant{Val: 1500},
|
|
||||||
// Ignore
|
|
||||||
bpf.RetConstant{Val: 0},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minimal requirements to make a valid IPv4 header
|
|
||||||
h := &ipv4.Header{
|
|
||||||
Len: ipv4.HeaderLen,
|
|
||||||
Src: net.IPv4(192, 168, 1, 1),
|
|
||||||
Dst: net.IPv4(192, 168, 1, 2),
|
|
||||||
}
|
|
||||||
hb, err := h.Marshal()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal IPv4 header: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
hb = append([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
}, hb...)
|
|
||||||
|
|
||||||
return vm, hb, done
|
|
||||||
}
|
|
115
vendor/golang.org/x/net/bpf/vm_ret_test.go
generated
vendored
115
vendor/golang.org/x/net/bpf/vm_ret_test.go
generated
vendored
@ -1,115 +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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMRetA(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
9,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMRetALargerThanInput(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 255,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMRetConstant(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMRetConstantLargerThanInput(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 16,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
247
vendor/golang.org/x/net/bpf/vm_scratch_test.go
generated
vendored
247
vendor/golang.org/x/net/bpf/vm_scratch_test.go
generated
vendored
@ -1,247 +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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMStoreScratchInvalidScratchRegisterTooSmall(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: -1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMStoreScratchInvalidScratchRegisterTooLarge(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 16,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMStoreScratchUnknownSourceRegister(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: 100,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid source register 100" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadScratchInvalidScratchRegisterTooSmall(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
N: -1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadScratchInvalidScratchRegisterTooLarge(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
N: 16,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadScratchUnknownDestinationRegister(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: 100,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid target register 100" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMStoreScratchLoadScratchOneValue(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load byte 255
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Copy to X and store in scratch[0]
|
|
||||||
bpf.TAX{},
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegX,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
// Load byte 1
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 9,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Overwrite 1 with 255 from scratch[0]
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
// Return 255
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
255, 1, 2,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 3, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMStoreScratchLoadScratchMultipleValues(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load byte 10
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Store in scratch[0]
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
// Load byte 20
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 9,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Store in scratch[1]
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 1,
|
|
||||||
},
|
|
||||||
// Load byte 30
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 10,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Store in scratch[2]
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 2,
|
|
||||||
},
|
|
||||||
// Load byte 1
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 11,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Store in scratch[3]
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 3,
|
|
||||||
},
|
|
||||||
// Load in byte 10 to X
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
// Copy X -> A
|
|
||||||
bpf.TXA{},
|
|
||||||
// Verify value is 10
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 10,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
// Fail test if incorrect
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
// Load in byte 20 to A
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
N: 1,
|
|
||||||
},
|
|
||||||
// Verify value is 20
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 20,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
// Fail test if incorrect
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
// Load in byte 30 to A
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
N: 2,
|
|
||||||
},
|
|
||||||
// Verify value is 30
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 30,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
// Fail test if incorrect
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
// Return first two bytes on success
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 10,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
10, 20, 30, 1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
144
vendor/golang.org/x/net/bpf/vm_test.go
generated
vendored
144
vendor/golang.org/x/net/bpf/vm_test.go
generated
vendored
@ -1,144 +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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ bpf.Instruction = unknown{}
|
|
||||||
|
|
||||||
type unknown struct{}
|
|
||||||
|
|
||||||
func (unknown) Assemble() (bpf.RawInstruction, error) {
|
|
||||||
return bpf.RawInstruction{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMUnknownInstruction(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
Val: 100,
|
|
||||||
},
|
|
||||||
// Should terminate the program with an error immediately
|
|
||||||
unknown{},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
_, err = vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x00,
|
|
||||||
})
|
|
||||||
if errStr(err) != "unknown Instruction at index 1: bpf_test.unknown" {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMNoReturnInstruction(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
Val: 1,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if errStr(err) != "BPF program must end with RetA or RetConstant" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMNoInputInstructions(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{})
|
|
||||||
if errStr(err) != "one or more Instructions must be specified" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExampleNewVM demonstrates usage of a VM, using an Ethernet frame
|
|
||||||
// as input and checking its EtherType to determine if it should be accepted.
|
|
||||||
func ExampleNewVM() {
|
|
||||||
// Offset | Length | Comment
|
|
||||||
// -------------------------
|
|
||||||
// 00 | 06 | Ethernet destination MAC address
|
|
||||||
// 06 | 06 | Ethernet source MAC address
|
|
||||||
// 12 | 02 | Ethernet EtherType
|
|
||||||
const (
|
|
||||||
etOff = 12
|
|
||||||
etLen = 2
|
|
||||||
|
|
||||||
etARP = 0x0806
|
|
||||||
)
|
|
||||||
|
|
||||||
// Set up a VM to filter traffic based on if its EtherType
|
|
||||||
// matches the ARP EtherType.
|
|
||||||
vm, err := bpf.NewVM([]bpf.Instruction{
|
|
||||||
// Load EtherType value from Ethernet header
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: etOff,
|
|
||||||
Size: etLen,
|
|
||||||
},
|
|
||||||
// If EtherType is equal to the ARP EtherType, jump to allow
|
|
||||||
// packet to be accepted
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: etARP,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
// EtherType does not match the ARP EtherType
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
// EtherType matches the ARP EtherType, accept up to 1500
|
|
||||||
// bytes of packet
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 1500,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("failed to load BPF program: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an Ethernet frame with the ARP EtherType for testing
|
|
||||||
frame := []byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
|
|
||||||
0x08, 0x06,
|
|
||||||
// Payload omitted for brevity
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run our VM's BPF program using the Ethernet frame as input
|
|
||||||
out, err := vm.Run(frame)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("failed to accept Ethernet frame: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// BPF VM can return a byte count greater than the number of input
|
|
||||||
// bytes, so trim the output to match the input byte length
|
|
||||||
if out > len(frame) {
|
|
||||||
out = len(frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("out: %d bytes", out)
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// out: 14 bytes
|
|
||||||
}
|
|
||||||
|
|
||||||
// errStr returns the string representation of an error, or
|
|
||||||
// "<nil>" if it is nil.
|
|
||||||
func errStr(err error) string {
|
|
||||||
if err == nil {
|
|
||||||
return "<nil>"
|
|
||||||
}
|
|
||||||
|
|
||||||
return err.Error()
|
|
||||||
}
|
|
274
vendor/golang.org/x/net/icmp/diag_test.go
generated
vendored
274
vendor/golang.org/x/net/icmp/diag_test.go
generated
vendored
@ -1,274 +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 icmp_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
type diagTest struct {
|
|
||||||
network, address string
|
|
||||||
protocol int
|
|
||||||
m icmp.Message
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDiag(t *testing.T) {
|
|
||||||
if testing.Short() {
|
|
||||||
t.Skip("avoid external network")
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("Ping/NonPrivileged", func(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
case "linux":
|
|
||||||
t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state")
|
|
||||||
default:
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i, dt := range []diagTest{
|
|
||||||
{
|
|
||||||
"udp4", "0.0.0.0", iana.ProtocolICMP,
|
|
||||||
icmp.Message{
|
|
||||||
Type: ipv4.ICMPTypeEcho, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"udp6", "::", iana.ProtocolIPv6ICMP,
|
|
||||||
icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
if err := doDiag(dt, i); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("Ping/Privileged", func(t *testing.T) {
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
for i, dt := range []diagTest{
|
|
||||||
{
|
|
||||||
"ip4:icmp", "0.0.0.0", iana.ProtocolICMP,
|
|
||||||
icmp.Message{
|
|
||||||
Type: ipv4.ICMPTypeEcho, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP,
|
|
||||||
icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
if err := doDiag(dt, i); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("Probe/Privileged", func(t *testing.T) {
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
for i, dt := range []diagTest{
|
|
||||||
{
|
|
||||||
"ip4:icmp", "0.0.0.0", iana.ProtocolICMP,
|
|
||||||
icmp.Message{
|
|
||||||
Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: os.Getpid() & 0xffff,
|
|
||||||
Local: true,
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3, Type: 1,
|
|
||||||
Name: "doesnotexist",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP,
|
|
||||||
icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: os.Getpid() & 0xffff,
|
|
||||||
Local: true,
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3, Type: 1,
|
|
||||||
Name: "doesnotexist",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
if err := doDiag(dt, i); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func doDiag(dt diagTest, seq int) error {
|
|
||||||
c, err := icmp.ListenPacket(dt.network, dt.address)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
dst, err := googleAddr(c, dt.protocol)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if dt.network != "udp6" && dt.protocol == iana.ProtocolIPv6ICMP {
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Accept(ipv6.ICMPTypeDestinationUnreachable)
|
|
||||||
f.Accept(ipv6.ICMPTypePacketTooBig)
|
|
||||||
f.Accept(ipv6.ICMPTypeTimeExceeded)
|
|
||||||
f.Accept(ipv6.ICMPTypeParameterProblem)
|
|
||||||
f.Accept(ipv6.ICMPTypeEchoReply)
|
|
||||||
f.Accept(ipv6.ICMPTypeExtendedEchoReply)
|
|
||||||
if err := c.IPv6PacketConn().SetICMPFilter(&f); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch m := dt.m.Body.(type) {
|
|
||||||
case *icmp.Echo:
|
|
||||||
m.Seq = 1 << uint(seq)
|
|
||||||
case *icmp.ExtendedEchoRequest:
|
|
||||||
m.Seq = 1 << uint(seq)
|
|
||||||
}
|
|
||||||
wb, err := dt.m.Marshal(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if n, err := c.WriteTo(wb, dst); err != nil {
|
|
||||||
return err
|
|
||||||
} else if n != len(wb) {
|
|
||||||
return fmt.Errorf("got %v; want %v", n, len(wb))
|
|
||||||
}
|
|
||||||
|
|
||||||
rb := make([]byte, 1500)
|
|
||||||
if err := c.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
n, peer, err := c.ReadFrom(rb)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
rm, err := icmp.ParseMessage(dt.protocol, rb[:n])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case dt.m.Type == ipv4.ICMPTypeEcho && rm.Type == ipv4.ICMPTypeEchoReply:
|
|
||||||
fallthrough
|
|
||||||
case dt.m.Type == ipv6.ICMPTypeEchoRequest && rm.Type == ipv6.ICMPTypeEchoReply:
|
|
||||||
fallthrough
|
|
||||||
case dt.m.Type == ipv4.ICMPTypeExtendedEchoRequest && rm.Type == ipv4.ICMPTypeExtendedEchoReply:
|
|
||||||
fallthrough
|
|
||||||
case dt.m.Type == ipv6.ICMPTypeExtendedEchoRequest && rm.Type == ipv6.ICMPTypeExtendedEchoReply:
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("got %+v from %v; want echo reply or extended echo reply", rm, peer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func googleAddr(c *icmp.PacketConn, protocol int) (net.Addr, error) {
|
|
||||||
host := "ipv4.google.com"
|
|
||||||
if protocol == iana.ProtocolIPv6ICMP {
|
|
||||||
host = "ipv6.google.com"
|
|
||||||
}
|
|
||||||
ips, err := net.LookupIP(host)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
netaddr := func(ip net.IP) (net.Addr, error) {
|
|
||||||
switch c.LocalAddr().(type) {
|
|
||||||
case *net.UDPAddr:
|
|
||||||
return &net.UDPAddr{IP: ip}, nil
|
|
||||||
case *net.IPAddr:
|
|
||||||
return &net.IPAddr{IP: ip}, nil
|
|
||||||
default:
|
|
||||||
return nil, errors.New("neither UDPAddr nor IPAddr")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(ips) > 0 {
|
|
||||||
return netaddr(ips[0])
|
|
||||||
}
|
|
||||||
return nil, errors.New("no A or AAAA record")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConcurrentNonPrivilegedListenPacket(t *testing.T) {
|
|
||||||
if testing.Short() {
|
|
||||||
t.Skip("avoid external network")
|
|
||||||
}
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
case "linux":
|
|
||||||
t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state")
|
|
||||||
default:
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
network, address := "udp4", "127.0.0.1"
|
|
||||||
if !nettest.SupportsIPv4() {
|
|
||||||
network, address = "udp6", "::1"
|
|
||||||
}
|
|
||||||
const N = 1000
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(N)
|
|
||||||
for i := 0; i < N; i++ {
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
c, err := icmp.ListenPacket(network, address)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Close()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
63
vendor/golang.org/x/net/icmp/example_test.go
generated
vendored
63
vendor/golang.org/x/net/icmp/example_test.go
generated
vendored
@ -1,63 +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 icmp_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExamplePacketConn_nonPrivilegedPing() {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
case "linux":
|
|
||||||
log.Println("you may need to adjust the net.ipv4.ping_group_range kernel state")
|
|
||||||
default:
|
|
||||||
log.Println("not supported on", runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := icmp.ListenPacket("udp6", "fe80::1%en0")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
wm := icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff, Seq: 1,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wb, err := wm.Marshal(nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, err := c.WriteTo(wb, &net.UDPAddr{IP: net.ParseIP("ff02::1"), Zone: "en0"}); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rb := make([]byte, 1500)
|
|
||||||
n, peer, err := c.ReadFrom(rb)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
rm, err := icmp.ParseMessage(58, rb[:n])
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
switch rm.Type {
|
|
||||||
case ipv6.ICMPTypeEchoReply:
|
|
||||||
log.Printf("got reflection from %v", peer)
|
|
||||||
default:
|
|
||||||
log.Printf("got %+v; want echo reply", rm)
|
|
||||||
}
|
|
||||||
}
|
|
333
vendor/golang.org/x/net/icmp/extension_test.go
generated
vendored
333
vendor/golang.org/x/net/icmp/extension_test.go
generated
vendored
@ -1,333 +0,0 @@
|
|||||||
// Copyright 2015 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 icmp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMarshalAndParseExtension(t *testing.T) {
|
|
||||||
fn := func(t *testing.T, proto int, typ Type, hdr, obj []byte, te Extension) error {
|
|
||||||
b, err := te.Marshal(proto)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(b, obj) {
|
|
||||||
return fmt.Errorf("got %#v; want %#v", b, obj)
|
|
||||||
}
|
|
||||||
switch typ {
|
|
||||||
case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
|
|
||||||
exts, l, err := parseExtensions(typ, append(hdr, obj...), 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if l != 0 {
|
|
||||||
return fmt.Errorf("got %d; want 0", l)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(exts, []Extension{te}) {
|
|
||||||
return fmt.Errorf("got %#v; want %#v", exts[0], te)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
for i, wire := range []struct {
|
|
||||||
data []byte // original datagram
|
|
||||||
inlattr int // length of padded original datagram, a hint
|
|
||||||
outlattr int // length of padded original datagram, a want
|
|
||||||
err error
|
|
||||||
}{
|
|
||||||
{nil, 0, -1, errNoExtension},
|
|
||||||
{make([]byte, 127), 128, -1, errNoExtension},
|
|
||||||
|
|
||||||
{make([]byte, 128), 127, -1, errNoExtension},
|
|
||||||
{make([]byte, 128), 128, -1, errNoExtension},
|
|
||||||
{make([]byte, 128), 129, -1, errNoExtension},
|
|
||||||
|
|
||||||
{append(make([]byte, 128), append(hdr, obj...)...), 127, 128, nil},
|
|
||||||
{append(make([]byte, 128), append(hdr, obj...)...), 128, 128, nil},
|
|
||||||
{append(make([]byte, 128), append(hdr, obj...)...), 129, 128, nil},
|
|
||||||
|
|
||||||
{append(make([]byte, 512), append(hdr, obj...)...), 511, -1, errNoExtension},
|
|
||||||
{append(make([]byte, 512), append(hdr, obj...)...), 512, 512, nil},
|
|
||||||
{append(make([]byte, 512), append(hdr, obj...)...), 513, -1, errNoExtension},
|
|
||||||
} {
|
|
||||||
exts, l, err := parseExtensions(typ, wire.data, wire.inlattr)
|
|
||||||
if err != wire.err {
|
|
||||||
return fmt.Errorf("#%d: got %v; want %v", i, err, wire.err)
|
|
||||||
}
|
|
||||||
if wire.err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if l != wire.outlattr {
|
|
||||||
return fmt.Errorf("#%d: got %d; want %d", i, l, wire.outlattr)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(exts, []Extension{te}) {
|
|
||||||
return fmt.Errorf("#%d: got %#v; want %#v", i, exts[0], te)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("MPLSLabelStack", func(t *testing.T) {
|
|
||||||
for _, et := range []struct {
|
|
||||||
proto int
|
|
||||||
typ Type
|
|
||||||
hdr []byte
|
|
||||||
obj []byte
|
|
||||||
ext Extension
|
|
||||||
}{
|
|
||||||
// MPLS label stack with no label
|
|
||||||
{
|
|
||||||
proto: iana.ProtocolICMP,
|
|
||||||
typ: ipv4.ICMPTypeDestinationUnreachable,
|
|
||||||
hdr: []byte{
|
|
||||||
0x20, 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
obj: []byte{
|
|
||||||
0x00, 0x04, 0x01, 0x01,
|
|
||||||
},
|
|
||||||
ext: &MPLSLabelStack{
|
|
||||||
Class: classMPLSLabelStack,
|
|
||||||
Type: typeIncomingMPLSLabelStack,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// MPLS label stack with a single label
|
|
||||||
{
|
|
||||||
proto: iana.ProtocolIPv6ICMP,
|
|
||||||
typ: ipv6.ICMPTypeDestinationUnreachable,
|
|
||||||
hdr: []byte{
|
|
||||||
0x20, 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
obj: []byte{
|
|
||||||
0x00, 0x08, 0x01, 0x01,
|
|
||||||
0x03, 0xe8, 0xe9, 0xff,
|
|
||||||
},
|
|
||||||
ext: &MPLSLabelStack{
|
|
||||||
Class: classMPLSLabelStack,
|
|
||||||
Type: typeIncomingMPLSLabelStack,
|
|
||||||
Labels: []MPLSLabel{
|
|
||||||
{
|
|
||||||
Label: 16014,
|
|
||||||
TC: 0x4,
|
|
||||||
S: true,
|
|
||||||
TTL: 255,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// MPLS label stack with multiple labels
|
|
||||||
{
|
|
||||||
proto: iana.ProtocolICMP,
|
|
||||||
typ: ipv4.ICMPTypeDestinationUnreachable,
|
|
||||||
hdr: []byte{
|
|
||||||
0x20, 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
obj: []byte{
|
|
||||||
0x00, 0x0c, 0x01, 0x01,
|
|
||||||
0x03, 0xe8, 0xde, 0xfe,
|
|
||||||
0x03, 0xe8, 0xe1, 0xff,
|
|
||||||
},
|
|
||||||
ext: &MPLSLabelStack{
|
|
||||||
Class: classMPLSLabelStack,
|
|
||||||
Type: typeIncomingMPLSLabelStack,
|
|
||||||
Labels: []MPLSLabel{
|
|
||||||
{
|
|
||||||
Label: 16013,
|
|
||||||
TC: 0x7,
|
|
||||||
S: false,
|
|
||||||
TTL: 254,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: 16014,
|
|
||||||
TC: 0,
|
|
||||||
S: true,
|
|
||||||
TTL: 255,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("InterfaceInfo", func(t *testing.T) {
|
|
||||||
for _, et := range []struct {
|
|
||||||
proto int
|
|
||||||
typ Type
|
|
||||||
hdr []byte
|
|
||||||
obj []byte
|
|
||||||
ext Extension
|
|
||||||
}{
|
|
||||||
// Interface information with no attribute
|
|
||||||
{
|
|
||||||
proto: iana.ProtocolICMP,
|
|
||||||
typ: ipv4.ICMPTypeDestinationUnreachable,
|
|
||||||
hdr: []byte{
|
|
||||||
0x20, 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
obj: []byte{
|
|
||||||
0x00, 0x04, 0x02, 0x00,
|
|
||||||
},
|
|
||||||
ext: &InterfaceInfo{
|
|
||||||
Class: classInterfaceInfo,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Interface information with ifIndex and name
|
|
||||||
{
|
|
||||||
proto: iana.ProtocolICMP,
|
|
||||||
typ: ipv4.ICMPTypeDestinationUnreachable,
|
|
||||||
hdr: []byte{
|
|
||||||
0x20, 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
obj: []byte{
|
|
||||||
0x00, 0x10, 0x02, 0x0a,
|
|
||||||
0x00, 0x00, 0x00, 0x10,
|
|
||||||
0x08, byte('e'), byte('n'), byte('1'),
|
|
||||||
byte('0'), byte('1'), 0x00, 0x00,
|
|
||||||
},
|
|
||||||
ext: &InterfaceInfo{
|
|
||||||
Class: classInterfaceInfo,
|
|
||||||
Type: 0x0a,
|
|
||||||
Interface: &net.Interface{
|
|
||||||
Index: 16,
|
|
||||||
Name: "en101",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Interface information with ifIndex, IPAddr, name and MTU
|
|
||||||
{
|
|
||||||
proto: iana.ProtocolIPv6ICMP,
|
|
||||||
typ: ipv6.ICMPTypeDestinationUnreachable,
|
|
||||||
hdr: []byte{
|
|
||||||
0x20, 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
obj: []byte{
|
|
||||||
0x00, 0x28, 0x02, 0x0f,
|
|
||||||
0x00, 0x00, 0x00, 0x0f,
|
|
||||||
0x00, 0x02, 0x00, 0x00,
|
|
||||||
0xfe, 0x80, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x08, byte('e'), byte('n'), byte('1'),
|
|
||||||
byte('0'), byte('1'), 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x20, 0x00,
|
|
||||||
},
|
|
||||||
ext: &InterfaceInfo{
|
|
||||||
Class: classInterfaceInfo,
|
|
||||||
Type: 0x0f,
|
|
||||||
Interface: &net.Interface{
|
|
||||||
Index: 15,
|
|
||||||
Name: "en101",
|
|
||||||
MTU: 8192,
|
|
||||||
},
|
|
||||||
Addr: &net.IPAddr{
|
|
||||||
IP: net.ParseIP("fe80::1"),
|
|
||||||
Zone: "en101",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("InterfaceIdent", func(t *testing.T) {
|
|
||||||
for _, et := range []struct {
|
|
||||||
proto int
|
|
||||||
typ Type
|
|
||||||
hdr []byte
|
|
||||||
obj []byte
|
|
||||||
ext Extension
|
|
||||||
}{
|
|
||||||
// Interface identification by name
|
|
||||||
{
|
|
||||||
proto: iana.ProtocolICMP,
|
|
||||||
typ: ipv4.ICMPTypeExtendedEchoRequest,
|
|
||||||
hdr: []byte{
|
|
||||||
0x20, 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
obj: []byte{
|
|
||||||
0x00, 0x0c, 0x03, 0x01,
|
|
||||||
byte('e'), byte('n'), byte('1'), byte('0'),
|
|
||||||
byte('1'), 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
ext: &InterfaceIdent{
|
|
||||||
Class: classInterfaceIdent,
|
|
||||||
Type: typeInterfaceByName,
|
|
||||||
Name: "en101",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Interface identification by index
|
|
||||||
{
|
|
||||||
proto: iana.ProtocolIPv6ICMP,
|
|
||||||
typ: ipv6.ICMPTypeExtendedEchoRequest,
|
|
||||||
hdr: []byte{
|
|
||||||
0x20, 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
obj: []byte{
|
|
||||||
0x00, 0x0c, 0x03, 0x02,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x03, 0x8f,
|
|
||||||
},
|
|
||||||
ext: &InterfaceIdent{
|
|
||||||
Class: classInterfaceIdent,
|
|
||||||
Type: typeInterfaceByIndex,
|
|
||||||
Index: 911,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Interface identification by address
|
|
||||||
{
|
|
||||||
proto: iana.ProtocolICMP,
|
|
||||||
typ: ipv4.ICMPTypeExtendedEchoRequest,
|
|
||||||
hdr: []byte{
|
|
||||||
0x20, 0x00, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
obj: []byte{
|
|
||||||
0x00, 0x10, 0x03, 0x03,
|
|
||||||
byte(iana.AddrFamily48bitMAC >> 8), byte(iana.AddrFamily48bitMAC & 0x0f), 0x06, 0x00,
|
|
||||||
0x01, 0x23, 0x45, 0x67,
|
|
||||||
0x89, 0xab, 0x00, 0x00,
|
|
||||||
},
|
|
||||||
ext: &InterfaceIdent{
|
|
||||||
Class: classInterfaceIdent,
|
|
||||||
Type: typeInterfaceByAddress,
|
|
||||||
AFI: iana.AddrFamily48bitMAC,
|
|
||||||
Addr: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseInterfaceName(t *testing.T) {
|
|
||||||
ifi := InterfaceInfo{Interface: &net.Interface{}}
|
|
||||||
for i, tt := range []struct {
|
|
||||||
b []byte
|
|
||||||
error
|
|
||||||
}{
|
|
||||||
{[]byte{0, 'e', 'n', '0'}, errInvalidExtension},
|
|
||||||
{[]byte{4, 'e', 'n', '0'}, nil},
|
|
||||||
{[]byte{7, 'e', 'n', '0', 0xff, 0xff, 0xff, 0xff}, errInvalidExtension},
|
|
||||||
{[]byte{8, 'e', 'n', '0', 0xff, 0xff, 0xff}, errMessageTooShort},
|
|
||||||
} {
|
|
||||||
if _, err := ifi.parseName(tt.b); err != tt.error {
|
|
||||||
t.Errorf("#%d: got %v; want %v", i, err, tt.error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
75
vendor/golang.org/x/net/icmp/ipv4_test.go
generated
vendored
75
vendor/golang.org/x/net/icmp/ipv4_test.go
generated
vendored
@ -1,75 +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 icmp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/socket"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseIPv4Header(t *testing.T) {
|
|
||||||
switch socket.NativeEndian {
|
|
||||||
case binary.LittleEndian:
|
|
||||||
t.Run("LittleEndian", func(t *testing.T) {
|
|
||||||
// TODO(mikio): Add platform dependent wire
|
|
||||||
// header formats when we support new
|
|
||||||
// platforms.
|
|
||||||
wireHeaderFromKernel := [ipv4.HeaderLen]byte{
|
|
||||||
0x45, 0x01, 0xbe, 0xef,
|
|
||||||
0xca, 0xfe, 0x45, 0xdc,
|
|
||||||
0xff, 0x01, 0xde, 0xad,
|
|
||||||
172, 16, 254, 254,
|
|
||||||
192, 168, 0, 1,
|
|
||||||
}
|
|
||||||
wireHeaderFromTradBSDKernel := [ipv4.HeaderLen]byte{
|
|
||||||
0x45, 0x01, 0xef, 0xbe,
|
|
||||||
0xca, 0xfe, 0x45, 0xdc,
|
|
||||||
0xff, 0x01, 0xde, 0xad,
|
|
||||||
172, 16, 254, 254,
|
|
||||||
192, 168, 0, 1,
|
|
||||||
}
|
|
||||||
th := &ipv4.Header{
|
|
||||||
Version: ipv4.Version,
|
|
||||||
Len: ipv4.HeaderLen,
|
|
||||||
TOS: 1,
|
|
||||||
TotalLen: 0xbeef,
|
|
||||||
ID: 0xcafe,
|
|
||||||
Flags: ipv4.DontFragment,
|
|
||||||
FragOff: 1500,
|
|
||||||
TTL: 255,
|
|
||||||
Protocol: 1,
|
|
||||||
Checksum: 0xdead,
|
|
||||||
Src: net.IPv4(172, 16, 254, 254),
|
|
||||||
Dst: net.IPv4(192, 168, 0, 1),
|
|
||||||
}
|
|
||||||
var wh []byte
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
wh = wireHeaderFromTradBSDKernel[:]
|
|
||||||
case "freebsd":
|
|
||||||
if freebsdVersion >= 1000000 {
|
|
||||||
wh = wireHeaderFromKernel[:]
|
|
||||||
} else {
|
|
||||||
wh = wireHeaderFromTradBSDKernel[:]
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
wh = wireHeaderFromKernel[:]
|
|
||||||
}
|
|
||||||
h, err := ParseIPv4Header(wh)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(h, th) {
|
|
||||||
t.Fatalf("got %#v; want %#v", h, th)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
155
vendor/golang.org/x/net/icmp/message_test.go
generated
vendored
155
vendor/golang.org/x/net/icmp/message_test.go
generated
vendored
@ -1,155 +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 icmp_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMarshalAndParseMessage(t *testing.T) {
|
|
||||||
fn := func(t *testing.T, proto int, tms []icmp.Message) {
|
|
||||||
var pshs [][]byte
|
|
||||||
switch proto {
|
|
||||||
case iana.ProtocolICMP:
|
|
||||||
pshs = [][]byte{nil}
|
|
||||||
case iana.ProtocolIPv6ICMP:
|
|
||||||
pshs = [][]byte{
|
|
||||||
icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1")),
|
|
||||||
nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, tm := range tms {
|
|
||||||
for _, psh := range pshs {
|
|
||||||
b, err := tm.Marshal(psh)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
m, err := icmp.ParseMessage(proto, b)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if m.Type != tm.Type || m.Code != tm.Code {
|
|
||||||
t.Errorf("#%d: got %#v; want %#v", i, m, &tm)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(m.Body, tm.Body) {
|
|
||||||
t.Errorf("#%d: got %#v; want %#v", i, m.Body, tm.Body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("IPv4", func(t *testing.T) {
|
|
||||||
fn(t, iana.ProtocolICMP,
|
|
||||||
[]icmp.Message{
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
|
|
||||||
Body: &icmp.DstUnreach{
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
|
|
||||||
Body: &icmp.TimeExceeded{
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeParameterProblem, Code: 2,
|
|
||||||
Body: &icmp.ParamProb{
|
|
||||||
Pointer: 8,
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeEcho, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: 1, Seq: 2,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: 1, Seq: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeExtendedEchoReply, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoReply{
|
|
||||||
State: 4 /* Delay */, Active: true, IPv4: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypePhoturis,
|
|
||||||
Body: &icmp.DefaultMessageBody{
|
|
||||||
Data: []byte{0x80, 0x40, 0x20, 0x10},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
t.Run("IPv6", func(t *testing.T) {
|
|
||||||
fn(t, iana.ProtocolIPv6ICMP,
|
|
||||||
[]icmp.Message{
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
|
|
||||||
Body: &icmp.DstUnreach{
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypePacketTooBig, Code: 0,
|
|
||||||
Body: &icmp.PacketTooBig{
|
|
||||||
MTU: 1<<16 - 1,
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
|
|
||||||
Body: &icmp.TimeExceeded{
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeParameterProblem, Code: 2,
|
|
||||||
Body: &icmp.ParamProb{
|
|
||||||
Pointer: 8,
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: 1, Seq: 2,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: 1, Seq: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeExtendedEchoReply, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoReply{
|
|
||||||
State: 5 /* Probe */, Active: true, IPv6: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeDuplicateAddressConfirmation,
|
|
||||||
Body: &icmp.DefaultMessageBody{
|
|
||||||
Data: []byte{0x80, 0x40, 0x20, 0x10},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
575
vendor/golang.org/x/net/icmp/multipart_test.go
generated
vendored
575
vendor/golang.org/x/net/icmp/multipart_test.go
generated
vendored
@ -1,575 +0,0 @@
|
|||||||
// Copyright 2015 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 icmp_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMarshalAndParseMultipartMessage(t *testing.T) {
|
|
||||||
fn := func(t *testing.T, proto int, tm icmp.Message) error {
|
|
||||||
b, err := tm.Marshal(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch tm.Type {
|
|
||||||
case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
|
|
||||||
default:
|
|
||||||
switch proto {
|
|
||||||
case iana.ProtocolICMP:
|
|
||||||
if b[5] != 32 {
|
|
||||||
return fmt.Errorf("got %d; want 32", b[5])
|
|
||||||
}
|
|
||||||
case iana.ProtocolIPv6ICMP:
|
|
||||||
if b[4] != 16 {
|
|
||||||
return fmt.Errorf("got %d; want 16", b[4])
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unknown protocol: %d", proto)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m, err := icmp.ParseMessage(proto, b)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if m.Type != tm.Type || m.Code != tm.Code {
|
|
||||||
return fmt.Errorf("got %v; want %v", m, &tm)
|
|
||||||
}
|
|
||||||
switch m.Type {
|
|
||||||
case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
|
|
||||||
got, want := m.Body.(*icmp.ExtendedEchoRequest), tm.Body.(*icmp.ExtendedEchoRequest)
|
|
||||||
if !reflect.DeepEqual(got.Extensions, want.Extensions) {
|
|
||||||
return errors.New(dumpExtensions(got.Extensions, want.Extensions))
|
|
||||||
}
|
|
||||||
case ipv4.ICMPTypeDestinationUnreachable:
|
|
||||||
got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach)
|
|
||||||
if !reflect.DeepEqual(got.Extensions, want.Extensions) {
|
|
||||||
return errors.New(dumpExtensions(got.Extensions, want.Extensions))
|
|
||||||
}
|
|
||||||
if len(got.Data) != 128 {
|
|
||||||
return fmt.Errorf("got %d; want 128", len(got.Data))
|
|
||||||
}
|
|
||||||
case ipv4.ICMPTypeTimeExceeded:
|
|
||||||
got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded)
|
|
||||||
if !reflect.DeepEqual(got.Extensions, want.Extensions) {
|
|
||||||
return errors.New(dumpExtensions(got.Extensions, want.Extensions))
|
|
||||||
}
|
|
||||||
if len(got.Data) != 128 {
|
|
||||||
return fmt.Errorf("got %d; want 128", len(got.Data))
|
|
||||||
}
|
|
||||||
case ipv4.ICMPTypeParameterProblem:
|
|
||||||
got, want := m.Body.(*icmp.ParamProb), tm.Body.(*icmp.ParamProb)
|
|
||||||
if !reflect.DeepEqual(got.Extensions, want.Extensions) {
|
|
||||||
return errors.New(dumpExtensions(got.Extensions, want.Extensions))
|
|
||||||
}
|
|
||||||
if len(got.Data) != 128 {
|
|
||||||
return fmt.Errorf("got %d; want 128", len(got.Data))
|
|
||||||
}
|
|
||||||
case ipv6.ICMPTypeDestinationUnreachable:
|
|
||||||
got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach)
|
|
||||||
if !reflect.DeepEqual(got.Extensions, want.Extensions) {
|
|
||||||
return errors.New(dumpExtensions(got.Extensions, want.Extensions))
|
|
||||||
}
|
|
||||||
if len(got.Data) != 128 {
|
|
||||||
return fmt.Errorf("got %d; want 128", len(got.Data))
|
|
||||||
}
|
|
||||||
case ipv6.ICMPTypeTimeExceeded:
|
|
||||||
got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded)
|
|
||||||
if !reflect.DeepEqual(got.Extensions, want.Extensions) {
|
|
||||||
return errors.New(dumpExtensions(got.Extensions, want.Extensions))
|
|
||||||
}
|
|
||||||
if len(got.Data) != 128 {
|
|
||||||
return fmt.Errorf("got %d; want 128", len(got.Data))
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unknown message type: %v", m.Type)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("IPv4", func(t *testing.T) {
|
|
||||||
for i, tm := range []icmp.Message{
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
|
|
||||||
Body: &icmp.DstUnreach{
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.MPLSLabelStack{
|
|
||||||
Class: 1,
|
|
||||||
Type: 1,
|
|
||||||
Labels: []icmp.MPLSLabel{
|
|
||||||
{
|
|
||||||
Label: 16014,
|
|
||||||
TC: 0x4,
|
|
||||||
S: true,
|
|
||||||
TTL: 255,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&icmp.InterfaceInfo{
|
|
||||||
Class: 2,
|
|
||||||
Type: 0x0f,
|
|
||||||
Interface: &net.Interface{
|
|
||||||
Index: 15,
|
|
||||||
Name: "en101",
|
|
||||||
MTU: 8192,
|
|
||||||
},
|
|
||||||
Addr: &net.IPAddr{
|
|
||||||
IP: net.IPv4(192, 168, 0, 1).To4(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
|
|
||||||
Body: &icmp.TimeExceeded{
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceInfo{
|
|
||||||
Class: 2,
|
|
||||||
Type: 0x0f,
|
|
||||||
Interface: &net.Interface{
|
|
||||||
Index: 15,
|
|
||||||
Name: "en101",
|
|
||||||
MTU: 8192,
|
|
||||||
},
|
|
||||||
Addr: &net.IPAddr{
|
|
||||||
IP: net.IPv4(192, 168, 0, 1).To4(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&icmp.MPLSLabelStack{
|
|
||||||
Class: 1,
|
|
||||||
Type: 1,
|
|
||||||
Labels: []icmp.MPLSLabel{
|
|
||||||
{
|
|
||||||
Label: 16014,
|
|
||||||
TC: 0x4,
|
|
||||||
S: true,
|
|
||||||
TTL: 255,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeParameterProblem, Code: 2,
|
|
||||||
Body: &icmp.ParamProb{
|
|
||||||
Pointer: 8,
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.MPLSLabelStack{
|
|
||||||
Class: 1,
|
|
||||||
Type: 1,
|
|
||||||
Labels: []icmp.MPLSLabel{
|
|
||||||
{
|
|
||||||
Label: 16014,
|
|
||||||
TC: 0x4,
|
|
||||||
S: true,
|
|
||||||
TTL: 255,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&icmp.InterfaceInfo{
|
|
||||||
Class: 2,
|
|
||||||
Type: 0x0f,
|
|
||||||
Interface: &net.Interface{
|
|
||||||
Index: 15,
|
|
||||||
Name: "en101",
|
|
||||||
MTU: 8192,
|
|
||||||
},
|
|
||||||
Addr: &net.IPAddr{
|
|
||||||
IP: net.IPv4(192, 168, 0, 1).To4(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&icmp.InterfaceInfo{
|
|
||||||
Class: 2,
|
|
||||||
Type: 0x2f,
|
|
||||||
Interface: &net.Interface{
|
|
||||||
Index: 16,
|
|
||||||
Name: "en102",
|
|
||||||
MTU: 8192,
|
|
||||||
},
|
|
||||||
Addr: &net.IPAddr{
|
|
||||||
IP: net.IPv4(192, 168, 0, 2).To4(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: 1, Seq: 2, Local: true,
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3,
|
|
||||||
Type: 1,
|
|
||||||
Name: "en101",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: 1, Seq: 2, Local: true,
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3,
|
|
||||||
Type: 2,
|
|
||||||
Index: 911,
|
|
||||||
},
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3,
|
|
||||||
Type: 1,
|
|
||||||
Name: "en101",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: 1, Seq: 2,
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3,
|
|
||||||
Type: 3,
|
|
||||||
AFI: iana.AddrFamily48bitMAC,
|
|
||||||
Addr: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
if err := fn(t, iana.ProtocolICMP, tm); err != nil {
|
|
||||||
t.Errorf("#%d: %v", i, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("IPv6", func(t *testing.T) {
|
|
||||||
for i, tm := range []icmp.Message{
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
|
|
||||||
Body: &icmp.DstUnreach{
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.MPLSLabelStack{
|
|
||||||
Class: 1,
|
|
||||||
Type: 1,
|
|
||||||
Labels: []icmp.MPLSLabel{
|
|
||||||
{
|
|
||||||
Label: 16014,
|
|
||||||
TC: 0x4,
|
|
||||||
S: true,
|
|
||||||
TTL: 255,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&icmp.InterfaceInfo{
|
|
||||||
Class: 2,
|
|
||||||
Type: 0x0f,
|
|
||||||
Interface: &net.Interface{
|
|
||||||
Index: 15,
|
|
||||||
Name: "en101",
|
|
||||||
MTU: 8192,
|
|
||||||
},
|
|
||||||
Addr: &net.IPAddr{
|
|
||||||
IP: net.ParseIP("fe80::1"),
|
|
||||||
Zone: "en101",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
|
|
||||||
Body: &icmp.TimeExceeded{
|
|
||||||
Data: []byte("ERROR-INVOKING-PACKET"),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceInfo{
|
|
||||||
Class: 2,
|
|
||||||
Type: 0x0f,
|
|
||||||
Interface: &net.Interface{
|
|
||||||
Index: 15,
|
|
||||||
Name: "en101",
|
|
||||||
MTU: 8192,
|
|
||||||
},
|
|
||||||
Addr: &net.IPAddr{
|
|
||||||
IP: net.ParseIP("fe80::1"),
|
|
||||||
Zone: "en101",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&icmp.MPLSLabelStack{
|
|
||||||
Class: 1,
|
|
||||||
Type: 1,
|
|
||||||
Labels: []icmp.MPLSLabel{
|
|
||||||
{
|
|
||||||
Label: 16014,
|
|
||||||
TC: 0x4,
|
|
||||||
S: true,
|
|
||||||
TTL: 255,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&icmp.InterfaceInfo{
|
|
||||||
Class: 2,
|
|
||||||
Type: 0x2f,
|
|
||||||
Interface: &net.Interface{
|
|
||||||
Index: 16,
|
|
||||||
Name: "en102",
|
|
||||||
MTU: 8192,
|
|
||||||
},
|
|
||||||
Addr: &net.IPAddr{
|
|
||||||
IP: net.ParseIP("fe80::1"),
|
|
||||||
Zone: "en102",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: 1, Seq: 2, Local: true,
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3,
|
|
||||||
Type: 1,
|
|
||||||
Name: "en101",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: 1, Seq: 2, Local: true,
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3,
|
|
||||||
Type: 1,
|
|
||||||
Name: "en101",
|
|
||||||
},
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3,
|
|
||||||
Type: 2,
|
|
||||||
Index: 911,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.ExtendedEchoRequest{
|
|
||||||
ID: 1, Seq: 2,
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Class: 3,
|
|
||||||
Type: 3,
|
|
||||||
AFI: iana.AddrFamilyIPv4,
|
|
||||||
Addr: []byte{192, 0, 2, 1},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
if err := fn(t, iana.ProtocolIPv6ICMP, tm); err != nil {
|
|
||||||
t.Errorf("#%d: %v", i, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func dumpExtensions(gotExts, wantExts []icmp.Extension) string {
|
|
||||||
var s string
|
|
||||||
for i, got := range gotExts {
|
|
||||||
switch got := got.(type) {
|
|
||||||
case *icmp.MPLSLabelStack:
|
|
||||||
want := wantExts[i].(*icmp.MPLSLabelStack)
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
|
||||||
s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want)
|
|
||||||
}
|
|
||||||
case *icmp.InterfaceInfo:
|
|
||||||
want := wantExts[i].(*icmp.InterfaceInfo)
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
|
||||||
s += fmt.Sprintf("#%d: got %#v, %#v, %#v; want %#v, %#v, %#v\n", i, got, got.Interface, got.Addr, want, want.Interface, want.Addr)
|
|
||||||
}
|
|
||||||
case *icmp.InterfaceIdent:
|
|
||||||
want := wantExts[i].(*icmp.InterfaceIdent)
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
|
||||||
s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(s) == 0 {
|
|
||||||
return "<nil>"
|
|
||||||
}
|
|
||||||
return s[:len(s)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMultipartMessageBodyLen(t *testing.T) {
|
|
||||||
for i, tt := range []struct {
|
|
||||||
proto int
|
|
||||||
in icmp.MessageBody
|
|
||||||
out int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
iana.ProtocolICMP,
|
|
||||||
&icmp.DstUnreach{
|
|
||||||
Data: make([]byte, ipv4.HeaderLen),
|
|
||||||
},
|
|
||||||
4 + ipv4.HeaderLen, // unused and original datagram
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolICMP,
|
|
||||||
&icmp.TimeExceeded{
|
|
||||||
Data: make([]byte, ipv4.HeaderLen),
|
|
||||||
},
|
|
||||||
4 + ipv4.HeaderLen, // unused and original datagram
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolICMP,
|
|
||||||
&icmp.ParamProb{
|
|
||||||
Data: make([]byte, ipv4.HeaderLen),
|
|
||||||
},
|
|
||||||
4 + ipv4.HeaderLen, // [pointer, unused] and original datagram
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
iana.ProtocolICMP,
|
|
||||||
&icmp.ParamProb{
|
|
||||||
Data: make([]byte, ipv4.HeaderLen),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.MPLSLabelStack{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolICMP,
|
|
||||||
&icmp.ParamProb{
|
|
||||||
Data: make([]byte, 128),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.MPLSLabelStack{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolICMP,
|
|
||||||
&icmp.ParamProb{
|
|
||||||
Data: make([]byte, 129),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.MPLSLabelStack{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
iana.ProtocolIPv6ICMP,
|
|
||||||
&icmp.DstUnreach{
|
|
||||||
Data: make([]byte, ipv6.HeaderLen),
|
|
||||||
},
|
|
||||||
4 + ipv6.HeaderLen, // unused and original datagram
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolIPv6ICMP,
|
|
||||||
&icmp.PacketTooBig{
|
|
||||||
Data: make([]byte, ipv6.HeaderLen),
|
|
||||||
},
|
|
||||||
4 + ipv6.HeaderLen, // mtu and original datagram
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolIPv6ICMP,
|
|
||||||
&icmp.TimeExceeded{
|
|
||||||
Data: make([]byte, ipv6.HeaderLen),
|
|
||||||
},
|
|
||||||
4 + ipv6.HeaderLen, // unused and original datagram
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolIPv6ICMP,
|
|
||||||
&icmp.ParamProb{
|
|
||||||
Data: make([]byte, ipv6.HeaderLen),
|
|
||||||
},
|
|
||||||
4 + ipv6.HeaderLen, // pointer and original datagram
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
iana.ProtocolIPv6ICMP,
|
|
||||||
&icmp.DstUnreach{
|
|
||||||
Data: make([]byte, 127),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.MPLSLabelStack{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolIPv6ICMP,
|
|
||||||
&icmp.DstUnreach{
|
|
||||||
Data: make([]byte, 128),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.MPLSLabelStack{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolIPv6ICMP,
|
|
||||||
&icmp.DstUnreach{
|
|
||||||
Data: make([]byte, 129),
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.MPLSLabelStack{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
iana.ProtocolICMP,
|
|
||||||
&icmp.ExtendedEchoRequest{},
|
|
||||||
4, // [id, seq, l-bit]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolICMP,
|
|
||||||
&icmp.ExtendedEchoRequest{
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
4 + 4 + 4, // [id, seq, l-bit], extension header, object header
|
|
||||||
},
|
|
||||||
{
|
|
||||||
iana.ProtocolIPv6ICMP,
|
|
||||||
&icmp.ExtendedEchoRequest{
|
|
||||||
Extensions: []icmp.Extension{
|
|
||||||
&icmp.InterfaceIdent{
|
|
||||||
Type: 3,
|
|
||||||
AFI: iana.AddrFamilyNSAP,
|
|
||||||
Addr: []byte{0x49, 0x00, 0x01, 0xaa, 0xaa, 0xbb, 0xbb, 0xcc, 0xcc, 0x00},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
4 + 4 + 4 + 16, // [id, seq, l-bit], extension header, object header, object payload
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
if out := tt.in.Len(tt.proto); out != tt.out {
|
|
||||||
t.Errorf("#%d: got %d; want %d", i, out, tt.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
53
vendor/golang.org/x/net/internal/nettest/helper_bsd.go
generated
vendored
53
vendor/golang.org/x/net/internal/nettest/helper_bsd.go
generated
vendored
@ -1,53 +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.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd netbsd openbsd
|
|
||||||
|
|
||||||
package nettest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
var darwinVersion int
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
if runtime.GOOS == "darwin" {
|
|
||||||
// See http://support.apple.com/kb/HT1633.
|
|
||||||
s, err := syscall.Sysctl("kern.osrelease")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ss := strings.Split(s, ".")
|
|
||||||
if len(ss) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
darwinVersion, _ = strconv.Atoi(ss[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func supportsIPv6MulticastDeliveryOnLoopback() bool {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "freebsd":
|
|
||||||
// See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
|
|
||||||
// Even after the fix, it looks like the latest
|
|
||||||
// kernels don't deliver link-local scoped multicast
|
|
||||||
// packets correctly.
|
|
||||||
return false
|
|
||||||
case "darwin":
|
|
||||||
return !causesIPv6Crash()
|
|
||||||
default:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func causesIPv6Crash() bool {
|
|
||||||
// We see some kernel crash when running IPv6 with IP-level
|
|
||||||
// options on Darwin kernel version 12 or below.
|
|
||||||
// See golang.org/issues/17015.
|
|
||||||
return darwinVersion < 13
|
|
||||||
}
|
|
15
vendor/golang.org/x/net/internal/nettest/helper_nobsd.go
generated
vendored
15
vendor/golang.org/x/net/internal/nettest/helper_nobsd.go
generated
vendored
@ -1,15 +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.
|
|
||||||
|
|
||||||
// +build linux solaris
|
|
||||||
|
|
||||||
package nettest
|
|
||||||
|
|
||||||
func supportsIPv6MulticastDeliveryOnLoopback() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func causesIPv6Crash() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
31
vendor/golang.org/x/net/internal/nettest/helper_posix.go
generated
vendored
31
vendor/golang.org/x/net/internal/nettest/helper_posix.go
generated
vendored
@ -1,31 +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.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
|
|
||||||
|
|
||||||
package nettest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func protocolNotSupported(err error) bool {
|
|
||||||
switch err := err.(type) {
|
|
||||||
case syscall.Errno:
|
|
||||||
switch err {
|
|
||||||
case syscall.EPROTONOSUPPORT, syscall.ENOPROTOOPT:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case *os.SyscallError:
|
|
||||||
switch err := err.Err.(type) {
|
|
||||||
case syscall.Errno:
|
|
||||||
switch err {
|
|
||||||
case syscall.EPROTONOSUPPORT, syscall.ENOPROTOOPT:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
32
vendor/golang.org/x/net/internal/nettest/helper_stub.go
generated
vendored
32
vendor/golang.org/x/net/internal/nettest/helper_stub.go
generated
vendored
@ -1,32 +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.
|
|
||||||
|
|
||||||
// +build js,wasm nacl plan9
|
|
||||||
|
|
||||||
package nettest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
func maxOpenFiles() int {
|
|
||||||
return defaultMaxOpenFiles
|
|
||||||
}
|
|
||||||
|
|
||||||
func supportsRawIPSocket() (string, bool) {
|
|
||||||
return fmt.Sprintf("not supported on %s", runtime.GOOS), false
|
|
||||||
}
|
|
||||||
|
|
||||||
func supportsIPv6MulticastDeliveryOnLoopback() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func causesIPv6Crash() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func protocolNotSupported(err error) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
29
vendor/golang.org/x/net/internal/nettest/helper_unix.go
generated
vendored
29
vendor/golang.org/x/net/internal/nettest/helper_unix.go
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2015 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 dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package nettest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func maxOpenFiles() int {
|
|
||||||
var rlim syscall.Rlimit
|
|
||||||
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
|
|
||||||
return defaultMaxOpenFiles
|
|
||||||
}
|
|
||||||
return int(rlim.Cur)
|
|
||||||
}
|
|
||||||
|
|
||||||
func supportsRawIPSocket() (string, bool) {
|
|
||||||
if os.Getuid() != 0 {
|
|
||||||
return fmt.Sprintf("must be root on %s", runtime.GOOS), false
|
|
||||||
}
|
|
||||||
return "", true
|
|
||||||
}
|
|
42
vendor/golang.org/x/net/internal/nettest/helper_windows.go
generated
vendored
42
vendor/golang.org/x/net/internal/nettest/helper_windows.go
generated
vendored
@ -1,42 +0,0 @@
|
|||||||
// Copyright 2015 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 nettest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func maxOpenFiles() int {
|
|
||||||
return 4 * defaultMaxOpenFiles /* actually it's 16581375 */
|
|
||||||
}
|
|
||||||
|
|
||||||
func supportsRawIPSocket() (string, bool) {
|
|
||||||
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548.aspx:
|
|
||||||
// Note: To use a socket of type SOCK_RAW requires administrative privileges.
|
|
||||||
// Users running Winsock applications that use raw sockets must be a member of
|
|
||||||
// the Administrators group on the local computer, otherwise raw socket calls
|
|
||||||
// will fail with an error code of WSAEACCES. On Windows Vista and later, access
|
|
||||||
// for raw sockets is enforced at socket creation. In earlier versions of Windows,
|
|
||||||
// access for raw sockets is enforced during other socket operations.
|
|
||||||
s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, 0)
|
|
||||||
if err == syscall.WSAEACCES {
|
|
||||||
return fmt.Sprintf("no access to raw socket allowed on %s", runtime.GOOS), false
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err.Error(), false
|
|
||||||
}
|
|
||||||
syscall.Closesocket(s)
|
|
||||||
return "", true
|
|
||||||
}
|
|
||||||
|
|
||||||
func supportsIPv6MulticastDeliveryOnLoopback() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func causesIPv6Crash() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
94
vendor/golang.org/x/net/internal/nettest/interface.go
generated
vendored
94
vendor/golang.org/x/net/internal/nettest/interface.go
generated
vendored
@ -1,94 +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 nettest
|
|
||||||
|
|
||||||
import "net"
|
|
||||||
|
|
||||||
// IsMulticastCapable reports whether ifi is an IP multicast-capable
|
|
||||||
// network interface. Network must be "ip", "ip4" or "ip6".
|
|
||||||
func IsMulticastCapable(network string, ifi *net.Interface) (net.IP, bool) {
|
|
||||||
switch network {
|
|
||||||
case "ip", "ip4", "ip6":
|
|
||||||
default:
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
if ifi == nil || ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
return hasRoutableIP(network, ifi)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RoutedInterface returns a network interface that can route IP
|
|
||||||
// traffic and satisfies flags. It returns nil when an appropriate
|
|
||||||
// network interface is not found. Network must be "ip", "ip4" or
|
|
||||||
// "ip6".
|
|
||||||
func RoutedInterface(network string, flags net.Flags) *net.Interface {
|
|
||||||
switch network {
|
|
||||||
case "ip", "ip4", "ip6":
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
for _, ifi := range ift {
|
|
||||||
if ifi.Flags&flags != flags {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, ok := hasRoutableIP(network, &ifi); !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return &ifi
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasRoutableIP(network string, ifi *net.Interface) (net.IP, bool) {
|
|
||||||
ifat, err := ifi.Addrs()
|
|
||||||
if err != nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
for _, ifa := range ifat {
|
|
||||||
switch ifa := ifa.(type) {
|
|
||||||
case *net.IPAddr:
|
|
||||||
if ip := routableIP(network, ifa.IP); ip != nil {
|
|
||||||
return ip, true
|
|
||||||
}
|
|
||||||
case *net.IPNet:
|
|
||||||
if ip := routableIP(network, ifa.IP); ip != nil {
|
|
||||||
return ip, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func routableIP(network string, ip net.IP) net.IP {
|
|
||||||
if !ip.IsLoopback() && !ip.IsLinkLocalUnicast() && !ip.IsGlobalUnicast() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
switch network {
|
|
||||||
case "ip4":
|
|
||||||
if ip := ip.To4(); ip != nil {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
case "ip6":
|
|
||||||
if ip.IsLoopback() { // addressing scope of the loopback address depends on each implementation
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if ip := ip.To16(); ip != nil && ip.To4() == nil {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if ip := ip.To4(); ip != nil {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
if ip := ip.To16(); ip != nil {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
11
vendor/golang.org/x/net/internal/nettest/rlimit.go
generated
vendored
11
vendor/golang.org/x/net/internal/nettest/rlimit.go
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
// Copyright 2015 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 nettest
|
|
||||||
|
|
||||||
const defaultMaxOpenFiles = 256
|
|
||||||
|
|
||||||
// MaxOpenFiles returns the maximum number of open files for the
|
|
||||||
// caller's process.
|
|
||||||
func MaxOpenFiles() int { return maxOpenFiles() }
|
|
152
vendor/golang.org/x/net/internal/nettest/stack.go
generated
vendored
152
vendor/golang.org/x/net/internal/nettest/stack.go
generated
vendored
@ -1,152 +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 nettest provides utilities for network testing.
|
|
||||||
package nettest // import "golang.org/x/net/internal/nettest"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
supportsIPv4 bool
|
|
||||||
supportsIPv6 bool
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
|
|
||||||
ln.Close()
|
|
||||||
supportsIPv4 = true
|
|
||||||
}
|
|
||||||
if ln, err := net.Listen("tcp6", "[::1]:0"); err == nil {
|
|
||||||
ln.Close()
|
|
||||||
supportsIPv6 = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsIPv4 reports whether the platform supports IPv4 networking
|
|
||||||
// functionality.
|
|
||||||
func SupportsIPv4() bool { return supportsIPv4 }
|
|
||||||
|
|
||||||
// SupportsIPv6 reports whether the platform supports IPv6 networking
|
|
||||||
// functionality.
|
|
||||||
func SupportsIPv6() bool { return supportsIPv6 }
|
|
||||||
|
|
||||||
// SupportsRawIPSocket reports whether the platform supports raw IP
|
|
||||||
// sockets.
|
|
||||||
func SupportsRawIPSocket() (string, bool) {
|
|
||||||
return supportsRawIPSocket()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsIPv6MulticastDeliveryOnLoopback reports whether the
|
|
||||||
// platform supports IPv6 multicast packet delivery on software
|
|
||||||
// loopback interface.
|
|
||||||
func SupportsIPv6MulticastDeliveryOnLoopback() bool {
|
|
||||||
return supportsIPv6MulticastDeliveryOnLoopback()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProtocolNotSupported reports whether err is a protocol not
|
|
||||||
// supported error.
|
|
||||||
func ProtocolNotSupported(err error) bool {
|
|
||||||
return protocolNotSupported(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestableNetwork reports whether network is testable on the current
|
|
||||||
// platform configuration.
|
|
||||||
func TestableNetwork(network string) bool {
|
|
||||||
// This is based on logic from standard library's
|
|
||||||
// net/platform_test.go.
|
|
||||||
switch network {
|
|
||||||
case "unix", "unixgram":
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "android", "js", "nacl", "plan9", "windows":
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case "unixpacket":
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "android", "darwin", "freebsd", "js", "nacl", "plan9", "windows":
|
|
||||||
return false
|
|
||||||
case "netbsd":
|
|
||||||
// It passes on amd64 at least. 386 fails (Issue 22927). arm is unknown.
|
|
||||||
if runtime.GOARCH == "386" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLocalListener returns a listener which listens to a loopback IP
|
|
||||||
// address or local file system path.
|
|
||||||
// Network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
|
|
||||||
func NewLocalListener(network string) (net.Listener, error) {
|
|
||||||
switch network {
|
|
||||||
case "tcp":
|
|
||||||
if supportsIPv4 {
|
|
||||||
if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
|
|
||||||
return ln, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if supportsIPv6 {
|
|
||||||
return net.Listen("tcp6", "[::1]:0")
|
|
||||||
}
|
|
||||||
case "tcp4":
|
|
||||||
if supportsIPv4 {
|
|
||||||
return net.Listen("tcp4", "127.0.0.1:0")
|
|
||||||
}
|
|
||||||
case "tcp6":
|
|
||||||
if supportsIPv6 {
|
|
||||||
return net.Listen("tcp6", "[::1]:0")
|
|
||||||
}
|
|
||||||
case "unix", "unixpacket":
|
|
||||||
return net.Listen(network, localPath())
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("%s is not supported", network)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLocalPacketListener returns a packet listener which listens to a
|
|
||||||
// loopback IP address or local file system path.
|
|
||||||
// Network must be "udp", "udp4", "udp6" or "unixgram".
|
|
||||||
func NewLocalPacketListener(network string) (net.PacketConn, error) {
|
|
||||||
switch network {
|
|
||||||
case "udp":
|
|
||||||
if supportsIPv4 {
|
|
||||||
if c, err := net.ListenPacket("udp4", "127.0.0.1:0"); err == nil {
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if supportsIPv6 {
|
|
||||||
return net.ListenPacket("udp6", "[::1]:0")
|
|
||||||
}
|
|
||||||
case "udp4":
|
|
||||||
if supportsIPv4 {
|
|
||||||
return net.ListenPacket("udp4", "127.0.0.1:0")
|
|
||||||
}
|
|
||||||
case "udp6":
|
|
||||||
if supportsIPv6 {
|
|
||||||
return net.ListenPacket("udp6", "[::1]:0")
|
|
||||||
}
|
|
||||||
case "unixgram":
|
|
||||||
return net.ListenPacket(network, localPath())
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("%s is not supported", network)
|
|
||||||
}
|
|
||||||
|
|
||||||
func localPath() string {
|
|
||||||
f, err := ioutil.TempFile("", "nettest")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
path := f.Name()
|
|
||||||
f.Close()
|
|
||||||
os.Remove(path)
|
|
||||||
return path
|
|
||||||
}
|
|
259
vendor/golang.org/x/net/internal/socket/socket_go1_9_test.go
generated
vendored
259
vendor/golang.org/x/net/internal/socket/socket_go1_9_test.go
generated
vendored
@ -1,259 +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
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package socket_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/internal/socket"
|
|
||||||
)
|
|
||||||
|
|
||||||
type mockControl struct {
|
|
||||||
Level int
|
|
||||||
Type int
|
|
||||||
Data []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestControlMessage(t *testing.T) {
|
|
||||||
for _, tt := range []struct {
|
|
||||||
cs []mockControl
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
[]mockControl{
|
|
||||||
{Level: 1, Type: 1},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]mockControl{
|
|
||||||
{Level: 2, Type: 2, Data: []byte{0xfe}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]mockControl{
|
|
||||||
{Level: 3, Type: 3, Data: []byte{0xfe, 0xff, 0xff, 0xfe}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]mockControl{
|
|
||||||
{Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]mockControl{
|
|
||||||
{Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
|
|
||||||
{Level: 2, Type: 2, Data: []byte{0xfe}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
var w []byte
|
|
||||||
var tailPadLen int
|
|
||||||
mm := socket.NewControlMessage([]int{0})
|
|
||||||
for i, c := range tt.cs {
|
|
||||||
m := socket.NewControlMessage([]int{len(c.Data)})
|
|
||||||
l := len(m) - len(mm)
|
|
||||||
if i == len(tt.cs)-1 && l > len(c.Data) {
|
|
||||||
tailPadLen = l - len(c.Data)
|
|
||||||
}
|
|
||||||
w = append(w, m...)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
ww := make([]byte, len(w))
|
|
||||||
copy(ww, w)
|
|
||||||
m := socket.ControlMessage(ww)
|
|
||||||
for _, c := range tt.cs {
|
|
||||||
if err = m.MarshalHeader(c.Level, c.Type, len(c.Data)); err != nil {
|
|
||||||
t.Fatalf("(%v).MarshalHeader() = %v", tt.cs, err)
|
|
||||||
}
|
|
||||||
copy(m.Data(len(c.Data)), c.Data)
|
|
||||||
m = m.Next(len(c.Data))
|
|
||||||
}
|
|
||||||
m = socket.ControlMessage(w)
|
|
||||||
for _, c := range tt.cs {
|
|
||||||
m, err = m.Marshal(c.Level, c.Type, c.Data)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("(%v).Marshal() = %v", tt.cs, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !bytes.Equal(ww, w) {
|
|
||||||
t.Fatalf("got %#v; want %#v", ww, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
ws := [][]byte{w}
|
|
||||||
if tailPadLen > 0 {
|
|
||||||
// Test a message with no tail padding.
|
|
||||||
nopad := w[:len(w)-tailPadLen]
|
|
||||||
ws = append(ws, [][]byte{nopad}...)
|
|
||||||
}
|
|
||||||
for _, w := range ws {
|
|
||||||
ms, err := socket.ControlMessage(w).Parse()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("(%v).Parse() = %v", tt.cs, err)
|
|
||||||
}
|
|
||||||
for i, m := range ms {
|
|
||||||
lvl, typ, dataLen, err := m.ParseHeader()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("(%v).ParseHeader() = %v", tt.cs, err)
|
|
||||||
}
|
|
||||||
if lvl != tt.cs[i].Level || typ != tt.cs[i].Type || dataLen != len(tt.cs[i].Data) {
|
|
||||||
t.Fatalf("%v: got %d, %d, %d; want %d, %d, %d", tt.cs[i], lvl, typ, dataLen, tt.cs[i].Level, tt.cs[i].Type, len(tt.cs[i].Data))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUDP(t *testing.T) {
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp")
|
|
||||||
if err != nil {
|
|
||||||
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
cc, err := socket.NewConn(c.(net.Conn))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("Message", func(t *testing.T) {
|
|
||||||
data := []byte("HELLO-R-U-THERE")
|
|
||||||
wm := socket.Message{
|
|
||||||
Buffers: bytes.SplitAfter(data, []byte("-")),
|
|
||||||
Addr: c.LocalAddr(),
|
|
||||||
}
|
|
||||||
if err := cc.SendMsg(&wm, 0); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
b := make([]byte, 32)
|
|
||||||
rm := socket.Message{
|
|
||||||
Buffers: [][]byte{b[:1], b[1:3], b[3:7], b[7:11], b[11:]},
|
|
||||||
}
|
|
||||||
if err := cc.RecvMsg(&rm, 0); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(b[:rm.N], data) {
|
|
||||||
t.Fatalf("got %#v; want %#v", b[:rm.N], data)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "android", "linux":
|
|
||||||
t.Run("Messages", func(t *testing.T) {
|
|
||||||
data := []byte("HELLO-R-U-THERE")
|
|
||||||
wmbs := bytes.SplitAfter(data, []byte("-"))
|
|
||||||
wms := []socket.Message{
|
|
||||||
{Buffers: wmbs[:1], Addr: c.LocalAddr()},
|
|
||||||
{Buffers: wmbs[1:], Addr: c.LocalAddr()},
|
|
||||||
}
|
|
||||||
n, err := cc.SendMsgs(wms, 0)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n != len(wms) {
|
|
||||||
t.Fatalf("got %d; want %d", n, len(wms))
|
|
||||||
}
|
|
||||||
b := make([]byte, 32)
|
|
||||||
rmbs := [][][]byte{{b[:len(wmbs[0])]}, {b[len(wmbs[0]):]}}
|
|
||||||
rms := []socket.Message{
|
|
||||||
{Buffers: rmbs[0]},
|
|
||||||
{Buffers: rmbs[1]},
|
|
||||||
}
|
|
||||||
n, err = cc.RecvMsgs(rms, 0)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n != len(rms) {
|
|
||||||
t.Fatalf("got %d; want %d", n, len(rms))
|
|
||||||
}
|
|
||||||
nn := 0
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
nn += rms[i].N
|
|
||||||
}
|
|
||||||
if !bytes.Equal(b[:nn], data) {
|
|
||||||
t.Fatalf("got %#v; want %#v", b[:nn], data)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// The behavior of transmission for zero byte paylaod depends
|
|
||||||
// on each platform implementation. Some may transmit only
|
|
||||||
// protocol header and options, other may transmit nothing.
|
|
||||||
// We test only that SendMsg and SendMsgs will not crash with
|
|
||||||
// empty buffers.
|
|
||||||
wm := socket.Message{
|
|
||||||
Buffers: [][]byte{{}},
|
|
||||||
Addr: c.LocalAddr(),
|
|
||||||
}
|
|
||||||
cc.SendMsg(&wm, 0)
|
|
||||||
wms := []socket.Message{
|
|
||||||
{Buffers: [][]byte{{}}, Addr: c.LocalAddr()},
|
|
||||||
}
|
|
||||||
cc.SendMsgs(wms, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkUDP(b *testing.B) {
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp")
|
|
||||||
if err != nil {
|
|
||||||
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
cc, err := socket.NewConn(c.(net.Conn))
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
data := []byte("HELLO-R-U-THERE")
|
|
||||||
wm := socket.Message{
|
|
||||||
Buffers: [][]byte{data},
|
|
||||||
Addr: c.LocalAddr(),
|
|
||||||
}
|
|
||||||
rm := socket.Message{
|
|
||||||
Buffers: [][]byte{make([]byte, 128)},
|
|
||||||
OOB: make([]byte, 128),
|
|
||||||
}
|
|
||||||
|
|
||||||
for M := 1; M <= 1<<9; M = M << 1 {
|
|
||||||
b.Run(fmt.Sprintf("Iter-%d", M), func(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
for j := 0; j < M; j++ {
|
|
||||||
if err := cc.SendMsg(&wm, 0); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := cc.RecvMsg(&rm, 0); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "android", "linux":
|
|
||||||
wms := make([]socket.Message, M)
|
|
||||||
for i := range wms {
|
|
||||||
wms[i].Buffers = [][]byte{data}
|
|
||||||
wms[i].Addr = c.LocalAddr()
|
|
||||||
}
|
|
||||||
rms := make([]socket.Message, M)
|
|
||||||
for i := range rms {
|
|
||||||
rms[i].Buffers = [][]byte{make([]byte, 128)}
|
|
||||||
rms[i].OOB = make([]byte, 128)
|
|
||||||
}
|
|
||||||
b.Run(fmt.Sprintf("Batch-%d", M), func(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
if _, err := cc.SendMsgs(wms, 0); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, err := cc.RecvMsgs(rms, 0); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
46
vendor/golang.org/x/net/internal/socket/socket_test.go
generated
vendored
46
vendor/golang.org/x/net/internal/socket/socket_test.go
generated
vendored
@ -1,46 +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 darwin dragonfly freebsd linux netbsd openbsd solaris windows
|
|
||||||
|
|
||||||
package socket_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/internal/socket"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSocket(t *testing.T) {
|
|
||||||
t.Run("Option", func(t *testing.T) {
|
|
||||||
testSocketOption(t, &socket.Option{Level: syscall.SOL_SOCKET, Name: syscall.SO_RCVBUF, Len: 4})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testSocketOption(t *testing.T, so *socket.Option) {
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp")
|
|
||||||
if err != nil {
|
|
||||||
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
cc, err := socket.NewConn(c.(net.Conn))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
const N = 2048
|
|
||||||
if err := so.SetInt(cc, N); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
n, err := so.GetInt(cc)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n < N {
|
|
||||||
t.Fatalf("got %d; want greater than or equal to %d", n, N)
|
|
||||||
}
|
|
||||||
}
|
|
93
vendor/golang.org/x/net/ipv4/bpf_test.go
generated
vendored
93
vendor/golang.org/x/net/ipv4/bpf_test.go
generated
vendored
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
21
vendor/golang.org/x/net/ipv4/control_test.go
generated
vendored
21
vendor/golang.org/x/net/ipv4/control_test.go
generated
vendored
@ -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))
|
|
||||||
}
|
|
||||||
}
|
|
224
vendor/golang.org/x/net/ipv4/example_test.go
generated
vendored
224
vendor/golang.org/x/net/ipv4/example_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
228
vendor/golang.org/x/net/ipv4/header_test.go
generated
vendored
228
vendor/golang.org/x/net/ipv4/header_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
95
vendor/golang.org/x/net/ipv4/icmp_test.go
generated
vendored
95
vendor/golang.org/x/net/ipv4/icmp_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
334
vendor/golang.org/x/net/ipv4/multicast_test.go
generated
vendored
334
vendor/golang.org/x/net/ipv4/multicast_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
265
vendor/golang.org/x/net/ipv4/multicastlistener_test.go
generated
vendored
265
vendor/golang.org/x/net/ipv4/multicastlistener_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
195
vendor/golang.org/x/net/ipv4/multicastsockopt_test.go
generated
vendored
195
vendor/golang.org/x/net/ipv4/multicastsockopt_test.go
generated
vendored
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
248
vendor/golang.org/x/net/ipv4/readwrite_go1_8_test.go
generated
vendored
248
vendor/golang.org/x/net/ipv4/readwrite_go1_8_test.go
generated
vendored
@ -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()
|
|
||||||
}
|
|
388
vendor/golang.org/x/net/ipv4/readwrite_go1_9_test.go
generated
vendored
388
vendor/golang.org/x/net/ipv4/readwrite_go1_9_test.go
generated
vendored
@ -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()
|
|
||||||
}
|
|
140
vendor/golang.org/x/net/ipv4/readwrite_test.go
generated
vendored
140
vendor/golang.org/x/net/ipv4/readwrite_test.go
generated
vendored
@ -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()
|
|
||||||
}
|
|
247
vendor/golang.org/x/net/ipv4/unicast_test.go
generated
vendored
247
vendor/golang.org/x/net/ipv4/unicast_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
148
vendor/golang.org/x/net/ipv4/unicastsockopt_test.go
generated
vendored
148
vendor/golang.org/x/net/ipv4/unicastsockopt_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
96
vendor/golang.org/x/net/ipv6/bpf_test.go
generated
vendored
96
vendor/golang.org/x/net/ipv6/bpf_test.go
generated
vendored
@ -1,96 +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 ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBPF(t *testing.T) {
|
|
||||||
if runtime.GOOS != "linux" {
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
l, err := net.ListenPacket("udp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer l.Close()
|
|
||||||
|
|
||||||
p := ipv6.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("udp6", 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
21
vendor/golang.org/x/net/ipv6/control_test.go
generated
vendored
21
vendor/golang.org/x/net/ipv6/control_test.go
generated
vendored
@ -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 ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestControlMessageParseWithFuzz(t *testing.T) {
|
|
||||||
var cm ipv6.ControlMessage
|
|
||||||
for _, fuzz := range []string{
|
|
||||||
"\f\x00\x00\x00)\x00\x00\x00.\x00\x00\x00",
|
|
||||||
"\f\x00\x00\x00)\x00\x00\x00,\x00\x00\x00",
|
|
||||||
} {
|
|
||||||
cm.Parse([]byte(fuzz))
|
|
||||||
}
|
|
||||||
}
|
|
216
vendor/golang.org/x/net/ipv6/example_test.go
generated
vendored
216
vendor/golang.org/x/net/ipv6/example_test.go
generated
vendored
@ -1,216 +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 ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleConn_markingTCP() {
|
|
||||||
ln, err := net.Listen("tcp", "[::]: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.To16() != nil && c.RemoteAddr().(*net.TCPAddr).IP.To4() == nil {
|
|
||||||
p := ipv6.NewConn(c)
|
|
||||||
if err := p.SetTrafficClass(0x28); err != nil { // DSCP AF11
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetHopLimit(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("udp6", "[::]:5353") // mDNS over UDP
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
en0, err := net.InterfaceByName("en0")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
mDNSLinkLocal := net.UDPAddr{IP: net.ParseIP("ff02::fb")}
|
|
||||||
if err := p.JoinGroup(en0, &mDNSLinkLocal); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer p.LeaveGroup(en0, &mDNSLinkLocal)
|
|
||||||
if err := p.SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var wcm ipv6.ControlMessage
|
|
||||||
b := make([]byte, 1500)
|
|
||||||
for {
|
|
||||||
_, rcm, peer, err := p.ReadFrom(b)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if !rcm.Dst.IsMulticast() || !rcm.Dst.Equal(mDNSLinkLocal.IP) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
wcm.IfIndex = rcm.IfIndex
|
|
||||||
answers := []byte("FAKE-MDNS-ANSWERS") // fake mDNS answers, you need to implement this
|
|
||||||
if _, err := p.WriteTo(answers, &wcm, 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.To16() != nil && 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 AAAA record found")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:58", "::") // ICMP for IPv6
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
if err := p.SetControlMessage(ipv6.FlagHopLimit|ipv6.FlagSrc|ipv6.FlagDst|ipv6.FlagInterface, true); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
wm := icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Accept(ipv6.ICMPTypeTimeExceeded)
|
|
||||||
f.Accept(ipv6.ICMPTypeEchoReply)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var wcm ipv6.ControlMessage
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
wcm.HopLimit = i
|
|
||||||
if _, err := p.WriteTo(wb, &wcm, &dst); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
n, rcm, 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(58, 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,
|
|
||||||
// ControlMesage.Dst, icmp.Echo.ID and icmp.Echo.Seq.
|
|
||||||
switch rm.Type {
|
|
||||||
case ipv6.ICMPTypeTimeExceeded:
|
|
||||||
names, _ := net.LookupAddr(peer.String())
|
|
||||||
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, rcm)
|
|
||||||
case ipv6.ICMPTypeEchoReply:
|
|
||||||
names, _ := net.LookupAddr(peer.String())
|
|
||||||
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, rcm)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExamplePacketConn_advertisingOSPFHello() {
|
|
||||||
c, err := net.ListenPacket("ip6:89", "::") // OSPF for IPv6
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
en0, err := net.InterfaceByName("en0")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
allSPFRouters := net.IPAddr{IP: net.ParseIP("ff02::5")}
|
|
||||||
if err := p.JoinGroup(en0, &allSPFRouters); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer p.LeaveGroup(en0, &allSPFRouters)
|
|
||||||
|
|
||||||
hello := make([]byte, 24) // fake hello data, you need to implement this
|
|
||||||
ospf := make([]byte, 16) // fake ospf header, you need to implement this
|
|
||||||
ospf[0] = 3 // version 3
|
|
||||||
ospf[1] = 1 // hello packet
|
|
||||||
ospf = append(ospf, hello...)
|
|
||||||
if err := p.SetChecksum(true, 12); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: 0xc0, // DSCP CS6
|
|
||||||
HopLimit: 1,
|
|
||||||
IfIndex: en0.Index,
|
|
||||||
}
|
|
||||||
if _, err := p.WriteTo(ospf, &cm, &allSPFRouters); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
55
vendor/golang.org/x/net/ipv6/header_test.go
generated
vendored
55
vendor/golang.org/x/net/ipv6/header_test.go
generated
vendored
@ -1,55 +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 ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
wireHeaderFromKernel = [ipv6.HeaderLen]byte{
|
|
||||||
0x69, 0x8b, 0xee, 0xf1,
|
|
||||||
0xca, 0xfe, 0x2c, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8,
|
|
||||||
0x00, 0x01, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8,
|
|
||||||
0x00, 0x02, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x01,
|
|
||||||
}
|
|
||||||
|
|
||||||
testHeader = &ipv6.Header{
|
|
||||||
Version: ipv6.Version,
|
|
||||||
TrafficClass: iana.DiffServAF43,
|
|
||||||
FlowLabel: 0xbeef1,
|
|
||||||
PayloadLen: 0xcafe,
|
|
||||||
NextHeader: iana.ProtocolIPv6Frag,
|
|
||||||
HopLimit: 1,
|
|
||||||
Src: net.ParseIP("2001:db8:1::1"),
|
|
||||||
Dst: net.ParseIP("2001:db8:2::1"),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseHeader(t *testing.T) {
|
|
||||||
h, err := ipv6.ParseHeader(wireHeaderFromKernel[:])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(h, testHeader) {
|
|
||||||
t.Fatalf("got %#v; want %#v", h, testHeader)
|
|
||||||
}
|
|
||||||
s := h.String()
|
|
||||||
if strings.Contains(s, ",") {
|
|
||||||
t.Fatalf("should be space-separated values: %s", s)
|
|
||||||
}
|
|
||||||
}
|
|
96
vendor/golang.org/x/net/ipv6/icmp_test.go
generated
vendored
96
vendor/golang.org/x/net/ipv6/icmp_test.go
generated
vendored
@ -1,96 +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"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
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; want %s", s, tt.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestICMPFilter(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
for _, toggle := range []bool{false, true} {
|
|
||||||
f.SetAll(toggle)
|
|
||||||
for _, typ := range []ipv6.ICMPType{
|
|
||||||
ipv6.ICMPTypeDestinationUnreachable,
|
|
||||||
ipv6.ICMPTypeEchoReply,
|
|
||||||
ipv6.ICMPTypeNeighborSolicitation,
|
|
||||||
ipv6.ICMPTypeDuplicateAddressConfirmation,
|
|
||||||
} {
|
|
||||||
f.Accept(typ)
|
|
||||||
if f.WillBlock(typ) {
|
|
||||||
t.Errorf("ipv6.ICMPFilter.Set(%v, false) failed", typ)
|
|
||||||
}
|
|
||||||
f.Block(typ)
|
|
||||||
if !f.WillBlock(typ) {
|
|
||||||
t.Errorf("ipv6.ICMPFilter.Set(%v, true) failed", typ)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetICMPFilter(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Accept(ipv6.ICMPTypeEchoRequest)
|
|
||||||
f.Accept(ipv6.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)
|
|
||||||
}
|
|
||||||
}
|
|
32
vendor/golang.org/x/net/ipv6/mocktransponder_test.go
generated
vendored
32
vendor/golang.org/x/net/ipv6/mocktransponder_test.go
generated
vendored
@ -1,32 +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 connector(t *testing.T, network, addr string, done chan<- bool) {
|
|
||||||
defer func() { done <- true }()
|
|
||||||
|
|
||||||
c, err := net.Dial(network, addr)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(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.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Close()
|
|
||||||
}
|
|
264
vendor/golang.org/x/net/ipv6/multicast_test.go
generated
vendored
264
vendor/golang.org/x/net/ipv6/multicast_test.go
generated
vendored
@ -1,264 +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"
|
|
||||||
"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/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var packetConnReadWriteMulticastUDPTests = []struct {
|
|
||||||
addr string
|
|
||||||
grp, src *net.UDPAddr
|
|
||||||
}{
|
|
||||||
{"[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
|
|
||||||
|
|
||||||
{"[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if !nettest.SupportsIPv6MulticastDeliveryOnLoopback() {
|
|
||||||
t.Skipf("multicast delivery doesn't work correctly on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
ifi := nettest.RoutedInterface("ip6", 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("udp6", tt.addr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
grp := *tt.grp
|
|
||||||
grp.Port = c.LocalAddr().(*net.UDPAddr).Port
|
|
||||||
p := ipv6.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 MLDv2 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.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 {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
cm.HopLimit = i + 1
|
|
||||||
if n, err := p.WriteTo(wb, &cm, &grp); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if n != len(wb) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
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.ParseIP("ff02::114")}, nil}, // see RFC 4727
|
|
||||||
|
|
||||||
{&net.IPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.IPAddr{IP: net.IPv6loopback}}, // see RFC 5771
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if !nettest.SupportsIPv6MulticastDeliveryOnLoopback() {
|
|
||||||
t.Skipf("multicast delivery doesn't work correctly on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
ifi := nettest.RoutedInterface("ip6", 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("ip6:ipv6-icmp", "::")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, tt.grp.IP)
|
|
||||||
p := ipv6.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 MLDv2 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.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.Accept(ipv6.ICMPTypeEchoReply)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var psh []byte
|
|
||||||
for i, toggle := range []bool{true, false, true} {
|
|
||||||
if toggle {
|
|
||||||
psh = nil
|
|
||||||
if err := p.SetChecksum(true, 2); err != nil {
|
|
||||||
// Solaris never allows to
|
|
||||||
// modify ICMP properties.
|
|
||||||
if runtime.GOOS != "solaris" {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
psh = pshicmp
|
|
||||||
// Some platforms never allow to
|
|
||||||
// disable the kernel checksum
|
|
||||||
// processing.
|
|
||||||
p.SetChecksum(false, -1)
|
|
||||||
}
|
|
||||||
wb, err := (&icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
}).Marshal(psh)
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
cm.HopLimit = i + 1
|
|
||||||
if n, err := p.WriteTo(wb, &cm, 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 {
|
|
||||||
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 {
|
|
||||||
if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
|
|
||||||
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
261
vendor/golang.org/x/net/ipv6/multicastlistener_test.go
generated
vendored
261
vendor/golang.org/x/net/ipv6/multicastlistener_test.go
generated
vendored
@ -1,261 +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"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
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 "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", 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.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.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("ip6", &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 !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, gaddr := range udpMultipleGroupListenerTests {
|
|
||||||
c1, err := net.ListenPacket("udp6", "[ff02::]: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("udp6", net.JoinHostPort("ff02::", port)) // wildcard address with reusable port
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(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.Fatal(err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
if _, ok := nettest.IsMulticastCapable("ip6", &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 !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.Fatal(err)
|
|
||||||
}
|
|
||||||
port := "0"
|
|
||||||
for i, ifi := range ift {
|
|
||||||
ip, ok := nettest.IsMulticastCapable("ip6", &ifi)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c, err := net.ListenPacket("udp6", net.JoinHostPort(ip.String()+"%"+ifi.Name, 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 := ipv6.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 TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::") // wildcard address
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(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.Fatal(err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
if _, ok := nettest.IsMulticastCapable("ip6", &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 TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin", "dragonfly", "openbsd": // platforms that return fe80::1%lo0: bind: can't assign requested address
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
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.Fatal(err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
ip, ok := nettest.IsMulticastCapable("ip6", &ifi)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", ip.String()+"%"+ifi.Name) // unicast address
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
157
vendor/golang.org/x/net/ipv6/multicastsockopt_test.go
generated
vendored
157
vendor/golang.org/x/net/ipv6/multicastsockopt_test.go
generated
vendored
@ -1,157 +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"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var packetConnMulticastSocketOptionTests = []struct {
|
|
||||||
net, proto, addr string
|
|
||||||
grp, src net.Addr
|
|
||||||
}{
|
|
||||||
{"udp6", "", "[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
|
|
||||||
{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff02::115")}, nil}, // see RFC 4727
|
|
||||||
|
|
||||||
{"udp6", "", "[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771
|
|
||||||
{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff30::8000:2")}, &net.IPAddr{IP: net.IPv6loopback}}, // see RFC 5771
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnMulticastSocketOptions(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
ifi := nettest.RoutedInterface("ip6", 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 == "ip6" && !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 := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
if tt.src == nil {
|
|
||||||
testMulticastSocketOptions(t, p, ifi, tt.grp)
|
|
||||||
} else {
|
|
||||||
testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type testIPv6MulticastConn interface {
|
|
||||||
MulticastHopLimit() (int, error)
|
|
||||||
SetMulticastHopLimit(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 testIPv6MulticastConn, ifi *net.Interface, grp net.Addr) {
|
|
||||||
const hoplim = 255
|
|
||||||
if err := c.SetMulticastHopLimit(hoplim); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if v, err := c.MulticastHopLimit(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
} else if v != hoplim {
|
|
||||||
t.Errorf("got %v; want %v", v, hoplim)
|
|
||||||
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 testIPv6MulticastConn, 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 MLDv2 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
|
|
||||||
}
|
|
||||||
}
|
|
242
vendor/golang.org/x/net/ipv6/readwrite_go1_8_test.go
generated
vendored
242
vendor/golang.org/x/net/ipv6/readwrite_go1_8_test.go
generated
vendored
@ -1,242 +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.9
|
|
||||||
|
|
||||||
package ipv6_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/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
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 := []byte{
|
|
||||||
0x69, 0x8b, 0xee, 0xf1, 0xca, 0xfe, 0xff, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
}
|
|
||||||
greh := []byte{0x00, 0x00, 0x86, 0xdd, 0x00, 0x00, 0x00, 0x00}
|
|
||||||
datagram := append(greh, append(iph, payload...)...)
|
|
||||||
bb := make([]byte, 128)
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
HopLimit: 1,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
if ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback); ifi != nil {
|
|
||||||
cm.IfIndex = ifi.Index
|
|
||||||
}
|
|
||||||
|
|
||||||
b.Run("UDP", func(b *testing.B) {
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp6")
|
|
||||||
if err != nil {
|
|
||||||
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
dst := c.LocalAddr()
|
|
||||||
cf := ipv6.FlagHopLimit | ipv6.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("ip6:%d", iana.ProtocolGRE), "::1")
|
|
||||||
if err != nil {
|
|
||||||
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
dst := c.LocalAddr()
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
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 := []byte{
|
|
||||||
0x69, 0x8b, 0xee, 0xf1, 0xca, 0xfe, 0xff, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
}
|
|
||||||
greh := []byte{0x00, 0x00, 0x86, 0xdd, 0x00, 0x00, 0x00, 0x00}
|
|
||||||
datagram := append(greh, append(iph, payload...)...)
|
|
||||||
|
|
||||||
t.Run("UDP", func(t *testing.T) {
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp6")
|
|
||||||
if err != nil {
|
|
||||||
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.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("ip6:%d", iana.ProtocolGRE), "::1")
|
|
||||||
if err != nil {
|
|
||||||
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
t.Run("ToFrom", func(t *testing.T) {
|
|
||||||
testPacketConnConcurrentReadWriteUnicast(t, p, datagram, c.LocalAddr())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testPacketConnConcurrentReadWriteUnicast(t *testing.T, p *ipv6.PacketConn, data []byte, dst net.Addr) {
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
|
|
||||||
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 := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
HopLimit: 1,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
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()
|
|
||||||
}
|
|
373
vendor/golang.org/x/net/ipv6/readwrite_go1_9_test.go
generated
vendored
373
vendor/golang.org/x/net/ipv6/readwrite_go1_9_test.go
generated
vendored
@ -1,373 +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 ipv6_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/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
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 := []byte{
|
|
||||||
0x69, 0x8b, 0xee, 0xf1, 0xca, 0xfe, 0xff, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
}
|
|
||||||
greh := []byte{0x00, 0x00, 0x86, 0xdd, 0x00, 0x00, 0x00, 0x00}
|
|
||||||
datagram := append(greh, append(iph, payload...)...)
|
|
||||||
bb := make([]byte, 128)
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
HopLimit: 1,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
if ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback); ifi != nil {
|
|
||||||
cm.IfIndex = ifi.Index
|
|
||||||
}
|
|
||||||
|
|
||||||
b.Run("UDP", func(b *testing.B) {
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp6")
|
|
||||||
if err != nil {
|
|
||||||
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
dst := c.LocalAddr()
|
|
||||||
cf := ipv6.FlagHopLimit | ipv6.FlagInterface
|
|
||||||
if err := p.SetControlMessage(cf, true); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
wms := []ipv6.Message{
|
|
||||||
{
|
|
||||||
Buffers: [][]byte{payload},
|
|
||||||
Addr: dst,
|
|
||||||
OOB: cm.Marshal(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
rms := []ipv6.Message{
|
|
||||||
{
|
|
||||||
Buffers: [][]byte{bb},
|
|
||||||
OOB: ipv6.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("ip6:%d", iana.ProtocolGRE), "::1")
|
|
||||||
if err != nil {
|
|
||||||
b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
dst := c.LocalAddr()
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
if err := p.SetControlMessage(cf, true); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
wms := []ipv6.Message{
|
|
||||||
{
|
|
||||||
Buffers: [][]byte{datagram},
|
|
||||||
Addr: dst,
|
|
||||||
OOB: cm.Marshal(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
rms := []ipv6.Message{
|
|
||||||
{
|
|
||||||
Buffers: [][]byte{bb},
|
|
||||||
OOB: ipv6.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 := []byte{
|
|
||||||
0x69, 0x8b, 0xee, 0xf1, 0xca, 0xfe, 0xff, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
}
|
|
||||||
greh := []byte{0x00, 0x00, 0x86, 0xdd, 0x00, 0x00, 0x00, 0x00}
|
|
||||||
datagram := append(greh, append(iph, payload...)...)
|
|
||||||
|
|
||||||
t.Run("UDP", func(t *testing.T) {
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp6")
|
|
||||||
if err != nil {
|
|
||||||
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.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("ip6:%d", iana.ProtocolGRE), "::1")
|
|
||||||
if err != nil {
|
|
||||||
t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.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 *ipv6.PacketConn, data []byte, dst net.Addr, batch bool) {
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
|
|
||||||
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 := []ipv6.Message{
|
|
||||||
{
|
|
||||||
Buffers: [][]byte{make([]byte, 128)},
|
|
||||||
OOB: ipv6.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 ipv6.ControlMessage
|
|
||||||
if err := cm.Parse(ms[0].OOB[:ms[0].NN]); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
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 := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
HopLimit: 1,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
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 := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
HopLimit: 1,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
if ifi != nil {
|
|
||||||
cm.IfIndex = ifi.Index
|
|
||||||
}
|
|
||||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ms := []ipv6.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()
|
|
||||||
}
|
|
148
vendor/golang.org/x/net/ipv6/readwrite_test.go
generated
vendored
148
vendor/golang.org/x/net/ipv6/readwrite_test.go
generated
vendored
@ -1,148 +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"
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func BenchmarkReadWriteUnicast(b *testing.B) {
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp6")
|
|
||||||
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("IPv6UDP", func(b *testing.B) {
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
if err := p.SetControlMessage(cf, true); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
HopLimit: 1,
|
|
||||||
}
|
|
||||||
ifi := nettest.RoutedInterface("ip6", 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)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp6")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
dst := c.LocalAddr()
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
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 := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
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()
|
|
||||||
}
|
|
133
vendor/golang.org/x/net/ipv6/sockopt_test.go
generated
vendored
133
vendor/golang.org/x/net/ipv6/sockopt_test.go
generated
vendored
@ -1,133 +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 (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var supportsIPv6 bool = nettest.SupportsIPv6()
|
|
||||||
|
|
||||||
func TestConnInitiatorPathMTU(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(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.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin": // older darwin kernels don't support IPV6_PATHMTU option
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
default:
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu)
|
|
||||||
}
|
|
||||||
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConnResponderPathMTU(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
done := make(chan bool)
|
|
||||||
go connector(t, "tcp6", ln.Addr().String(), done)
|
|
||||||
|
|
||||||
c, err := ln.Accept()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin": // older darwin kernels don't support IPV6_PATHMTU option
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
default:
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu)
|
|
||||||
}
|
|
||||||
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnChecksum(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket(fmt.Sprintf("ip6:%d", iana.ProtocolOSPFIGP), "::") // OSPF for IPv6
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(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.Fatal(err)
|
|
||||||
} else {
|
|
||||||
t.Logf("kernel checksum processing enabled=%v, offset=%v", on, offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
184
vendor/golang.org/x/net/ipv6/unicast_test.go
generated
vendored
184
vendor/golang.org/x/net/ipv6/unicast_test.go
generated
vendored
@ -1,184 +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"
|
|
||||||
"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/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := nettest.NewLocalPacketListener("udp6")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
dst := c.LocalAddr()
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
|
|
||||||
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 {
|
|
||||||
if nettest.ProtocolNotSupported(err) {
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
cm.HopLimit = i + 1
|
|
||||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n, err := p.WriteTo(wb, &cm, 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 !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
dst, err := net.ResolveIPAddr("ip6", "::1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP)
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
|
|
||||||
if ifi != nil {
|
|
||||||
cm.IfIndex = ifi.Index
|
|
||||||
}
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Accept(ipv6.ICMPTypeEchoReply)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var psh []byte
|
|
||||||
for i, toggle := range []bool{true, false, true} {
|
|
||||||
if toggle {
|
|
||||||
psh = nil
|
|
||||||
if err := p.SetChecksum(true, 2); err != nil {
|
|
||||||
// Solaris never allows to modify
|
|
||||||
// ICMP properties.
|
|
||||||
if runtime.GOOS != "solaris" {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
psh = pshicmp
|
|
||||||
// Some platforms never allow to disable the
|
|
||||||
// kernel checksum processing.
|
|
||||||
p.SetChecksum(false, -1)
|
|
||||||
}
|
|
||||||
wb, err := (&icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
}).Marshal(psh)
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
cm.HopLimit = i + 1
|
|
||||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n, err := p.WriteTo(wb, &cm, 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 {
|
|
||||||
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 {
|
|
||||||
if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
|
|
||||||
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
120
vendor/golang.org/x/net/ipv6/unicastsockopt_test.go
generated
vendored
120
vendor/golang.org/x/net/ipv6/unicastsockopt_test.go
generated
vendored
@ -1,120 +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"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestConnUnicastSocketOptions(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := net.Listen("tcp6", "[::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("tcp6", ln.Addr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
testUnicastSocketOptions(t, ipv6.NewConn(c))
|
|
||||||
|
|
||||||
if err := <-errc; err != nil {
|
|
||||||
t.Errorf("server: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var packetConnUnicastSocketOptionTests = []struct {
|
|
||||||
net, proto, addr string
|
|
||||||
}{
|
|
||||||
{"udp6", "", "[::1]:0"},
|
|
||||||
{"ip6", ":ipv6-icmp", "::1"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnUnicastSocketOptions(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "js", "nacl", "plan9", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
m, ok := nettest.SupportsRawIPSocket()
|
|
||||||
for _, tt := range packetConnUnicastSocketOptionTests {
|
|
||||||
if tt.net == "ip6" && !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, 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 := iana.DiffServCS0 | iana.NotECNTransport
|
|
||||||
if err := c.SetTrafficClass(tclass); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin": // older darwin kernels don't support IPV6_TCLASS option
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
goto next
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if v, err := c.TrafficClass(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if v != tclass {
|
|
||||||
t.Fatalf("got %v; want %v", v, tclass)
|
|
||||||
}
|
|
||||||
|
|
||||||
next:
|
|
||||||
hoplim := 255
|
|
||||||
if err := c.SetHopLimit(hoplim); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if v, err := c.HopLimit(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if v != hoplim {
|
|
||||||
t.Fatalf("got %v; want %v", v, hoplim)
|
|
||||||
}
|
|
||||||
}
|
|
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code refers to The Go Authors for copyright purposes.
|
||||||
|
# The master list of authors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code was written by the Go contributors.
|
||||||
|
# The master list of contributors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/CONTRIBUTORS.
|
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
134
vendor/golang.org/x/sys/unix/creds_test.go
generated
vendored
134
vendor/golang.org/x/sys/unix/creds_test.go
generated
vendored
@ -1,134 +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 linux
|
|
||||||
|
|
||||||
package unix_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"go/build"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestSCMCredentials tests the sending and receiving of credentials
|
|
||||||
// (PID, UID, GID) in an ancillary message between two UNIX
|
|
||||||
// sockets. The SO_PASSCRED socket option is enabled on the sending
|
|
||||||
// socket for this to work.
|
|
||||||
func TestSCMCredentials(t *testing.T) {
|
|
||||||
socketTypeTests := []struct {
|
|
||||||
socketType int
|
|
||||||
dataLen int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
unix.SOCK_STREAM,
|
|
||||||
1,
|
|
||||||
}, {
|
|
||||||
unix.SOCK_DGRAM,
|
|
||||||
0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range socketTypeTests {
|
|
||||||
if tt.socketType == unix.SOCK_DGRAM && !atLeast1p10() {
|
|
||||||
t.Log("skipping DGRAM test on pre-1.10")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fds, err := unix.Socketpair(unix.AF_LOCAL, tt.socketType, 0)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Socketpair: %v", err)
|
|
||||||
}
|
|
||||||
defer unix.Close(fds[0])
|
|
||||||
defer unix.Close(fds[1])
|
|
||||||
|
|
||||||
err = unix.SetsockoptInt(fds[0], unix.SOL_SOCKET, unix.SO_PASSCRED, 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("SetsockoptInt: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
srvFile := os.NewFile(uintptr(fds[0]), "server")
|
|
||||||
defer srvFile.Close()
|
|
||||||
srv, err := net.FileConn(srvFile)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("FileConn: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer srv.Close()
|
|
||||||
|
|
||||||
cliFile := os.NewFile(uintptr(fds[1]), "client")
|
|
||||||
defer cliFile.Close()
|
|
||||||
cli, err := net.FileConn(cliFile)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("FileConn: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer cli.Close()
|
|
||||||
|
|
||||||
var ucred unix.Ucred
|
|
||||||
ucred.Pid = int32(os.Getpid())
|
|
||||||
ucred.Uid = uint32(os.Getuid())
|
|
||||||
ucred.Gid = uint32(os.Getgid())
|
|
||||||
oob := unix.UnixCredentials(&ucred)
|
|
||||||
|
|
||||||
// On SOCK_STREAM, this is internally going to send a dummy byte
|
|
||||||
n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriteMsgUnix: %v", err)
|
|
||||||
}
|
|
||||||
if n != 0 {
|
|
||||||
t.Fatalf("WriteMsgUnix n = %d, want 0", n)
|
|
||||||
}
|
|
||||||
if oobn != len(oob) {
|
|
||||||
t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
|
|
||||||
}
|
|
||||||
|
|
||||||
oob2 := make([]byte, 10*len(oob))
|
|
||||||
n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ReadMsgUnix: %v", err)
|
|
||||||
}
|
|
||||||
if flags != 0 {
|
|
||||||
t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
|
|
||||||
}
|
|
||||||
if n != tt.dataLen {
|
|
||||||
t.Fatalf("ReadMsgUnix n = %d, want %d", n, tt.dataLen)
|
|
||||||
}
|
|
||||||
if oobn2 != oobn {
|
|
||||||
// without SO_PASSCRED set on the socket, ReadMsgUnix will
|
|
||||||
// return zero oob bytes
|
|
||||||
t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
|
|
||||||
}
|
|
||||||
oob2 = oob2[:oobn2]
|
|
||||||
if !bytes.Equal(oob, oob2) {
|
|
||||||
t.Fatal("ReadMsgUnix oob bytes don't match")
|
|
||||||
}
|
|
||||||
|
|
||||||
scm, err := unix.ParseSocketControlMessage(oob2)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ParseSocketControlMessage: %v", err)
|
|
||||||
}
|
|
||||||
newUcred, err := unix.ParseUnixCredentials(&scm[0])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ParseUnixCredentials: %v", err)
|
|
||||||
}
|
|
||||||
if *newUcred != ucred {
|
|
||||||
t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// atLeast1p10 reports whether we are running on Go 1.10 or later.
|
|
||||||
func atLeast1p10() bool {
|
|
||||||
for _, ver := range build.Default.ReleaseTags {
|
|
||||||
if ver == "go1.10" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
56
vendor/golang.org/x/sys/unix/dev_linux_test.go
generated
vendored
56
vendor/golang.org/x/sys/unix/dev_linux_test.go
generated
vendored
@ -1,56 +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.7
|
|
||||||
|
|
||||||
package unix_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDevices(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
path string
|
|
||||||
major uint32
|
|
||||||
minor uint32
|
|
||||||
}{
|
|
||||||
// well known major/minor numbers according to
|
|
||||||
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/devices.txt
|
|
||||||
{"/dev/null", 1, 3},
|
|
||||||
{"/dev/zero", 1, 5},
|
|
||||||
{"/dev/random", 1, 8},
|
|
||||||
{"/dev/full", 1, 7},
|
|
||||||
{"/dev/urandom", 1, 9},
|
|
||||||
{"/dev/tty", 5, 0},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
|
|
||||||
var stat unix.Stat_t
|
|
||||||
err := unix.Stat(tc.path, &stat)
|
|
||||||
if err != nil {
|
|
||||||
if err == unix.EACCES {
|
|
||||||
t.Skip("no permission to stat device, skipping test")
|
|
||||||
}
|
|
||||||
t.Errorf("failed to stat device: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
dev := uint64(stat.Rdev)
|
|
||||||
if unix.Major(dev) != tc.major {
|
|
||||||
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
|
|
||||||
}
|
|
||||||
if unix.Minor(dev) != tc.minor {
|
|
||||||
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
|
|
||||||
}
|
|
||||||
if unix.Mkdev(tc.major, tc.minor) != dev {
|
|
||||||
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
19
vendor/golang.org/x/sys/unix/example_test.go
generated
vendored
19
vendor/golang.org/x/sys/unix/example_test.go
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
// Copyright 2018 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 dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package unix_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleExec() {
|
|
||||||
err := unix.Exec("/bin/ls", []string{"ls", "-al"}, os.Environ())
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
9
vendor/golang.org/x/sys/unix/export_test.go
generated
vendored
9
vendor/golang.org/x/sys/unix/export_test.go
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
// Copyright 2015 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 dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
var Itoa = itoa
|
|
35
vendor/golang.org/x/sys/unix/mmap_unix_test.go
generated
vendored
35
vendor/golang.org/x/sys/unix/mmap_unix_test.go
generated
vendored
@ -1,35 +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.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package unix_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMmap(t *testing.T) {
|
|
||||||
b, err := unix.Mmap(-1, 0, unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Mmap: %v", err)
|
|
||||||
}
|
|
||||||
if err := unix.Mprotect(b, unix.PROT_READ|unix.PROT_WRITE); err != nil {
|
|
||||||
t.Fatalf("Mprotect: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
b[0] = 42
|
|
||||||
|
|
||||||
if err := unix.Msync(b, unix.MS_SYNC); err != nil {
|
|
||||||
t.Fatalf("Msync: %v", err)
|
|
||||||
}
|
|
||||||
if err := unix.Madvise(b, unix.MADV_DONTNEED); err != nil {
|
|
||||||
t.Fatalf("Madvise: %v", err)
|
|
||||||
}
|
|
||||||
if err := unix.Munmap(b); err != nil {
|
|
||||||
t.Fatalf("Munmap: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
113
vendor/golang.org/x/sys/unix/openbsd_test.go
generated
vendored
113
vendor/golang.org/x/sys/unix/openbsd_test.go
generated
vendored
@ -1,113 +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.
|
|
||||||
|
|
||||||
// +build openbsd
|
|
||||||
|
|
||||||
// This, on the face of it, bizarre testing mechanism is necessary because
|
|
||||||
// the only reliable way to gauge whether or not a pledge(2) call has succeeded
|
|
||||||
// is that the program has been killed as a result of breaking its pledge.
|
|
||||||
|
|
||||||
package unix_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
type testProc struct {
|
|
||||||
fn func() // should always exit instead of returning
|
|
||||||
cleanup func() error // for instance, delete coredumps from testing pledge
|
|
||||||
success bool // whether zero-exit means success or failure
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
testProcs = map[string]testProc{}
|
|
||||||
procName = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
optName = "sys-unix-internal-procname"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.StringVar(&procName, optName, "", "internal use only")
|
|
||||||
}
|
|
||||||
|
|
||||||
// testCmd generates a proper command that, when executed, runs the test
|
|
||||||
// corresponding to the given key.
|
|
||||||
func testCmd(procName string) (*exec.Cmd, error) {
|
|
||||||
exe, err := filepath.Abs(os.Args[0])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cmd := exec.Command(exe, "-"+optName+"="+procName)
|
|
||||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
|
||||||
return cmd, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
|
|
||||||
// a testProc with a key.
|
|
||||||
func ExitsCorrectly(procName string, t *testing.T) {
|
|
||||||
s := testProcs[procName]
|
|
||||||
c, err := testCmd(procName)
|
|
||||||
defer func() {
|
|
||||||
if s.cleanup() != nil {
|
|
||||||
t.Fatalf("Failed to run cleanup for %s", procName)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to construct command for %s", procName)
|
|
||||||
}
|
|
||||||
if (c.Run() == nil) != s.success {
|
|
||||||
result := "succeed"
|
|
||||||
if !s.success {
|
|
||||||
result = "fail"
|
|
||||||
}
|
|
||||||
t.Fatalf("Process did not %s when it was supposed to", result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
|
||||||
flag.Parse()
|
|
||||||
if procName != "" {
|
|
||||||
testProcs[procName].fn()
|
|
||||||
}
|
|
||||||
os.Exit(m.Run())
|
|
||||||
}
|
|
||||||
|
|
||||||
// For example, add a test for pledge.
|
|
||||||
func init() {
|
|
||||||
testProcs["pledge"] = testProc{
|
|
||||||
func() {
|
|
||||||
fmt.Println(unix.Pledge("", nil))
|
|
||||||
os.Exit(0)
|
|
||||||
},
|
|
||||||
func() error {
|
|
||||||
files, err := ioutil.ReadDir(".")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, file := range files {
|
|
||||||
if filepath.Ext(file.Name()) == ".core" {
|
|
||||||
if err := os.Remove(file.Name()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPledge(t *testing.T) {
|
|
||||||
ExitsCorrectly("pledge", t)
|
|
||||||
}
|
|
93
vendor/golang.org/x/sys/unix/syscall_bsd_test.go
generated
vendored
93
vendor/golang.org/x/sys/unix/syscall_bsd_test.go
generated
vendored
@ -1,93 +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.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd openbsd
|
|
||||||
|
|
||||||
package unix_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
const MNT_WAIT = 1
|
|
||||||
const MNT_NOWAIT = 2
|
|
||||||
|
|
||||||
func TestGetfsstat(t *testing.T) {
|
|
||||||
const flags = MNT_NOWAIT // see golang.org/issue/16937
|
|
||||||
n, err := unix.Getfsstat(nil, flags)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
data := make([]unix.Statfs_t, n)
|
|
||||||
n2, err := unix.Getfsstat(data, flags)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n != n2 {
|
|
||||||
t.Errorf("Getfsstat(nil) = %d, but subsequent Getfsstat(slice) = %d", n, n2)
|
|
||||||
}
|
|
||||||
for i, stat := range data {
|
|
||||||
if stat == (unix.Statfs_t{}) {
|
|
||||||
t.Errorf("index %v is an empty Statfs_t struct", i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if t.Failed() {
|
|
||||||
for i, stat := range data[:n2] {
|
|
||||||
t.Logf("data[%v] = %+v", i, stat)
|
|
||||||
}
|
|
||||||
mount, err := exec.Command("mount").CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
t.Logf("mount: %v\n%s", err, mount)
|
|
||||||
} else {
|
|
||||||
t.Logf("mount: %s", mount)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSelect(t *testing.T) {
|
|
||||||
err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Select: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dur := 250 * time.Millisecond
|
|
||||||
tv := unix.NsecToTimeval(int64(dur))
|
|
||||||
start := time.Now()
|
|
||||||
err = unix.Select(0, nil, nil, nil, &tv)
|
|
||||||
took := time.Since(start)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Select: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// On some BSDs the actual timeout might also be slightly less than the requested.
|
|
||||||
// Add an acceptable margin to avoid flaky tests.
|
|
||||||
if took < dur*2/3 {
|
|
||||||
t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSysctlRaw(t *testing.T) {
|
|
||||||
if runtime.GOOS == "openbsd" {
|
|
||||||
t.Skip("kern.proc.pid does not exist on OpenBSD")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := unix.SysctlRaw("kern.proc.pid", unix.Getpid())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSysctlUint32(t *testing.T) {
|
|
||||||
maxproc, err := unix.SysctlUint32("kern.maxproc")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Logf("kern.maxproc: %v", maxproc)
|
|
||||||
}
|
|
19
vendor/golang.org/x/sys/unix/syscall_darwin_test.go
generated
vendored
19
vendor/golang.org/x/sys/unix/syscall_darwin_test.go
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
// Copyright 2018 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 unix_test
|
|
||||||
|
|
||||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
|
||||||
// On Darwin, each entry is a NULL-terminated string.
|
|
||||||
func stringsFromByteSlice(buf []byte) []string {
|
|
||||||
var result []string
|
|
||||||
off := 0
|
|
||||||
for i, b := range buf {
|
|
||||||
if b == 0 {
|
|
||||||
result = append(result, string(buf[off:i]))
|
|
||||||
off = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
312
vendor/golang.org/x/sys/unix/syscall_freebsd_test.go
generated
vendored
312
vendor/golang.org/x/sys/unix/syscall_freebsd_test.go
generated
vendored
@ -1,312 +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.
|
|
||||||
|
|
||||||
// +build freebsd
|
|
||||||
|
|
||||||
package unix_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSysctlUint64(t *testing.T) {
|
|
||||||
_, err := unix.SysctlUint64("vm.swap_total")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Infrastructure for launching tests in subprocesses stolen from openbsd_test.go - refactor?
|
|
||||||
// testCmd generates a proper command that, when executed, runs the test
|
|
||||||
// corresponding to the given key.
|
|
||||||
|
|
||||||
type testProc struct {
|
|
||||||
fn func() // should always exit instead of returning
|
|
||||||
arg func(t *testing.T) string // generate argument for test
|
|
||||||
cleanup func(arg string) error // for instance, delete coredumps from testing pledge
|
|
||||||
success bool // whether zero-exit means success or failure
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
testProcs = map[string]testProc{}
|
|
||||||
procName = ""
|
|
||||||
procArg = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
optName = "sys-unix-internal-procname"
|
|
||||||
optArg = "sys-unix-internal-arg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.StringVar(&procName, optName, "", "internal use only")
|
|
||||||
flag.StringVar(&procArg, optArg, "", "internal use only")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func testCmd(procName string, procArg string) (*exec.Cmd, error) {
|
|
||||||
exe, err := filepath.Abs(os.Args[0])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cmd := exec.Command(exe, "-"+optName+"="+procName, "-"+optArg+"="+procArg)
|
|
||||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
|
||||||
return cmd, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
|
|
||||||
// a testProc with a key.
|
|
||||||
func ExitsCorrectly(t *testing.T, procName string) {
|
|
||||||
s := testProcs[procName]
|
|
||||||
arg := "-"
|
|
||||||
if s.arg != nil {
|
|
||||||
arg = s.arg(t)
|
|
||||||
}
|
|
||||||
c, err := testCmd(procName, arg)
|
|
||||||
defer func(arg string) {
|
|
||||||
if err := s.cleanup(arg); err != nil {
|
|
||||||
t.Fatalf("Failed to run cleanup for %s %s %#v", procName, err, err)
|
|
||||||
}
|
|
||||||
}(arg)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to construct command for %s", procName)
|
|
||||||
}
|
|
||||||
if (c.Run() == nil) != s.success {
|
|
||||||
result := "succeed"
|
|
||||||
if !s.success {
|
|
||||||
result = "fail"
|
|
||||||
}
|
|
||||||
t.Fatalf("Process did not %s when it was supposed to", result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
|
||||||
flag.Parse()
|
|
||||||
if procName != "" {
|
|
||||||
t := testProcs[procName]
|
|
||||||
t.fn()
|
|
||||||
os.Stderr.WriteString("test function did not exit\n")
|
|
||||||
if t.success {
|
|
||||||
os.Exit(1)
|
|
||||||
} else {
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os.Exit(m.Run())
|
|
||||||
}
|
|
||||||
|
|
||||||
// end of infrastructure
|
|
||||||
|
|
||||||
const testfile = "gocapmodetest"
|
|
||||||
const testfile2 = testfile + "2"
|
|
||||||
|
|
||||||
func CapEnterTest() {
|
|
||||||
_, err := os.OpenFile(path.Join(procArg, testfile), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("OpenFile: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.CapEnter()
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("CapEnter: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = os.OpenFile(path.Join(procArg, testfile2), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
|
||||||
if err == nil {
|
|
||||||
panic("OpenFile works!")
|
|
||||||
}
|
|
||||||
if err.(*os.PathError).Err != unix.ECAPMODE {
|
|
||||||
panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeTempDir(t *testing.T) string {
|
|
||||||
d, err := ioutil.TempDir("", "go_openat_test")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("TempDir failed: %s", err)
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeTempDir(arg string) error {
|
|
||||||
err := os.RemoveAll(arg)
|
|
||||||
if err != nil && err.(*os.PathError).Err == unix.ENOENT {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testProcs["cap_enter"] = testProc{
|
|
||||||
CapEnterTest,
|
|
||||||
makeTempDir,
|
|
||||||
removeTempDir,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCapEnter(t *testing.T) {
|
|
||||||
if runtime.GOARCH != "amd64" {
|
|
||||||
t.Skipf("skipping test on %s", runtime.GOARCH)
|
|
||||||
}
|
|
||||||
ExitsCorrectly(t, "cap_enter")
|
|
||||||
}
|
|
||||||
|
|
||||||
func OpenatTest() {
|
|
||||||
f, err := os.Open(procArg)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.CapEnter()
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("CapEnter: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
fxx, err := unix.Openat(int(f.Fd()), "xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
unix.Close(fxx)
|
|
||||||
|
|
||||||
// The right to open BASE/xx is not ambient
|
|
||||||
_, err = os.OpenFile(procArg+"/xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
|
||||||
if err == nil {
|
|
||||||
panic("OpenFile succeeded")
|
|
||||||
}
|
|
||||||
if err.(*os.PathError).Err != unix.ECAPMODE {
|
|
||||||
panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't make a new directory either
|
|
||||||
err = os.Mkdir(procArg+"2", 0777)
|
|
||||||
if err == nil {
|
|
||||||
panic("MKdir succeeded")
|
|
||||||
}
|
|
||||||
if err.(*os.PathError).Err != unix.ECAPMODE {
|
|
||||||
panic(fmt.Sprintf("Mkdir failed wrong: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove all caps except read and lookup.
|
|
||||||
r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_LOOKUP})
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("CapRightsInit failed: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
err = unix.CapRightsLimit(f.Fd(), r)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("CapRightsLimit failed: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check we can get the rights back again
|
|
||||||
r, err = unix.CapRightsGet(f.Fd())
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("CapRightsGet failed: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP})
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
if !b {
|
|
||||||
panic(fmt.Sprintf("Unexpected rights"))
|
|
||||||
}
|
|
||||||
b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP, unix.CAP_WRITE})
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
if b {
|
|
||||||
panic(fmt.Sprintf("Unexpected rights (2)"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can no longer create a file
|
|
||||||
_, err = unix.Openat(int(f.Fd()), "xx2", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
|
||||||
if err == nil {
|
|
||||||
panic("Openat succeeded")
|
|
||||||
}
|
|
||||||
if err != unix.ENOTCAPABLE {
|
|
||||||
panic(fmt.Sprintf("OpenFileAt failed wrong: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// But can read an existing one
|
|
||||||
_, err = unix.Openat(int(f.Fd()), "xx", os.O_RDONLY, 0666)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("Openat failed: %s %#v", err, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testProcs["openat"] = testProc{
|
|
||||||
OpenatTest,
|
|
||||||
makeTempDir,
|
|
||||||
removeTempDir,
|
|
||||||
true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOpenat(t *testing.T) {
|
|
||||||
if runtime.GOARCH != "amd64" {
|
|
||||||
t.Skipf("skipping test on %s", runtime.GOARCH)
|
|
||||||
}
|
|
||||||
ExitsCorrectly(t, "openat")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCapRightsSetAndClear(t *testing.T) {
|
|
||||||
r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CapRightsInit failed: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.CapRightsSet(r, []uint64{unix.CAP_EVENT, unix.CAP_LISTEN})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CapRightsSet failed: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT, unix.CAP_EVENT, unix.CAP_LISTEN})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CapRightsIsSet failed: %s", err)
|
|
||||||
}
|
|
||||||
if !b {
|
|
||||||
t.Fatalf("Wrong rights set")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.CapRightsClear(r, []uint64{unix.CAP_READ, unix.CAP_PDWAIT})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CapRightsClear failed: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_WRITE, unix.CAP_EVENT, unix.CAP_LISTEN})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CapRightsIsSet failed: %s", err)
|
|
||||||
}
|
|
||||||
if !b {
|
|
||||||
t.Fatalf("Wrong rights set")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
|
||||||
// On FreeBSD, each entry consists of a single byte containing the length
|
|
||||||
// of the attribute name, followed by the attribute name.
|
|
||||||
// The name is _not_ NULL-terminated.
|
|
||||||
func stringsFromByteSlice(buf []byte) []string {
|
|
||||||
var result []string
|
|
||||||
i := 0
|
|
||||||
for i < len(buf) {
|
|
||||||
next := i + 1 + int(buf[i])
|
|
||||||
result = append(result, string(buf[i+1:next]))
|
|
||||||
i = next
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
421
vendor/golang.org/x/sys/unix/syscall_linux_test.go
generated
vendored
421
vendor/golang.org/x/sys/unix/syscall_linux_test.go
generated
vendored
@ -1,421 +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.
|
|
||||||
|
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package unix_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"runtime/debug"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestIoctlGetInt(t *testing.T) {
|
|
||||||
f, err := os.Open("/dev/random")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to open device: %v", err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
v, err := unix.IoctlGetInt(int(f.Fd()), unix.RNDGETENTCNT)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to perform ioctl: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Logf("%d bits of entropy available", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPpoll(t *testing.T) {
|
|
||||||
if runtime.GOOS == "android" {
|
|
||||||
t.Skip("mkfifo syscall is not available on android, skipping test")
|
|
||||||
}
|
|
||||||
|
|
||||||
f, cleanup := mktmpfifo(t)
|
|
||||||
defer cleanup()
|
|
||||||
|
|
||||||
const timeout = 100 * time.Millisecond
|
|
||||||
|
|
||||||
ok := make(chan bool, 1)
|
|
||||||
go func() {
|
|
||||||
select {
|
|
||||||
case <-time.After(10 * timeout):
|
|
||||||
t.Errorf("Ppoll: failed to timeout after %d", 10*timeout)
|
|
||||||
case <-ok:
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
|
|
||||||
timeoutTs := unix.NsecToTimespec(int64(timeout))
|
|
||||||
n, err := unix.Ppoll(fds, &timeoutTs, nil)
|
|
||||||
ok <- true
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Ppoll: unexpected error: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if n != 0 {
|
|
||||||
t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTime(t *testing.T) {
|
|
||||||
var ut unix.Time_t
|
|
||||||
ut2, err := unix.Time(&ut)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Time: %v", err)
|
|
||||||
}
|
|
||||||
if ut != ut2 {
|
|
||||||
t.Errorf("Time: return value %v should be equal to argument %v", ut2, ut)
|
|
||||||
}
|
|
||||||
|
|
||||||
var now time.Time
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
ut, err = unix.Time(nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Time: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
now = time.Now()
|
|
||||||
|
|
||||||
if int64(ut) == now.Unix() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Errorf("Time: return value %v should be nearly equal to time.Now().Unix() %v", ut, now.Unix())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUtime(t *testing.T) {
|
|
||||||
defer chtmpdir(t)()
|
|
||||||
|
|
||||||
touch(t, "file1")
|
|
||||||
|
|
||||||
buf := &unix.Utimbuf{
|
|
||||||
Modtime: 12345,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := unix.Utime("file1", buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Utime: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fi, err := os.Stat("file1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if fi.ModTime().Unix() != 12345 {
|
|
||||||
t.Errorf("Utime: failed to change modtime: expected %v, got %v", 12345, fi.ModTime().Unix())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUtimesNanoAt(t *testing.T) {
|
|
||||||
defer chtmpdir(t)()
|
|
||||||
|
|
||||||
symlink := "symlink1"
|
|
||||||
os.Remove(symlink)
|
|
||||||
err := os.Symlink("nonexisting", symlink)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ts := []unix.Timespec{
|
|
||||||
{Sec: 1111, Nsec: 2222},
|
|
||||||
{Sec: 3333, Nsec: 4444},
|
|
||||||
}
|
|
||||||
err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("UtimesNanoAt: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var st unix.Stat_t
|
|
||||||
err = unix.Lstat(symlink, &st)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Lstat: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only check Mtim, Atim might not be supported by the underlying filesystem
|
|
||||||
expected := ts[1]
|
|
||||||
if st.Mtim.Nsec == 0 {
|
|
||||||
// Some filesystems only support 1-second time stamp resolution
|
|
||||||
// and will always set Nsec to 0.
|
|
||||||
expected.Nsec = 0
|
|
||||||
}
|
|
||||||
if st.Mtim != expected {
|
|
||||||
t.Errorf("UtimesNanoAt: wrong mtime: expected %v, got %v", expected, st.Mtim)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRlimitAs(t *testing.T) {
|
|
||||||
// disable GC during to avoid flaky test
|
|
||||||
defer debug.SetGCPercent(debug.SetGCPercent(-1))
|
|
||||||
|
|
||||||
var rlim unix.Rlimit
|
|
||||||
err := unix.Getrlimit(unix.RLIMIT_AS, &rlim)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Getrlimit: %v", err)
|
|
||||||
}
|
|
||||||
var zero unix.Rlimit
|
|
||||||
if zero == rlim {
|
|
||||||
t.Fatalf("Getrlimit: got zero value %#v", rlim)
|
|
||||||
}
|
|
||||||
set := rlim
|
|
||||||
set.Cur = uint64(unix.Getpagesize())
|
|
||||||
err = unix.Setrlimit(unix.RLIMIT_AS, &set)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Setrlimit: set failed: %#v %v", set, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RLIMIT_AS was set to the page size, so mmap()'ing twice the page size
|
|
||||||
// should fail. See 'man 2 getrlimit'.
|
|
||||||
_, err = unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("Mmap: unexpectedly suceeded after setting RLIMIT_AS")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.Setrlimit(unix.RLIMIT_AS, &rlim)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Setrlimit: restore failed: %#v %v", rlim, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Mmap: %v", err)
|
|
||||||
}
|
|
||||||
err = unix.Munmap(b)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Munmap: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSelect(t *testing.T) {
|
|
||||||
_, err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Select: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dur := 150 * time.Millisecond
|
|
||||||
tv := unix.NsecToTimeval(int64(dur))
|
|
||||||
start := time.Now()
|
|
||||||
_, err = unix.Select(0, nil, nil, nil, &tv)
|
|
||||||
took := time.Since(start)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Select: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if took < dur {
|
|
||||||
t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPselect(t *testing.T) {
|
|
||||||
_, err := unix.Pselect(0, nil, nil, nil, &unix.Timespec{Sec: 0, Nsec: 0}, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Pselect: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dur := 2500 * time.Microsecond
|
|
||||||
ts := unix.NsecToTimespec(int64(dur))
|
|
||||||
start := time.Now()
|
|
||||||
_, err = unix.Pselect(0, nil, nil, nil, &ts, nil)
|
|
||||||
took := time.Since(start)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Pselect: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if took < dur {
|
|
||||||
t.Errorf("Pselect: timeout should have been at least %v, got %v", dur, took)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSchedSetaffinity(t *testing.T) {
|
|
||||||
runtime.LockOSThread()
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
|
|
||||||
var oldMask unix.CPUSet
|
|
||||||
err := unix.SchedGetaffinity(0, &oldMask)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("SchedGetaffinity: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var newMask unix.CPUSet
|
|
||||||
newMask.Zero()
|
|
||||||
if newMask.Count() != 0 {
|
|
||||||
t.Errorf("CpuZero: didn't zero CPU set: %v", newMask)
|
|
||||||
}
|
|
||||||
cpu := 1
|
|
||||||
newMask.Set(cpu)
|
|
||||||
if newMask.Count() != 1 || !newMask.IsSet(cpu) {
|
|
||||||
t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask)
|
|
||||||
}
|
|
||||||
cpu = 5
|
|
||||||
newMask.Set(cpu)
|
|
||||||
if newMask.Count() != 2 || !newMask.IsSet(cpu) {
|
|
||||||
t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask)
|
|
||||||
}
|
|
||||||
newMask.Clear(cpu)
|
|
||||||
if newMask.Count() != 1 || newMask.IsSet(cpu) {
|
|
||||||
t.Errorf("CpuClr: didn't clear CPU %d in set: %v", cpu, newMask)
|
|
||||||
}
|
|
||||||
|
|
||||||
if runtime.NumCPU() < 2 {
|
|
||||||
t.Skip("skipping setaffinity tests on single CPU system")
|
|
||||||
}
|
|
||||||
if runtime.GOOS == "android" {
|
|
||||||
t.Skip("skipping setaffinity tests on android")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.SchedSetaffinity(0, &newMask)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("SchedSetaffinity: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var gotMask unix.CPUSet
|
|
||||||
err = unix.SchedGetaffinity(0, &gotMask)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("SchedGetaffinity: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if gotMask != newMask {
|
|
||||||
t.Errorf("SchedSetaffinity: returned affinity mask does not match set affinity mask")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore old mask so it doesn't affect successive tests
|
|
||||||
err = unix.SchedSetaffinity(0, &oldMask)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("SchedSetaffinity: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStatx(t *testing.T) {
|
|
||||||
var stx unix.Statx_t
|
|
||||||
err := unix.Statx(unix.AT_FDCWD, ".", 0, 0, &stx)
|
|
||||||
if err == unix.ENOSYS || err == unix.EPERM {
|
|
||||||
t.Skip("statx syscall is not available, skipping test")
|
|
||||||
} else if err != nil {
|
|
||||||
t.Fatalf("Statx: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer chtmpdir(t)()
|
|
||||||
touch(t, "file1")
|
|
||||||
|
|
||||||
var st unix.Stat_t
|
|
||||||
err = unix.Stat("file1", &st)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Stat: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
flags := unix.AT_STATX_SYNC_AS_STAT
|
|
||||||
err = unix.Statx(unix.AT_FDCWD, "file1", flags, unix.STATX_ALL, &stx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Statx: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if uint32(stx.Mode) != st.Mode {
|
|
||||||
t.Errorf("Statx: returned stat mode does not match Stat")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctime := unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)}
|
|
||||||
mtime := unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)}
|
|
||||||
|
|
||||||
if stx.Ctime != ctime {
|
|
||||||
t.Errorf("Statx: returned stat ctime does not match Stat")
|
|
||||||
}
|
|
||||||
if stx.Mtime != mtime {
|
|
||||||
t.Errorf("Statx: returned stat mtime does not match Stat")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.Symlink("file1", "symlink1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.Lstat("symlink1", &st)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Lstat: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.Statx(unix.AT_FDCWD, "symlink1", flags, unix.STATX_BASIC_STATS, &stx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Statx: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// follow symlink, expect a regulat file
|
|
||||||
if stx.Mode&unix.S_IFREG == 0 {
|
|
||||||
t.Errorf("Statx: didn't follow symlink")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.Statx(unix.AT_FDCWD, "symlink1", flags|unix.AT_SYMLINK_NOFOLLOW, unix.STATX_ALL, &stx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Statx: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// follow symlink, expect a symlink
|
|
||||||
if stx.Mode&unix.S_IFLNK == 0 {
|
|
||||||
t.Errorf("Statx: unexpectedly followed symlink")
|
|
||||||
}
|
|
||||||
if uint32(stx.Mode) != st.Mode {
|
|
||||||
t.Errorf("Statx: returned stat mode does not match Lstat")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctime = unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)}
|
|
||||||
mtime = unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)}
|
|
||||||
|
|
||||||
if stx.Ctime != ctime {
|
|
||||||
t.Errorf("Statx: returned stat ctime does not match Lstat")
|
|
||||||
}
|
|
||||||
if stx.Mtime != mtime {
|
|
||||||
t.Errorf("Statx: returned stat mtime does not match Lstat")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
|
||||||
// On Linux, each entry is a NULL-terminated string.
|
|
||||||
func stringsFromByteSlice(buf []byte) []string {
|
|
||||||
var result []string
|
|
||||||
off := 0
|
|
||||||
for i, b := range buf {
|
|
||||||
if b == 0 {
|
|
||||||
result = append(result, string(buf[off:i]))
|
|
||||||
off = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFaccessat(t *testing.T) {
|
|
||||||
defer chtmpdir(t)()
|
|
||||||
touch(t, "file1")
|
|
||||||
|
|
||||||
err := unix.Faccessat(unix.AT_FDCWD, "file1", unix.O_RDONLY, 0)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Faccessat: unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.O_RDONLY, 2)
|
|
||||||
if err != unix.EINVAL {
|
|
||||||
t.Errorf("Faccessat: unexpected error: %v, want EINVAL", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.O_RDONLY, unix.AT_EACCESS)
|
|
||||||
if err != unix.EOPNOTSUPP {
|
|
||||||
t.Errorf("Faccessat: unexpected error: %v, want EOPNOTSUPP", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.Symlink("file1", "symlink1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unix.Faccessat(unix.AT_FDCWD, "symlink1", unix.O_RDONLY, unix.AT_SYMLINK_NOFOLLOW)
|
|
||||||
if err != unix.EOPNOTSUPP {
|
|
||||||
t.Errorf("Faccessat: unexpected error: %v, want EOPNOTSUPP", err)
|
|
||||||
}
|
|
||||||
}
|
|
55
vendor/golang.org/x/sys/unix/syscall_solaris_test.go
generated
vendored
55
vendor/golang.org/x/sys/unix/syscall_solaris_test.go
generated
vendored
@ -1,55 +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 solaris
|
|
||||||
|
|
||||||
package unix_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSelect(t *testing.T) {
|
|
||||||
err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Select: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dur := 150 * time.Millisecond
|
|
||||||
tv := unix.NsecToTimeval(int64(dur))
|
|
||||||
start := time.Now()
|
|
||||||
err = unix.Select(0, nil, nil, nil, &tv)
|
|
||||||
took := time.Since(start)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Select: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if took < dur {
|
|
||||||
t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStatvfs(t *testing.T) {
|
|
||||||
if err := unix.Statvfs("", nil); err == nil {
|
|
||||||
t.Fatal(`Statvfs("") expected failure`)
|
|
||||||
}
|
|
||||||
|
|
||||||
statvfs := unix.Statvfs_t{}
|
|
||||||
if err := unix.Statvfs("/", &statvfs); err != nil {
|
|
||||||
t.Errorf(`Statvfs("/") failed: %v`, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.Failed() {
|
|
||||||
mount, err := exec.Command("mount").CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
t.Logf("mount: %v\n%s", err, mount)
|
|
||||||
} else {
|
|
||||||
t.Logf("mount: %s", mount)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user