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 }