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