bettercap/vendor/github.com/google/gopacket/tcpassembly/assembly_test.go
2018-03-23 15:25:11 +01:00

562 lines
10 KiB
Go

// Copyright 2012 Google, Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.
package tcpassembly
import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"net"
"reflect"
"testing"
"time"
)
var netFlow gopacket.Flow
func init() {
netFlow, _ = gopacket.FlowFromEndpoints(
layers.NewIPEndpoint(net.IP{1, 2, 3, 4}),
layers.NewIPEndpoint(net.IP{5, 6, 7, 8}))
}
type testSequence struct {
in layers.TCP
want []Reassembly
}
type testFactory struct {
reassembly []Reassembly
}
func (t *testFactory) New(a, b gopacket.Flow) Stream {
return t
}
func (t *testFactory) Reassembled(r []Reassembly) {
t.reassembly = r
for i := 0; i < len(r); i++ {
t.reassembly[i].Seen = time.Time{}
}
}
func (t *testFactory) ReassemblyComplete() {
}
func test(t *testing.T, s []testSequence) {
fact := &testFactory{}
p := NewStreamPool(fact)
a := NewAssembler(p)
a.MaxBufferedPagesPerConnection = 4
for i, test := range s {
fact.reassembly = []Reassembly{}
a.Assemble(netFlow, &test.in)
if !reflect.DeepEqual(fact.reassembly, test.want) {
t.Fatalf("test %v:\nwant: %v\n got: %v\n", i, test.want, fact.reassembly)
}
}
}
func TestReorder(t *testing.T) {
test(t, []testSequence{
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1001,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1004,
BaseLayer: layers.BaseLayer{Payload: []byte{2, 2, 3}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1010,
BaseLayer: layers.BaseLayer{Payload: []byte{4, 2, 3}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1007,
BaseLayer: layers.BaseLayer{Payload: []byte{3, 2, 3}},
},
want: []Reassembly{
Reassembly{
Skip: -1,
Bytes: []byte{1, 2, 3},
},
Reassembly{
Bytes: []byte{2, 2, 3},
},
Reassembly{
Bytes: []byte{3, 2, 3},
},
Reassembly{
Bytes: []byte{4, 2, 3},
},
},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1016,
BaseLayer: layers.BaseLayer{Payload: []byte{2, 2, 3}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1019,
BaseLayer: layers.BaseLayer{Payload: []byte{3, 2, 3}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1013,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}},
},
want: []Reassembly{
Reassembly{
Bytes: []byte{1, 2, 3},
},
Reassembly{
Bytes: []byte{2, 2, 3},
},
Reassembly{
Bytes: []byte{3, 2, 3},
},
},
},
})
}
func TestMaxPerSkip(t *testing.T) {
test(t, []testSequence{
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1000,
SYN: true,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}},
},
want: []Reassembly{
Reassembly{
Start: true,
Bytes: []byte{1, 2, 3},
},
},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1007,
BaseLayer: layers.BaseLayer{Payload: []byte{3, 2, 3}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1010,
BaseLayer: layers.BaseLayer{Payload: []byte{4, 2, 3}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1013,
BaseLayer: layers.BaseLayer{Payload: []byte{5, 2, 3}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1016,
BaseLayer: layers.BaseLayer{Payload: []byte{6, 2, 3}},
},
want: []Reassembly{
Reassembly{
Skip: 3,
Bytes: []byte{3, 2, 3},
},
Reassembly{
Bytes: []byte{4, 2, 3},
},
Reassembly{
Bytes: []byte{5, 2, 3},
},
Reassembly{
Bytes: []byte{6, 2, 3},
},
},
},
})
}
func TestReorderFast(t *testing.T) {
test(t, []testSequence{
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
SYN: true,
Seq: 1000,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}},
},
want: []Reassembly{
Reassembly{
Start: true,
Bytes: []byte{1, 2, 3},
},
},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1007,
BaseLayer: layers.BaseLayer{Payload: []byte{3, 2, 3}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1004,
BaseLayer: layers.BaseLayer{Payload: []byte{2, 2, 3}},
},
want: []Reassembly{
Reassembly{
Bytes: []byte{2, 2, 3},
},
Reassembly{
Bytes: []byte{3, 2, 3},
},
},
},
})
}
func TestOverlap(t *testing.T) {
test(t, []testSequence{
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
SYN: true,
Seq: 1000,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
},
want: []Reassembly{
Reassembly{
Start: true,
Bytes: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
},
},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1007,
BaseLayer: layers.BaseLayer{Payload: []byte{7, 8, 9, 0, 1, 2, 3, 4, 5}},
},
want: []Reassembly{
Reassembly{
Bytes: []byte{1, 2, 3, 4, 5},
},
},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1010,
BaseLayer: layers.BaseLayer{Payload: []byte{0, 1, 2, 3, 4, 5, 6, 7}},
},
want: []Reassembly{
Reassembly{
Bytes: []byte{6, 7},
},
},
},
})
}
func TestBufferedOverlap(t *testing.T) {
test(t, []testSequence{
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1007,
BaseLayer: layers.BaseLayer{Payload: []byte{7, 8, 9, 0, 1, 2, 3, 4, 5}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1010,
BaseLayer: layers.BaseLayer{Payload: []byte{0, 1, 2, 3, 4, 5, 6, 7}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
SYN: true,
Seq: 1000,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
},
want: []Reassembly{
Reassembly{
Start: true,
Bytes: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
},
Reassembly{
Bytes: []byte{1, 2, 3, 4, 5},
},
Reassembly{
Bytes: []byte{6, 7},
},
},
},
})
}
func TestOverrun1(t *testing.T) {
test(t, []testSequence{
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
SYN: true,
Seq: 0xFFFFFFFF,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
},
want: []Reassembly{
Reassembly{
Start: true,
Bytes: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
},
},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 10,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4}},
},
want: []Reassembly{
Reassembly{
Bytes: []byte{1, 2, 3, 4},
},
},
},
})
}
func TestOverrun2(t *testing.T) {
test(t, []testSequence{
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 10,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4}},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
SYN: true,
Seq: 0xFFFFFFFF,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
},
want: []Reassembly{
Reassembly{
Start: true,
Bytes: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
},
Reassembly{
Bytes: []byte{1, 2, 3, 4},
},
},
},
})
}
func TestCacheLargePacket(t *testing.T) {
data := make([]byte, pageBytes*3)
test(t, []testSequence{
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1001,
BaseLayer: layers.BaseLayer{Payload: data},
},
want: []Reassembly{},
},
{
in: layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 1000,
SYN: true,
BaseLayer: layers.BaseLayer{Payload: []byte{}},
},
want: []Reassembly{
Reassembly{
Start: true,
Bytes: []byte{},
},
Reassembly{
Bytes: data[:pageBytes],
},
Reassembly{
Bytes: data[pageBytes : pageBytes*2],
},
Reassembly{
Bytes: data[pageBytes*2 : pageBytes*3],
},
},
},
})
}
func BenchmarkSingleStream(b *testing.B) {
t := layers.TCP{
SrcPort: 1,
DstPort: 2,
SYN: true,
Seq: 1000,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
}
a := NewAssembler(NewStreamPool(&testFactory{}))
for i := 0; i < b.N; i++ {
a.Assemble(netFlow, &t)
if t.SYN {
t.SYN = false
t.Seq++
}
t.Seq += 10
}
}
func BenchmarkSingleStreamSkips(b *testing.B) {
t := layers.TCP{
SrcPort: 1,
DstPort: 2,
SYN: true,
Seq: 1000,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
}
a := NewAssembler(NewStreamPool(&testFactory{}))
skipped := false
for i := 0; i < b.N; i++ {
if i%10 == 9 {
t.Seq += 10
skipped = true
} else if skipped {
t.Seq -= 20
}
a.Assemble(netFlow, &t)
if t.SYN {
t.SYN = false
t.Seq++
}
t.Seq += 10
if skipped {
t.Seq += 10
skipped = false
}
}
}
func BenchmarkSingleStreamLoss(b *testing.B) {
t := layers.TCP{
SrcPort: 1,
DstPort: 2,
SYN: true,
Seq: 1000,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
}
a := NewAssembler(NewStreamPool(&testFactory{}))
for i := 0; i < b.N; i++ {
a.Assemble(netFlow, &t)
t.SYN = false
t.Seq += 11
}
}
func BenchmarkMultiStreamGrow(b *testing.B) {
t := layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 0,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
}
a := NewAssembler(NewStreamPool(&testFactory{}))
for i := 0; i < b.N; i++ {
t.SrcPort = layers.TCPPort(i)
a.Assemble(netFlow, &t)
t.Seq += 10
}
}
func BenchmarkMultiStreamConn(b *testing.B) {
t := layers.TCP{
SrcPort: 1,
DstPort: 2,
Seq: 0,
SYN: true,
BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
}
a := NewAssembler(NewStreamPool(&testFactory{}))
for i := 0; i < b.N; i++ {
t.SrcPort = layers.TCPPort(i)
a.Assemble(netFlow, &t)
if i%65536 == 65535 {
if t.SYN {
t.SYN = false
t.Seq++
}
t.Seq += 10
}
}
}