github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/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  	"bytes"
    19  	"fmt"
    20  	"io"
    21  	"net"
    22  	"testing"
    23  
    24  	"github.com/google/go-cmp/cmp"
    25  )
    26  
    27  func TestLimitedWriter_Write(t *testing.T) {
    28  	var b bytes.Buffer
    29  	l := LimitedWriter{
    30  		W: &b,
    31  		N: 5,
    32  	}
    33  	if n, err := l.Write([]byte{0, 1, 2}); err != nil {
    34  		t.Errorf("got l.Write(3/5) = (_, %s), want nil", err)
    35  	} else if n != 3 {
    36  		t.Errorf("got l.Write(3/5) = (%d, _), want 3", n)
    37  	}
    38  	if n, err := l.Write([]byte{3, 4, 5}); err != io.ErrShortWrite {
    39  		t.Errorf("got l.Write(3/2) = (_, %s), want io.ErrShortWrite", err)
    40  	} else if n != 2 {
    41  		t.Errorf("got l.Write(3/2) = (%d, _), want 2", n)
    42  	}
    43  	if l.N != 0 {
    44  		t.Errorf("got l.N = %d, want 0", l.N)
    45  	}
    46  	l.N = 1
    47  	if n, err := l.Write([]byte{5}); err != nil {
    48  		t.Errorf("got l.Write(1/1) = (_, %s), want nil", err)
    49  	} else if n != 1 {
    50  		t.Errorf("got l.Write(1/1) = (%d, _), want 1", n)
    51  	}
    52  	if diff := cmp.Diff(b.Bytes(), []byte{0, 1, 2, 3, 4, 5}); diff != "" {
    53  		t.Errorf("%T wrote incorrect data: (-want +got):\n%s", l, diff)
    54  	}
    55  }
    56  
    57  func TestSubnetContains(t *testing.T) {
    58  	tests := []struct {
    59  		s    Address
    60  		m    AddressMask
    61  		a    Address
    62  		want bool
    63  	}{
    64  		{"\xa0", "\xf0", "\x90", false},
    65  		{"\xa0", "\xf0", "\xa0", true},
    66  		{"\xa0", "\xf0", "\xa5", true},
    67  		{"\xa0", "\xf0", "\xaf", true},
    68  		{"\xa0", "\xf0", "\xb0", false},
    69  		{"\xa0", "\xf0", "", false},
    70  		{"\xa0", "\xf0", "\xa0\x00", false},
    71  		{"\xc2\x80", "\xff\xf0", "\xc2\x80", true},
    72  		{"\xc2\x80", "\xff\xf0", "\xc2\x00", false},
    73  		{"\xc2\x00", "\xff\xf0", "\xc2\x00", true},
    74  		{"\xc2\x00", "\xff\xf0", "\xc2\x80", false},
    75  	}
    76  	for _, tt := range tests {
    77  		s, err := NewSubnet(tt.s, tt.m)
    78  		if err != nil {
    79  			t.Errorf("NewSubnet(%v, %v) = %v", tt.s, tt.m, err)
    80  			continue
    81  		}
    82  		if got := s.Contains(tt.a); got != tt.want {
    83  			t.Errorf("Subnet(%v).Contains(%v) = %v, want %v", s, tt.a, got, tt.want)
    84  		}
    85  	}
    86  }
    87  
    88  func TestSubnetBits(t *testing.T) {
    89  	tests := []struct {
    90  		a     AddressMask
    91  		want1 int
    92  		want0 int
    93  	}{
    94  		{"\x00", 0, 8},
    95  		{"\x00\x00", 0, 16},
    96  		{"\x36", 0, 8},
    97  		{"\x5c", 0, 8},
    98  		{"\x5c\x5c", 0, 16},
    99  		{"\x5c\x36", 0, 16},
   100  		{"\x36\x5c", 0, 16},
   101  		{"\x36\x36", 0, 16},
   102  		{"\xff", 8, 0},
   103  		{"\xff\xff", 16, 0},
   104  	}
   105  	for _, tt := range tests {
   106  		s := &Subnet{mask: tt.a}
   107  		got1, got0 := s.Bits()
   108  		if got1 != tt.want1 || got0 != tt.want0 {
   109  			t.Errorf("Subnet{mask: %x}.Bits() = %d, %d, want %d, %d", tt.a, got1, got0, tt.want1, tt.want0)
   110  		}
   111  	}
   112  }
   113  
   114  func TestSubnetPrefix(t *testing.T) {
   115  	tests := []struct {
   116  		a    AddressMask
   117  		want int
   118  	}{
   119  		{"\x00", 0},
   120  		{"\x00\x00", 0},
   121  		{"\x36", 0},
   122  		{"\x86", 1},
   123  		{"\xc5", 2},
   124  		{"\xff\x00", 8},
   125  		{"\xff\x36", 8},
   126  		{"\xff\x8c", 9},
   127  		{"\xff\xc8", 10},
   128  		{"\xff", 8},
   129  		{"\xff\xff", 16},
   130  	}
   131  	for _, tt := range tests {
   132  		s := &Subnet{mask: tt.a}
   133  		got := s.Prefix()
   134  		if got != tt.want {
   135  			t.Errorf("Subnet{mask: %x}.Bits() = %d want %d", tt.a, got, tt.want)
   136  		}
   137  	}
   138  }
   139  
   140  func TestSubnetCreation(t *testing.T) {
   141  	tests := []struct {
   142  		a    Address
   143  		m    AddressMask
   144  		want error
   145  	}{
   146  		{"\xa0", "\xf0", nil},
   147  		{"\xa0\xa0", "\xf0", errSubnetLengthMismatch},
   148  		{"\xaa", "\xf0", errSubnetAddressMasked},
   149  		{"", "", nil},
   150  	}
   151  	for _, tt := range tests {
   152  		if _, err := NewSubnet(tt.a, tt.m); err != tt.want {
   153  			t.Errorf("NewSubnet(%v, %v) = %v, want %v", tt.a, tt.m, err, tt.want)
   154  		}
   155  	}
   156  }
   157  
   158  func TestAddressString(t *testing.T) {
   159  	for _, want := range []string{
   160  		// Taken from stdlib.
   161  		"2001:db8::123:12:1",
   162  		"2001:db8::1",
   163  		"2001:db8:0:1:0:1:0:1",
   164  		"2001:db8:1:0:1:0:1:0",
   165  		"2001::1:0:0:1",
   166  		"2001:db8:0:0:1::",
   167  		"2001:db8::1:0:0:1",
   168  		"2001:db8::a:b:c:d",
   169  
   170  		// Leading zeros.
   171  		"::1",
   172  		// Trailing zeros.
   173  		"8::",
   174  		// No zeros.
   175  		"1:1:1:1:1:1:1:1",
   176  		// Longer sequence is after other zeros, but not at the end.
   177  		"1:0:0:1::1",
   178  		// Longer sequence is at the beginning, shorter sequence is at
   179  		// the end.
   180  		"::1:1:1:0:0",
   181  		// Longer sequence is not at the beginning, shorter sequence is
   182  		// at the end.
   183  		"1::1:1:0:0",
   184  		// Longer sequence is at the beginning, shorter sequence is not
   185  		// at the end.
   186  		"::1:1:0:0:1",
   187  		// Neither sequence is at an end, longer is after shorter.
   188  		"1:0:0:1::1",
   189  		// Shorter sequence is at the beginning, longer sequence is not
   190  		// at the end.
   191  		"0:0:1:1::1",
   192  		// Shorter sequence is at the beginning, longer sequence is at
   193  		// the end.
   194  		"0:0:1:1:1::",
   195  		// Short sequences at both ends, longer one in the middle.
   196  		"0:1:1::1:1:0",
   197  		// Short sequences at both ends, longer one in the middle.
   198  		"0:1::1:0:0",
   199  		// Short sequences at both ends, longer one in the middle.
   200  		"0:0:1::1:0",
   201  		// Longer sequence surrounded by shorter sequences, but none at
   202  		// the end.
   203  		"1:0:1::1:0:1",
   204  	} {
   205  		addr := Address(net.ParseIP(want))
   206  		if got := addr.String(); got != want {
   207  			t.Errorf("Address(%x).String() = '%s', want = '%s'", addr, got, want)
   208  		}
   209  	}
   210  }
   211  
   212  func TestAddressWithPrefixSubnet(t *testing.T) {
   213  	tests := []struct {
   214  		addr       Address
   215  		prefixLen  int
   216  		subnetAddr Address
   217  		subnetMask AddressMask
   218  	}{
   219  		{"\xaa\x55\x33\x42", -1, "\x00\x00\x00\x00", "\x00\x00\x00\x00"},
   220  		{"\xaa\x55\x33\x42", 0, "\x00\x00\x00\x00", "\x00\x00\x00\x00"},
   221  		{"\xaa\x55\x33\x42", 1, "\x80\x00\x00\x00", "\x80\x00\x00\x00"},
   222  		{"\xaa\x55\x33\x42", 7, "\xaa\x00\x00\x00", "\xfe\x00\x00\x00"},
   223  		{"\xaa\x55\x33\x42", 8, "\xaa\x00\x00\x00", "\xff\x00\x00\x00"},
   224  		{"\xaa\x55\x33\x42", 24, "\xaa\x55\x33\x00", "\xff\xff\xff\x00"},
   225  		{"\xaa\x55\x33\x42", 31, "\xaa\x55\x33\x42", "\xff\xff\xff\xfe"},
   226  		{"\xaa\x55\x33\x42", 32, "\xaa\x55\x33\x42", "\xff\xff\xff\xff"},
   227  		{"\xaa\x55\x33\x42", 33, "\xaa\x55\x33\x42", "\xff\xff\xff\xff"},
   228  	}
   229  	for _, tt := range tests {
   230  		ap := AddressWithPrefix{Address: tt.addr, PrefixLen: tt.prefixLen}
   231  		gotSubnet := ap.Subnet()
   232  		wantSubnet, err := NewSubnet(tt.subnetAddr, tt.subnetMask)
   233  		if err != nil {
   234  			t.Errorf("NewSubnet(%q, %q) failed: %s", tt.subnetAddr, tt.subnetMask, err)
   235  			continue
   236  		}
   237  		if gotSubnet != wantSubnet {
   238  			t.Errorf("got subnet = %q, want = %q", gotSubnet, wantSubnet)
   239  		}
   240  	}
   241  }
   242  
   243  func TestAddressUnspecified(t *testing.T) {
   244  	tests := []struct {
   245  		addr        Address
   246  		unspecified bool
   247  	}{
   248  		{
   249  			addr:        "",
   250  			unspecified: true,
   251  		},
   252  		{
   253  			addr:        "\x00",
   254  			unspecified: true,
   255  		},
   256  		{
   257  			addr:        "\x01",
   258  			unspecified: false,
   259  		},
   260  		{
   261  			addr:        "\x00\x00",
   262  			unspecified: true,
   263  		},
   264  		{
   265  			addr:        "\x01\x00",
   266  			unspecified: false,
   267  		},
   268  		{
   269  			addr:        "\x00\x01",
   270  			unspecified: false,
   271  		},
   272  		{
   273  			addr:        "\x01\x01",
   274  			unspecified: false,
   275  		},
   276  	}
   277  
   278  	for _, test := range tests {
   279  		t.Run(fmt.Sprintf("addr=%s", test.addr), func(t *testing.T) {
   280  			if got := test.addr.Unspecified(); got != test.unspecified {
   281  				t.Fatalf("got addr.Unspecified() = %t, want = %t", got, test.unspecified)
   282  			}
   283  		})
   284  	}
   285  }
   286  
   287  func TestAddressMatchingPrefix(t *testing.T) {
   288  	tests := []struct {
   289  		addrA  Address
   290  		addrB  Address
   291  		prefix uint8
   292  	}{
   293  		{
   294  			addrA:  "\x01\x01",
   295  			addrB:  "\x01\x01",
   296  			prefix: 16,
   297  		},
   298  		{
   299  			addrA:  "\x01\x01",
   300  			addrB:  "\x01\x00",
   301  			prefix: 15,
   302  		},
   303  		{
   304  			addrA:  "\x01\x01",
   305  			addrB:  "\x81\x00",
   306  			prefix: 0,
   307  		},
   308  		{
   309  			addrA:  "\x01\x01",
   310  			addrB:  "\x01\x80",
   311  			prefix: 8,
   312  		},
   313  		{
   314  			addrA:  "\x01\x01",
   315  			addrB:  "\x02\x80",
   316  			prefix: 6,
   317  		},
   318  	}
   319  
   320  	for _, test := range tests {
   321  		if got := test.addrA.MatchingPrefix(test.addrB); got != test.prefix {
   322  			t.Errorf("got (%s).MatchingPrefix(%s) = %d, want = %d", test.addrA, test.addrB, got, test.prefix)
   323  		}
   324  	}
   325  }