github.com/gopacket/gopacket@v1.1.0/tcpassembly/assembly_test.go (about)

     1  // Copyright 2012 Google, Inc. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the LICENSE file in the root of the source
     5  // tree.
     6  
     7  package tcpassembly
     8  
     9  import (
    10  	"net"
    11  	"reflect"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/gopacket/gopacket"
    16  	"github.com/gopacket/gopacket/layers"
    17  )
    18  
    19  var netFlow gopacket.Flow
    20  
    21  func init() {
    22  	netFlow, _ = gopacket.FlowFromEndpoints(
    23  		layers.NewIPEndpoint(net.IP{1, 2, 3, 4}),
    24  		layers.NewIPEndpoint(net.IP{5, 6, 7, 8}))
    25  }
    26  
    27  func TestSequenceOverflow(t *testing.T) {
    28  	if want, got := 20, Sequence((1<<32)-10).Difference(Sequence(10)); want != got {
    29  		t.Errorf("overflow diff failure: got %d want %d", got, want)
    30  	}
    31  }
    32  
    33  type testSequence struct {
    34  	in   layers.TCP
    35  	want []Reassembly
    36  }
    37  
    38  type testFactory struct {
    39  	reassembly []Reassembly
    40  }
    41  
    42  func (t *testFactory) New(a, b gopacket.Flow) Stream {
    43  	return t
    44  }
    45  func (t *testFactory) Reassembled(r []Reassembly) {
    46  	t.reassembly = r
    47  	for i := 0; i < len(r); i++ {
    48  		t.reassembly[i].Seen = time.Time{}
    49  	}
    50  }
    51  func (t *testFactory) ReassemblyComplete() {
    52  }
    53  
    54  func test(t *testing.T, s []testSequence) {
    55  	fact := &testFactory{}
    56  	p := NewStreamPool(fact)
    57  	a := NewAssembler(p)
    58  	a.MaxBufferedPagesPerConnection = 4
    59  	for i, test := range s {
    60  		fact.reassembly = []Reassembly{}
    61  		a.Assemble(netFlow, &test.in)
    62  		if !reflect.DeepEqual(fact.reassembly, test.want) {
    63  			t.Fatalf("test %v:\nwant: %v\n got: %v\n", i, test.want, fact.reassembly)
    64  		}
    65  	}
    66  }
    67  
    68  func TestReorder(t *testing.T) {
    69  	test(t, []testSequence{
    70  		{
    71  			in: layers.TCP{
    72  				SrcPort:   1,
    73  				DstPort:   2,
    74  				Seq:       1001,
    75  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}},
    76  			},
    77  			want: []Reassembly{},
    78  		},
    79  		{
    80  			in: layers.TCP{
    81  				SrcPort:   1,
    82  				DstPort:   2,
    83  				Seq:       1004,
    84  				BaseLayer: layers.BaseLayer{Payload: []byte{2, 2, 3}},
    85  			},
    86  			want: []Reassembly{},
    87  		},
    88  		{
    89  			in: layers.TCP{
    90  				SrcPort:   1,
    91  				DstPort:   2,
    92  				Seq:       1010,
    93  				BaseLayer: layers.BaseLayer{Payload: []byte{4, 2, 3}},
    94  			},
    95  			want: []Reassembly{},
    96  		},
    97  		{
    98  			in: layers.TCP{
    99  				SrcPort:   1,
   100  				DstPort:   2,
   101  				Seq:       1007,
   102  				BaseLayer: layers.BaseLayer{Payload: []byte{3, 2, 3}},
   103  			},
   104  			want: []Reassembly{
   105  				Reassembly{
   106  					Skip:  -1,
   107  					Bytes: []byte{1, 2, 3},
   108  				},
   109  				Reassembly{
   110  					Bytes: []byte{2, 2, 3},
   111  				},
   112  				Reassembly{
   113  					Bytes: []byte{3, 2, 3},
   114  				},
   115  				Reassembly{
   116  					Bytes: []byte{4, 2, 3},
   117  				},
   118  			},
   119  		},
   120  		{
   121  			in: layers.TCP{
   122  				SrcPort:   1,
   123  				DstPort:   2,
   124  				Seq:       1016,
   125  				BaseLayer: layers.BaseLayer{Payload: []byte{2, 2, 3}},
   126  			},
   127  			want: []Reassembly{},
   128  		},
   129  		{
   130  			in: layers.TCP{
   131  				SrcPort:   1,
   132  				DstPort:   2,
   133  				Seq:       1019,
   134  				BaseLayer: layers.BaseLayer{Payload: []byte{3, 2, 3}},
   135  			},
   136  			want: []Reassembly{},
   137  		},
   138  		{
   139  			in: layers.TCP{
   140  				SrcPort:   1,
   141  				DstPort:   2,
   142  				Seq:       1013,
   143  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}},
   144  			},
   145  			want: []Reassembly{
   146  				Reassembly{
   147  					Bytes: []byte{1, 2, 3},
   148  				},
   149  				Reassembly{
   150  					Bytes: []byte{2, 2, 3},
   151  				},
   152  				Reassembly{
   153  					Bytes: []byte{3, 2, 3},
   154  				},
   155  			},
   156  		},
   157  	})
   158  }
   159  
   160  func TestMaxPerSkip(t *testing.T) {
   161  	test(t, []testSequence{
   162  		{
   163  			in: layers.TCP{
   164  				SrcPort:   1,
   165  				DstPort:   2,
   166  				Seq:       1000,
   167  				SYN:       true,
   168  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}},
   169  			},
   170  			want: []Reassembly{
   171  				Reassembly{
   172  					Start: true,
   173  					Bytes: []byte{1, 2, 3},
   174  				},
   175  			},
   176  		},
   177  		{
   178  			in: layers.TCP{
   179  				SrcPort:   1,
   180  				DstPort:   2,
   181  				Seq:       1007,
   182  				BaseLayer: layers.BaseLayer{Payload: []byte{3, 2, 3}},
   183  			},
   184  			want: []Reassembly{},
   185  		},
   186  		{
   187  			in: layers.TCP{
   188  				SrcPort:   1,
   189  				DstPort:   2,
   190  				Seq:       1010,
   191  				BaseLayer: layers.BaseLayer{Payload: []byte{4, 2, 3}},
   192  			},
   193  			want: []Reassembly{},
   194  		},
   195  		{
   196  			in: layers.TCP{
   197  				SrcPort:   1,
   198  				DstPort:   2,
   199  				Seq:       1013,
   200  				BaseLayer: layers.BaseLayer{Payload: []byte{5, 2, 3}},
   201  			},
   202  			want: []Reassembly{},
   203  		},
   204  		{
   205  			in: layers.TCP{
   206  				SrcPort:   1,
   207  				DstPort:   2,
   208  				Seq:       1016,
   209  				BaseLayer: layers.BaseLayer{Payload: []byte{6, 2, 3}},
   210  			},
   211  			want: []Reassembly{
   212  				Reassembly{
   213  					Skip:  3,
   214  					Bytes: []byte{3, 2, 3},
   215  				},
   216  				Reassembly{
   217  					Bytes: []byte{4, 2, 3},
   218  				},
   219  				Reassembly{
   220  					Bytes: []byte{5, 2, 3},
   221  				},
   222  				Reassembly{
   223  					Bytes: []byte{6, 2, 3},
   224  				},
   225  			},
   226  		},
   227  	})
   228  }
   229  
   230  func TestReorderFast(t *testing.T) {
   231  	test(t, []testSequence{
   232  		{
   233  			in: layers.TCP{
   234  				SrcPort:   1,
   235  				DstPort:   2,
   236  				SYN:       true,
   237  				Seq:       1000,
   238  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}},
   239  			},
   240  			want: []Reassembly{
   241  				Reassembly{
   242  					Start: true,
   243  					Bytes: []byte{1, 2, 3},
   244  				},
   245  			},
   246  		},
   247  		{
   248  			in: layers.TCP{
   249  				SrcPort:   1,
   250  				DstPort:   2,
   251  				Seq:       1007,
   252  				BaseLayer: layers.BaseLayer{Payload: []byte{3, 2, 3}},
   253  			},
   254  			want: []Reassembly{},
   255  		},
   256  		{
   257  			in: layers.TCP{
   258  				SrcPort:   1,
   259  				DstPort:   2,
   260  				Seq:       1004,
   261  				BaseLayer: layers.BaseLayer{Payload: []byte{2, 2, 3}},
   262  			},
   263  			want: []Reassembly{
   264  				Reassembly{
   265  					Bytes: []byte{2, 2, 3},
   266  				},
   267  				Reassembly{
   268  					Bytes: []byte{3, 2, 3},
   269  				},
   270  			},
   271  		},
   272  	})
   273  }
   274  
   275  func TestOverlap(t *testing.T) {
   276  	test(t, []testSequence{
   277  		{
   278  			in: layers.TCP{
   279  				SrcPort:   1,
   280  				DstPort:   2,
   281  				SYN:       true,
   282  				Seq:       1000,
   283  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
   284  			},
   285  			want: []Reassembly{
   286  				Reassembly{
   287  					Start: true,
   288  					Bytes: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
   289  				},
   290  			},
   291  		},
   292  		{
   293  			in: layers.TCP{
   294  				SrcPort:   1,
   295  				DstPort:   2,
   296  				Seq:       1007,
   297  				BaseLayer: layers.BaseLayer{Payload: []byte{7, 8, 9, 0, 1, 2, 3, 4, 5}},
   298  			},
   299  			want: []Reassembly{
   300  				Reassembly{
   301  					Bytes: []byte{1, 2, 3, 4, 5},
   302  				},
   303  			},
   304  		},
   305  		{
   306  			in: layers.TCP{
   307  				SrcPort:   1,
   308  				DstPort:   2,
   309  				Seq:       1010,
   310  				BaseLayer: layers.BaseLayer{Payload: []byte{0, 1, 2, 3, 4, 5, 6, 7}},
   311  			},
   312  			want: []Reassembly{
   313  				Reassembly{
   314  					Bytes: []byte{6, 7},
   315  				},
   316  			},
   317  		},
   318  	})
   319  }
   320  
   321  func TestBufferedOverlap(t *testing.T) {
   322  	test(t, []testSequence{
   323  		{
   324  			in: layers.TCP{
   325  				SrcPort:   1,
   326  				DstPort:   2,
   327  				Seq:       1007,
   328  				BaseLayer: layers.BaseLayer{Payload: []byte{7, 8, 9, 0, 1, 2, 3, 4, 5}},
   329  			},
   330  			want: []Reassembly{},
   331  		},
   332  		{
   333  			in: layers.TCP{
   334  				SrcPort:   1,
   335  				DstPort:   2,
   336  				Seq:       1010,
   337  				BaseLayer: layers.BaseLayer{Payload: []byte{0, 1, 2, 3, 4, 5, 6, 7}},
   338  			},
   339  			want: []Reassembly{},
   340  		},
   341  		{
   342  			in: layers.TCP{
   343  				SrcPort:   1,
   344  				DstPort:   2,
   345  				SYN:       true,
   346  				Seq:       1000,
   347  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
   348  			},
   349  			want: []Reassembly{
   350  				Reassembly{
   351  					Start: true,
   352  					Bytes: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
   353  				},
   354  				Reassembly{
   355  					Bytes: []byte{1, 2, 3, 4, 5},
   356  				},
   357  				Reassembly{
   358  					Bytes: []byte{6, 7},
   359  				},
   360  			},
   361  		},
   362  	})
   363  }
   364  
   365  func TestOverrun1(t *testing.T) {
   366  	test(t, []testSequence{
   367  		{
   368  			in: layers.TCP{
   369  				SrcPort:   1,
   370  				DstPort:   2,
   371  				SYN:       true,
   372  				Seq:       0xFFFFFFFF,
   373  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
   374  			},
   375  			want: []Reassembly{
   376  				Reassembly{
   377  					Start: true,
   378  					Bytes: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
   379  				},
   380  			},
   381  		},
   382  		{
   383  			in: layers.TCP{
   384  				SrcPort:   1,
   385  				DstPort:   2,
   386  				Seq:       10,
   387  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4}},
   388  			},
   389  			want: []Reassembly{
   390  				Reassembly{
   391  					Bytes: []byte{1, 2, 3, 4},
   392  				},
   393  			},
   394  		},
   395  	})
   396  }
   397  
   398  func TestOverrun2(t *testing.T) {
   399  	test(t, []testSequence{
   400  		{
   401  			in: layers.TCP{
   402  				SrcPort:   1,
   403  				DstPort:   2,
   404  				Seq:       10,
   405  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4}},
   406  			},
   407  			want: []Reassembly{},
   408  		},
   409  		{
   410  			in: layers.TCP{
   411  				SrcPort:   1,
   412  				DstPort:   2,
   413  				SYN:       true,
   414  				Seq:       0xFFFFFFFF,
   415  				BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
   416  			},
   417  			want: []Reassembly{
   418  				Reassembly{
   419  					Start: true,
   420  					Bytes: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
   421  				},
   422  				Reassembly{
   423  					Bytes: []byte{1, 2, 3, 4},
   424  				},
   425  			},
   426  		},
   427  	})
   428  }
   429  
   430  func TestCacheLargePacket(t *testing.T) {
   431  	data := make([]byte, pageBytes*3)
   432  	test(t, []testSequence{
   433  		{
   434  			in: layers.TCP{
   435  				SrcPort:   1,
   436  				DstPort:   2,
   437  				Seq:       1001,
   438  				BaseLayer: layers.BaseLayer{Payload: data},
   439  			},
   440  			want: []Reassembly{},
   441  		},
   442  		{
   443  			in: layers.TCP{
   444  				SrcPort:   1,
   445  				DstPort:   2,
   446  				Seq:       1000,
   447  				SYN:       true,
   448  				BaseLayer: layers.BaseLayer{Payload: []byte{}},
   449  			},
   450  			want: []Reassembly{
   451  				Reassembly{
   452  					Start: true,
   453  					Bytes: []byte{},
   454  				},
   455  				Reassembly{
   456  					Bytes: data[:pageBytes],
   457  				},
   458  				Reassembly{
   459  					Bytes: data[pageBytes : pageBytes*2],
   460  				},
   461  				Reassembly{
   462  					Bytes: data[pageBytes*2 : pageBytes*3],
   463  				},
   464  			},
   465  		},
   466  	})
   467  }
   468  
   469  func BenchmarkSingleStream(b *testing.B) {
   470  	t := layers.TCP{
   471  		SrcPort:   1,
   472  		DstPort:   2,
   473  		SYN:       true,
   474  		Seq:       1000,
   475  		BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
   476  	}
   477  	a := NewAssembler(NewStreamPool(&testFactory{}))
   478  	for i := 0; i < b.N; i++ {
   479  		a.Assemble(netFlow, &t)
   480  		if t.SYN {
   481  			t.SYN = false
   482  			t.Seq++
   483  		}
   484  		t.Seq += 10
   485  	}
   486  }
   487  
   488  func BenchmarkSingleStreamSkips(b *testing.B) {
   489  	t := layers.TCP{
   490  		SrcPort:   1,
   491  		DstPort:   2,
   492  		SYN:       true,
   493  		Seq:       1000,
   494  		BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
   495  	}
   496  	a := NewAssembler(NewStreamPool(&testFactory{}))
   497  	skipped := false
   498  	for i := 0; i < b.N; i++ {
   499  		if i%10 == 9 {
   500  			t.Seq += 10
   501  			skipped = true
   502  		} else if skipped {
   503  			t.Seq -= 20
   504  		}
   505  		a.Assemble(netFlow, &t)
   506  		if t.SYN {
   507  			t.SYN = false
   508  			t.Seq++
   509  		}
   510  		t.Seq += 10
   511  		if skipped {
   512  			t.Seq += 10
   513  			skipped = false
   514  		}
   515  	}
   516  }
   517  
   518  func BenchmarkSingleStreamLoss(b *testing.B) {
   519  	t := layers.TCP{
   520  		SrcPort:   1,
   521  		DstPort:   2,
   522  		SYN:       true,
   523  		Seq:       1000,
   524  		BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
   525  	}
   526  	a := NewAssembler(NewStreamPool(&testFactory{}))
   527  	for i := 0; i < b.N; i++ {
   528  		a.Assemble(netFlow, &t)
   529  		t.SYN = false
   530  		t.Seq += 11
   531  	}
   532  }
   533  
   534  func BenchmarkMultiStreamGrow(b *testing.B) {
   535  	t := layers.TCP{
   536  		SrcPort:   1,
   537  		DstPort:   2,
   538  		Seq:       0,
   539  		BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
   540  	}
   541  	a := NewAssembler(NewStreamPool(&testFactory{}))
   542  	for i := 0; i < b.N; i++ {
   543  		t.SrcPort = layers.TCPPort(i)
   544  		a.Assemble(netFlow, &t)
   545  		t.Seq += 10
   546  	}
   547  }
   548  
   549  func BenchmarkMultiStreamConn(b *testing.B) {
   550  	t := layers.TCP{
   551  		SrcPort:   1,
   552  		DstPort:   2,
   553  		Seq:       0,
   554  		SYN:       true,
   555  		BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}},
   556  	}
   557  	a := NewAssembler(NewStreamPool(&testFactory{}))
   558  	for i := 0; i < b.N; i++ {
   559  		t.SrcPort = layers.TCPPort(i)
   560  		a.Assemble(netFlow, &t)
   561  		if i%65536 == 65535 {
   562  			if t.SYN {
   563  				t.SYN = false
   564  				t.Seq++
   565  			}
   566  			t.Seq += 10
   567  		}
   568  	}
   569  }