github.com/google/netstack@v0.0.0-20191123085552-55fcc16cd0eb/tcpip/tcpip_test.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tcpip
    16  
    17  import (
    18  	"fmt"
    19  	"net"
    20  	"strings"
    21  	"testing"
    22  )
    23  
    24  func TestSubnetContains(t *testing.T) {
    25  	tests := []struct {
    26  		s    Address
    27  		m    AddressMask
    28  		a    Address
    29  		want bool
    30  	}{
    31  		{"\xa0", "\xf0", "\x90", false},
    32  		{"\xa0", "\xf0", "\xa0", true},
    33  		{"\xa0", "\xf0", "\xa5", true},
    34  		{"\xa0", "\xf0", "\xaf", true},
    35  		{"\xa0", "\xf0", "\xb0", false},
    36  		{"\xa0", "\xf0", "", false},
    37  		{"\xa0", "\xf0", "\xa0\x00", false},
    38  		{"\xc2\x80", "\xff\xf0", "\xc2\x80", true},
    39  		{"\xc2\x80", "\xff\xf0", "\xc2\x00", false},
    40  		{"\xc2\x00", "\xff\xf0", "\xc2\x00", true},
    41  		{"\xc2\x00", "\xff\xf0", "\xc2\x80", false},
    42  	}
    43  	for _, tt := range tests {
    44  		s, err := NewSubnet(tt.s, tt.m)
    45  		if err != nil {
    46  			t.Errorf("NewSubnet(%v, %v) = %v", tt.s, tt.m, err)
    47  			continue
    48  		}
    49  		if got := s.Contains(tt.a); got != tt.want {
    50  			t.Errorf("Subnet(%v).Contains(%v) = %v, want %v", s, tt.a, got, tt.want)
    51  		}
    52  	}
    53  }
    54  
    55  func TestSubnetBits(t *testing.T) {
    56  	tests := []struct {
    57  		a     AddressMask
    58  		want1 int
    59  		want0 int
    60  	}{
    61  		{"\x00", 0, 8},
    62  		{"\x00\x00", 0, 16},
    63  		{"\x36", 0, 8},
    64  		{"\x5c", 0, 8},
    65  		{"\x5c\x5c", 0, 16},
    66  		{"\x5c\x36", 0, 16},
    67  		{"\x36\x5c", 0, 16},
    68  		{"\x36\x36", 0, 16},
    69  		{"\xff", 8, 0},
    70  		{"\xff\xff", 16, 0},
    71  	}
    72  	for _, tt := range tests {
    73  		s := &Subnet{mask: tt.a}
    74  		got1, got0 := s.Bits()
    75  		if got1 != tt.want1 || got0 != tt.want0 {
    76  			t.Errorf("Subnet{mask: %x}.Bits() = %d, %d, want %d, %d", tt.a, got1, got0, tt.want1, tt.want0)
    77  		}
    78  	}
    79  }
    80  
    81  func TestSubnetPrefix(t *testing.T) {
    82  	tests := []struct {
    83  		a    AddressMask
    84  		want int
    85  	}{
    86  		{"\x00", 0},
    87  		{"\x00\x00", 0},
    88  		{"\x36", 0},
    89  		{"\x86", 1},
    90  		{"\xc5", 2},
    91  		{"\xff\x00", 8},
    92  		{"\xff\x36", 8},
    93  		{"\xff\x8c", 9},
    94  		{"\xff\xc8", 10},
    95  		{"\xff", 8},
    96  		{"\xff\xff", 16},
    97  	}
    98  	for _, tt := range tests {
    99  		s := &Subnet{mask: tt.a}
   100  		got := s.Prefix()
   101  		if got != tt.want {
   102  			t.Errorf("Subnet{mask: %x}.Bits() = %d want %d", tt.a, got, tt.want)
   103  		}
   104  	}
   105  }
   106  
   107  func TestSubnetCreation(t *testing.T) {
   108  	tests := []struct {
   109  		a    Address
   110  		m    AddressMask
   111  		want error
   112  	}{
   113  		{"\xa0", "\xf0", nil},
   114  		{"\xa0\xa0", "\xf0", errSubnetLengthMismatch},
   115  		{"\xaa", "\xf0", errSubnetAddressMasked},
   116  		{"", "", nil},
   117  	}
   118  	for _, tt := range tests {
   119  		if _, err := NewSubnet(tt.a, tt.m); err != tt.want {
   120  			t.Errorf("NewSubnet(%v, %v) = %v, want %v", tt.a, tt.m, err, tt.want)
   121  		}
   122  	}
   123  }
   124  
   125  func TestAddressString(t *testing.T) {
   126  	for _, want := range []string{
   127  		// Taken from stdlib.
   128  		"2001:db8::123:12:1",
   129  		"2001:db8::1",
   130  		"2001:db8:0:1:0:1:0:1",
   131  		"2001:db8:1:0:1:0:1:0",
   132  		"2001::1:0:0:1",
   133  		"2001:db8:0:0:1::",
   134  		"2001:db8::1:0:0:1",
   135  		"2001:db8::a:b:c:d",
   136  
   137  		// Leading zeros.
   138  		"::1",
   139  		// Trailing zeros.
   140  		"8::",
   141  		// No zeros.
   142  		"1:1:1:1:1:1:1:1",
   143  		// Longer sequence is after other zeros, but not at the end.
   144  		"1:0:0:1::1",
   145  		// Longer sequence is at the beginning, shorter sequence is at
   146  		// the end.
   147  		"::1:1:1:0:0",
   148  		// Longer sequence is not at the beginning, shorter sequence is
   149  		// at the end.
   150  		"1::1:1:0:0",
   151  		// Longer sequence is at the beginning, shorter sequence is not
   152  		// at the end.
   153  		"::1:1:0:0:1",
   154  		// Neither sequence is at an end, longer is after shorter.
   155  		"1:0:0:1::1",
   156  		// Shorter sequence is at the beginning, longer sequence is not
   157  		// at the end.
   158  		"0:0:1:1::1",
   159  		// Shorter sequence is at the beginning, longer sequence is at
   160  		// the end.
   161  		"0:0:1:1:1::",
   162  		// Short sequences at both ends, longer one in the middle.
   163  		"0:1:1::1:1:0",
   164  		// Short sequences at both ends, longer one in the middle.
   165  		"0:1::1:0:0",
   166  		// Short sequences at both ends, longer one in the middle.
   167  		"0:0:1::1:0",
   168  		// Longer sequence surrounded by shorter sequences, but none at
   169  		// the end.
   170  		"1:0:1::1:0:1",
   171  	} {
   172  		addr := Address(net.ParseIP(want))
   173  		if got := addr.String(); got != want {
   174  			t.Errorf("Address(%x).String() = '%s', want = '%s'", addr, got, want)
   175  		}
   176  	}
   177  }
   178  
   179  func TestStatsString(t *testing.T) {
   180  	got := fmt.Sprintf("%+v", Stats{}.FillIn())
   181  
   182  	matchers := []string{
   183  		// Print root-level stats correctly.
   184  		"UnknownProtocolRcvdPackets:0",
   185  		// Print protocol-specific stats correctly.
   186  		"TCP:{ActiveConnectionOpenings:0",
   187  	}
   188  
   189  	for _, m := range matchers {
   190  		if !strings.Contains(got, m) {
   191  			t.Errorf("string.Contains(got, %q) = false", m)
   192  		}
   193  	}
   194  	if t.Failed() {
   195  		t.Logf(`got = fmt.Sprintf("%%+v", Stats{}.FillIn()) = %q`, got)
   196  	}
   197  }
   198  
   199  func TestAddressWithPrefixSubnet(t *testing.T) {
   200  	tests := []struct {
   201  		addr       Address
   202  		prefixLen  int
   203  		subnetAddr Address
   204  		subnetMask AddressMask
   205  	}{
   206  		{"\xaa\x55\x33\x42", -1, "\x00\x00\x00\x00", "\x00\x00\x00\x00"},
   207  		{"\xaa\x55\x33\x42", 0, "\x00\x00\x00\x00", "\x00\x00\x00\x00"},
   208  		{"\xaa\x55\x33\x42", 1, "\x80\x00\x00\x00", "\x80\x00\x00\x00"},
   209  		{"\xaa\x55\x33\x42", 7, "\xaa\x00\x00\x00", "\xfe\x00\x00\x00"},
   210  		{"\xaa\x55\x33\x42", 8, "\xaa\x00\x00\x00", "\xff\x00\x00\x00"},
   211  		{"\xaa\x55\x33\x42", 24, "\xaa\x55\x33\x00", "\xff\xff\xff\x00"},
   212  		{"\xaa\x55\x33\x42", 31, "\xaa\x55\x33\x42", "\xff\xff\xff\xfe"},
   213  		{"\xaa\x55\x33\x42", 32, "\xaa\x55\x33\x42", "\xff\xff\xff\xff"},
   214  		{"\xaa\x55\x33\x42", 33, "\xaa\x55\x33\x42", "\xff\xff\xff\xff"},
   215  	}
   216  	for _, tt := range tests {
   217  		ap := AddressWithPrefix{Address: tt.addr, PrefixLen: tt.prefixLen}
   218  		gotSubnet := ap.Subnet()
   219  		wantSubnet, err := NewSubnet(tt.subnetAddr, tt.subnetMask)
   220  		if err != nil {
   221  			t.Error("NewSubnet(%q, %q) failed: %s", tt.subnetAddr, tt.subnetMask, err)
   222  			continue
   223  		}
   224  		if gotSubnet != wantSubnet {
   225  			t.Errorf("got subnet = %q, want = %q", gotSubnet, wantSubnet)
   226  		}
   227  	}
   228  }