github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/tcpip/stack/transport_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 stack_test 16 17 import ( 18 "bytes" 19 "io" 20 "testing" 21 22 "github.com/SagerNet/gvisor/pkg/tcpip" 23 "github.com/SagerNet/gvisor/pkg/tcpip/buffer" 24 "github.com/SagerNet/gvisor/pkg/tcpip/link/channel" 25 "github.com/SagerNet/gvisor/pkg/tcpip/ports" 26 "github.com/SagerNet/gvisor/pkg/tcpip/stack" 27 "github.com/SagerNet/gvisor/pkg/waiter" 28 ) 29 30 const ( 31 fakeTransNumber tcpip.TransportProtocolNumber = 1 32 fakeTransHeaderLen int = 3 33 ) 34 35 // fakeTransportEndpoint is a transport-layer protocol endpoint. It counts 36 // received packets; the counts of all endpoints are aggregated in the protocol 37 // descriptor. 38 // 39 // Headers of this protocol are fakeTransHeaderLen bytes, but we currently don't 40 // use it. 41 type fakeTransportEndpoint struct { 42 stack.TransportEndpointInfo 43 tcpip.DefaultSocketOptionsHandler 44 45 proto *fakeTransportProtocol 46 peerAddr tcpip.Address 47 route *stack.Route 48 uniqueID uint64 49 50 // acceptQueue is non-nil iff bound. 51 acceptQueue []*fakeTransportEndpoint 52 53 // ops is used to set and get socket options. 54 ops tcpip.SocketOptions 55 } 56 57 func (f *fakeTransportEndpoint) Info() tcpip.EndpointInfo { 58 return &f.TransportEndpointInfo 59 } 60 61 func (*fakeTransportEndpoint) Stats() tcpip.EndpointStats { 62 return nil 63 } 64 65 func (*fakeTransportEndpoint) SetOwner(owner tcpip.PacketOwner) {} 66 67 func (f *fakeTransportEndpoint) SocketOptions() *tcpip.SocketOptions { 68 return &f.ops 69 } 70 71 func newFakeTransportEndpoint(proto *fakeTransportProtocol, netProto tcpip.NetworkProtocolNumber, s *stack.Stack) tcpip.Endpoint { 72 ep := &fakeTransportEndpoint{TransportEndpointInfo: stack.TransportEndpointInfo{NetProto: netProto}, proto: proto, uniqueID: s.UniqueID()} 73 ep.ops.InitHandler(ep, s, tcpip.GetStackSendBufferLimits, tcpip.GetStackReceiveBufferLimits) 74 return ep 75 } 76 77 func (f *fakeTransportEndpoint) Abort() { 78 f.Close() 79 } 80 81 func (f *fakeTransportEndpoint) Close() { 82 // TODO(github.com/SagerNet/issue/5153): Consider retaining the route. 83 f.route.Release() 84 } 85 86 func (*fakeTransportEndpoint) Readiness(mask waiter.EventMask) waiter.EventMask { 87 return mask 88 } 89 90 func (*fakeTransportEndpoint) Read(io.Writer, tcpip.ReadOptions) (tcpip.ReadResult, tcpip.Error) { 91 return tcpip.ReadResult{}, nil 92 } 93 94 func (f *fakeTransportEndpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, tcpip.Error) { 95 if len(f.route.RemoteAddress()) == 0 { 96 return 0, &tcpip.ErrNoRoute{} 97 } 98 99 v := make([]byte, p.Len()) 100 if _, err := io.ReadFull(p, v); err != nil { 101 return 0, &tcpip.ErrBadBuffer{} 102 } 103 104 pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 105 ReserveHeaderBytes: int(f.route.MaxHeaderLength()) + fakeTransHeaderLen, 106 Data: buffer.View(v).ToVectorisedView(), 107 }) 108 _ = pkt.TransportHeader().Push(fakeTransHeaderLen) 109 if err := f.route.WritePacket(stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS}, pkt); err != nil { 110 return 0, err 111 } 112 113 return int64(len(v)), nil 114 } 115 116 // SetSockOpt sets a socket option. Currently not supported. 117 func (*fakeTransportEndpoint) SetSockOpt(tcpip.SettableSocketOption) tcpip.Error { 118 return &tcpip.ErrInvalidEndpointState{} 119 } 120 121 // SetSockOptInt sets a socket option. Currently not supported. 122 func (*fakeTransportEndpoint) SetSockOptInt(tcpip.SockOptInt, int) tcpip.Error { 123 return &tcpip.ErrInvalidEndpointState{} 124 } 125 126 // GetSockOptInt implements tcpip.Endpoint.GetSockOptInt. 127 func (*fakeTransportEndpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, tcpip.Error) { 128 return -1, &tcpip.ErrUnknownProtocolOption{} 129 } 130 131 // GetSockOpt implements tcpip.Endpoint.GetSockOpt. 132 func (*fakeTransportEndpoint) GetSockOpt(tcpip.GettableSocketOption) tcpip.Error { 133 return &tcpip.ErrInvalidEndpointState{} 134 } 135 136 // Disconnect implements tcpip.Endpoint.Disconnect. 137 func (*fakeTransportEndpoint) Disconnect() tcpip.Error { 138 return &tcpip.ErrNotSupported{} 139 } 140 141 func (f *fakeTransportEndpoint) Connect(addr tcpip.FullAddress) tcpip.Error { 142 f.peerAddr = addr.Addr 143 144 // Find the route. 145 r, err := f.proto.stack.FindRoute(addr.NIC, "", addr.Addr, fakeNetNumber, false /* multicastLoop */) 146 if err != nil { 147 return &tcpip.ErrNoRoute{} 148 } 149 150 // Try to register so that we can start receiving packets. 151 f.ID.RemoteAddress = addr.Addr 152 err = f.proto.stack.RegisterTransportEndpoint([]tcpip.NetworkProtocolNumber{fakeNetNumber}, fakeTransNumber, f.ID, f, ports.Flags{}, 0 /* bindToDevice */) 153 if err != nil { 154 r.Release() 155 return err 156 } 157 158 f.route = r 159 160 return nil 161 } 162 163 func (f *fakeTransportEndpoint) UniqueID() uint64 { 164 return f.uniqueID 165 } 166 167 func (*fakeTransportEndpoint) ConnectEndpoint(e tcpip.Endpoint) tcpip.Error { 168 return nil 169 } 170 171 func (*fakeTransportEndpoint) Shutdown(tcpip.ShutdownFlags) tcpip.Error { 172 return nil 173 } 174 175 func (*fakeTransportEndpoint) Reset() { 176 } 177 178 func (*fakeTransportEndpoint) Listen(int) tcpip.Error { 179 return nil 180 } 181 182 func (f *fakeTransportEndpoint) Accept(*tcpip.FullAddress) (tcpip.Endpoint, *waiter.Queue, tcpip.Error) { 183 if len(f.acceptQueue) == 0 { 184 return nil, nil, nil 185 } 186 a := f.acceptQueue[0] 187 f.acceptQueue = f.acceptQueue[1:] 188 return a, nil, nil 189 } 190 191 func (f *fakeTransportEndpoint) Bind(a tcpip.FullAddress) tcpip.Error { 192 if err := f.proto.stack.RegisterTransportEndpoint( 193 []tcpip.NetworkProtocolNumber{fakeNetNumber}, 194 fakeTransNumber, 195 stack.TransportEndpointID{LocalAddress: a.Addr}, 196 f, 197 ports.Flags{}, 198 0, /* bindtoDevice */ 199 ); err != nil { 200 return err 201 } 202 f.acceptQueue = []*fakeTransportEndpoint{} 203 return nil 204 } 205 206 func (*fakeTransportEndpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) { 207 return tcpip.FullAddress{}, nil 208 } 209 210 func (*fakeTransportEndpoint) GetRemoteAddress() (tcpip.FullAddress, tcpip.Error) { 211 return tcpip.FullAddress{}, nil 212 } 213 214 func (f *fakeTransportEndpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketBuffer) { 215 // Increment the number of received packets. 216 f.proto.packetCount++ 217 if f.acceptQueue == nil { 218 return 219 } 220 221 netHdr := pkt.NetworkHeader().View() 222 route, err := f.proto.stack.FindRoute(pkt.NICID, tcpip.Address(netHdr[dstAddrOffset]), tcpip.Address(netHdr[srcAddrOffset]), pkt.NetworkProtocolNumber, false /* multicastLoop */) 223 if err != nil { 224 return 225 } 226 227 ep := &fakeTransportEndpoint{ 228 TransportEndpointInfo: stack.TransportEndpointInfo{ 229 ID: f.ID, 230 NetProto: f.NetProto, 231 }, 232 proto: f.proto, 233 peerAddr: route.RemoteAddress(), 234 route: route, 235 } 236 ep.ops.InitHandler(ep, f.proto.stack, tcpip.GetStackSendBufferLimits, tcpip.GetStackReceiveBufferLimits) 237 f.acceptQueue = append(f.acceptQueue, ep) 238 } 239 240 func (f *fakeTransportEndpoint) HandleError(stack.TransportError, *stack.PacketBuffer) { 241 // Increment the number of received control packets. 242 f.proto.controlCount++ 243 } 244 245 func (*fakeTransportEndpoint) State() uint32 { 246 return 0 247 } 248 249 func (*fakeTransportEndpoint) ModerateRecvBuf(copied int) {} 250 251 func (*fakeTransportEndpoint) Resume(*stack.Stack) {} 252 253 func (*fakeTransportEndpoint) Wait() {} 254 255 func (*fakeTransportEndpoint) LastError() tcpip.Error { 256 return nil 257 } 258 259 type fakeTransportGoodOption bool 260 261 type fakeTransportBadOption bool 262 263 type fakeTransportInvalidValueOption int 264 265 type fakeTransportProtocolOptions struct { 266 good bool 267 } 268 269 // fakeTransportProtocol is a transport-layer protocol descriptor. It 270 // aggregates the number of packets received via endpoints of this protocol. 271 type fakeTransportProtocol struct { 272 stack *stack.Stack 273 274 packetCount int 275 controlCount int 276 opts fakeTransportProtocolOptions 277 } 278 279 func (*fakeTransportProtocol) Number() tcpip.TransportProtocolNumber { 280 return fakeTransNumber 281 } 282 283 func (f *fakeTransportProtocol) NewEndpoint(netProto tcpip.NetworkProtocolNumber, _ *waiter.Queue) (tcpip.Endpoint, tcpip.Error) { 284 return newFakeTransportEndpoint(f, netProto, f.stack), nil 285 } 286 287 func (*fakeTransportProtocol) NewRawEndpoint(tcpip.NetworkProtocolNumber, *waiter.Queue) (tcpip.Endpoint, tcpip.Error) { 288 return nil, &tcpip.ErrUnknownProtocol{} 289 } 290 291 func (*fakeTransportProtocol) MinimumPacketSize() int { 292 return fakeTransHeaderLen 293 } 294 295 func (*fakeTransportProtocol) ParsePorts(buffer.View) (src, dst uint16, err tcpip.Error) { 296 return 0, 0, nil 297 } 298 299 func (*fakeTransportProtocol) HandleUnknownDestinationPacket(stack.TransportEndpointID, *stack.PacketBuffer) stack.UnknownDestinationPacketDisposition { 300 return stack.UnknownDestinationPacketHandled 301 } 302 303 func (f *fakeTransportProtocol) SetOption(option tcpip.SettableTransportProtocolOption) tcpip.Error { 304 switch v := option.(type) { 305 case *tcpip.TCPModerateReceiveBufferOption: 306 f.opts.good = bool(*v) 307 return nil 308 default: 309 return &tcpip.ErrUnknownProtocolOption{} 310 } 311 } 312 313 func (f *fakeTransportProtocol) Option(option tcpip.GettableTransportProtocolOption) tcpip.Error { 314 switch v := option.(type) { 315 case *tcpip.TCPModerateReceiveBufferOption: 316 *v = tcpip.TCPModerateReceiveBufferOption(f.opts.good) 317 return nil 318 default: 319 return &tcpip.ErrUnknownProtocolOption{} 320 } 321 } 322 323 // Abort implements TransportProtocol.Abort. 324 func (*fakeTransportProtocol) Abort() {} 325 326 // Close implements tcpip.Endpoint.Close. 327 func (*fakeTransportProtocol) Close() {} 328 329 // Wait implements TransportProtocol.Wait. 330 func (*fakeTransportProtocol) Wait() {} 331 332 // Parse implements TransportProtocol.Parse. 333 func (*fakeTransportProtocol) Parse(pkt *stack.PacketBuffer) bool { 334 _, ok := pkt.TransportHeader().Consume(fakeTransHeaderLen) 335 return ok 336 } 337 338 func fakeTransFactory(s *stack.Stack) stack.TransportProtocol { 339 return &fakeTransportProtocol{stack: s} 340 } 341 342 func TestTransportReceive(t *testing.T) { 343 linkEP := channel.New(10, defaultMTU, "") 344 s := stack.New(stack.Options{ 345 NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory}, 346 TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory}, 347 }) 348 if err := s.CreateNIC(1, linkEP); err != nil { 349 t.Fatalf("CreateNIC failed: %v", err) 350 } 351 352 { 353 subnet, err := tcpip.NewSubnet("\x00", "\x00") 354 if err != nil { 355 t.Fatal(err) 356 } 357 s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}}) 358 } 359 360 if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { 361 t.Fatalf("AddAddress failed: %v", err) 362 } 363 364 // Create endpoint and connect to remote address. 365 wq := waiter.Queue{} 366 ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq) 367 if err != nil { 368 t.Fatalf("NewEndpoint failed: %v", err) 369 } 370 371 if err := ep.Connect(tcpip.FullAddress{0, "\x02", 0}); err != nil { 372 t.Fatalf("Connect failed: %v", err) 373 } 374 375 fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol) 376 377 // Create buffer that will hold the packet. 378 buf := buffer.NewView(30) 379 380 // Make sure packet with wrong protocol is not delivered. 381 buf[0] = 1 382 buf[2] = 0 383 linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ 384 Data: buf.ToVectorisedView(), 385 })) 386 if fakeTrans.packetCount != 0 { 387 t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0) 388 } 389 390 // Make sure packet from the wrong source is not delivered. 391 buf[0] = 1 392 buf[1] = 3 393 buf[2] = byte(fakeTransNumber) 394 linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ 395 Data: buf.ToVectorisedView(), 396 })) 397 if fakeTrans.packetCount != 0 { 398 t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0) 399 } 400 401 // Make sure packet is delivered. 402 buf[0] = 1 403 buf[1] = 2 404 buf[2] = byte(fakeTransNumber) 405 linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ 406 Data: buf.ToVectorisedView(), 407 })) 408 if fakeTrans.packetCount != 1 { 409 t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 1) 410 } 411 } 412 413 func TestTransportControlReceive(t *testing.T) { 414 linkEP := channel.New(10, defaultMTU, "") 415 s := stack.New(stack.Options{ 416 NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory}, 417 TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory}, 418 }) 419 if err := s.CreateNIC(1, linkEP); err != nil { 420 t.Fatalf("CreateNIC failed: %v", err) 421 } 422 423 { 424 subnet, err := tcpip.NewSubnet("\x00", "\x00") 425 if err != nil { 426 t.Fatal(err) 427 } 428 s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}}) 429 } 430 431 if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { 432 t.Fatalf("AddAddress failed: %v", err) 433 } 434 435 // Create endpoint and connect to remote address. 436 wq := waiter.Queue{} 437 ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq) 438 if err != nil { 439 t.Fatalf("NewEndpoint failed: %v", err) 440 } 441 442 if err := ep.Connect(tcpip.FullAddress{0, "\x02", 0}); err != nil { 443 t.Fatalf("Connect failed: %v", err) 444 } 445 446 fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol) 447 448 // Create buffer that will hold the control packet. 449 buf := buffer.NewView(2*fakeNetHeaderLen + 30) 450 451 // Outer packet contains the control protocol number. 452 buf[0] = 1 453 buf[1] = 0xfe 454 buf[2] = uint8(fakeControlProtocol) 455 456 // Make sure packet with wrong protocol is not delivered. 457 buf[fakeNetHeaderLen+0] = 0 458 buf[fakeNetHeaderLen+1] = 1 459 buf[fakeNetHeaderLen+2] = 0 460 linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ 461 Data: buf.ToVectorisedView(), 462 })) 463 if fakeTrans.controlCount != 0 { 464 t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0) 465 } 466 467 // Make sure packet from the wrong source is not delivered. 468 buf[fakeNetHeaderLen+0] = 3 469 buf[fakeNetHeaderLen+1] = 1 470 buf[fakeNetHeaderLen+2] = byte(fakeTransNumber) 471 linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ 472 Data: buf.ToVectorisedView(), 473 })) 474 if fakeTrans.controlCount != 0 { 475 t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0) 476 } 477 478 // Make sure packet is delivered. 479 buf[fakeNetHeaderLen+0] = 2 480 buf[fakeNetHeaderLen+1] = 1 481 buf[fakeNetHeaderLen+2] = byte(fakeTransNumber) 482 linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ 483 Data: buf.ToVectorisedView(), 484 })) 485 if fakeTrans.controlCount != 1 { 486 t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 1) 487 } 488 } 489 490 func TestTransportSend(t *testing.T) { 491 linkEP := channel.New(10, defaultMTU, "") 492 s := stack.New(stack.Options{ 493 NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory}, 494 TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory}, 495 }) 496 if err := s.CreateNIC(1, linkEP); err != nil { 497 t.Fatalf("CreateNIC failed: %v", err) 498 } 499 500 if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { 501 t.Fatalf("AddAddress failed: %v", err) 502 } 503 504 { 505 subnet, err := tcpip.NewSubnet("\x00", "\x00") 506 if err != nil { 507 t.Fatal(err) 508 } 509 s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}}) 510 } 511 512 // Create endpoint and bind it. 513 wq := waiter.Queue{} 514 ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq) 515 if err != nil { 516 t.Fatalf("NewEndpoint failed: %v", err) 517 } 518 519 if err := ep.Connect(tcpip.FullAddress{0, "\x02", 0}); err != nil { 520 t.Fatalf("Connect failed: %v", err) 521 } 522 523 // Create buffer that will hold the payload. 524 b := make([]byte, 30) 525 var r bytes.Reader 526 r.Reset(b) 527 if _, err := ep.Write(&r, tcpip.WriteOptions{}); err != nil { 528 t.Fatalf("write failed: %v", err) 529 } 530 531 fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) 532 533 if fakeNet.sendPacketCount[2] != 1 { 534 t.Errorf("sendPacketCount = %d, want %d", fakeNet.sendPacketCount[2], 1) 535 } 536 } 537 538 func TestTransportOptions(t *testing.T) { 539 s := stack.New(stack.Options{ 540 NetworkProtocols: []stack.NetworkProtocolFactory{fakeNetFactory}, 541 TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory}, 542 }) 543 544 v := tcpip.TCPModerateReceiveBufferOption(true) 545 if err := s.SetTransportProtocolOption(fakeTransNumber, &v); err != nil { 546 t.Errorf("s.SetTransportProtocolOption(fakeTrans, &%T(%t)): %s", v, v, err) 547 } 548 v = false 549 if err := s.TransportProtocolOption(fakeTransNumber, &v); err != nil { 550 t.Fatalf("s.TransportProtocolOption(fakeTransNumber, &%T): %s", v, err) 551 } 552 if !v { 553 t.Fatalf("got tcpip.TCPModerateReceiveBufferOption = false, want = true") 554 } 555 }