lvm: setupLV wait device + go mod
This commit is contained in:
		| @ -144,6 +144,16 @@ func setupLV(volume config.VolumeDef) { | ||||
| 		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) | ||||
|  | ||||
| 	switch volume.FS { | ||||
| @ -153,5 +163,5 @@ func setupLV(volume config.VolumeDef) { | ||||
| 		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 ( | ||||
| 	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 | ||||
| 	gopkg.in/yaml.v2 v2.2.1 | ||||
| 	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
		Reference in New Issue
	
	Block a user