inet.af/netstack@v0.0.0-20220214151720-7585b01ddccf/tcpip/transport/icmp/endpoint.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 icmp 16 17 import ( 18 "fmt" 19 "io" 20 "time" 21 22 "inet.af/netstack/sync" 23 "inet.af/netstack/tcpip" 24 "inet.af/netstack/tcpip/buffer" 25 "inet.af/netstack/tcpip/header" 26 "inet.af/netstack/tcpip/ports" 27 "inet.af/netstack/tcpip/stack" 28 "inet.af/netstack/tcpip/transport" 29 "inet.af/netstack/tcpip/transport/internal/network" 30 "inet.af/netstack/waiter" 31 ) 32 33 // +stateify savable 34 type icmpPacket struct { 35 icmpPacketEntry 36 senderAddress tcpip.FullAddress 37 data buffer.VectorisedView `state:".(buffer.VectorisedView)"` 38 receivedAt time.Time `state:".(int64)"` 39 } 40 41 // endpoint represents an ICMP endpoint. This struct serves as the interface 42 // between users of the endpoint and the protocol implementation; it is legal to 43 // have concurrent goroutines make calls into the endpoint, they are properly 44 // synchronized. 45 // 46 // +stateify savable 47 type endpoint struct { 48 tcpip.DefaultSocketOptionsHandler 49 50 // The following fields are initialized at creation time and are 51 // immutable. 52 stack *stack.Stack `state:"manual"` 53 transProto tcpip.TransportProtocolNumber 54 waiterQueue *waiter.Queue 55 uniqueID uint64 56 net network.Endpoint 57 stats tcpip.TransportEndpointStats 58 ops tcpip.SocketOptions 59 60 // The following fields are used to manage the receive queue, and are 61 // protected by rcvMu. 62 rcvMu sync.Mutex `state:"nosave"` 63 rcvReady bool 64 rcvList icmpPacketList 65 rcvBufSize int 66 rcvClosed bool 67 68 // The following fields are protected by the mu mutex. 69 mu sync.RWMutex `state:"nosave"` 70 // frozen indicates if the packets should be delivered to the endpoint 71 // during restore. 72 frozen bool 73 ident uint16 74 } 75 76 func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, tcpip.Error) { 77 ep := &endpoint{ 78 stack: s, 79 transProto: transProto, 80 waiterQueue: waiterQueue, 81 uniqueID: s.UniqueID(), 82 } 83 ep.ops.InitHandler(ep, ep.stack, tcpip.GetStackSendBufferLimits, tcpip.GetStackReceiveBufferLimits) 84 ep.ops.SetSendBufferSize(32*1024, false /* notify */) 85 ep.ops.SetReceiveBufferSize(32*1024, false /* notify */) 86 ep.net.Init(s, netProto, transProto, &ep.ops) 87 88 // Override with stack defaults. 89 var ss tcpip.SendBufferSizeOption 90 if err := s.Option(&ss); err == nil { 91 ep.ops.SetSendBufferSize(int64(ss.Default), false /* notify */) 92 } 93 var rs tcpip.ReceiveBufferSizeOption 94 if err := s.Option(&rs); err == nil { 95 ep.ops.SetReceiveBufferSize(int64(rs.Default), false /* notify */) 96 } 97 return ep, nil 98 } 99 100 // UniqueID implements stack.TransportEndpoint.UniqueID. 101 func (e *endpoint) UniqueID() uint64 { 102 return e.uniqueID 103 } 104 105 // Abort implements stack.TransportEndpoint.Abort. 106 func (e *endpoint) Abort() { 107 e.Close() 108 } 109 110 // Close puts the endpoint in a closed state and frees all resources 111 // associated with it. 112 func (e *endpoint) Close() { 113 notify := func() bool { 114 e.mu.Lock() 115 defer e.mu.Unlock() 116 117 switch state := e.net.State(); state { 118 case transport.DatagramEndpointStateInitial: 119 case transport.DatagramEndpointStateClosed: 120 return false 121 case transport.DatagramEndpointStateBound, transport.DatagramEndpointStateConnected: 122 info := e.net.Info() 123 info.ID.LocalPort = e.ident 124 e.stack.UnregisterTransportEndpoint([]tcpip.NetworkProtocolNumber{info.NetProto}, e.transProto, info.ID, e, ports.Flags{}, tcpip.NICID(e.ops.GetBindToDevice())) 125 default: 126 panic(fmt.Sprintf("unhandled state = %s", state)) 127 } 128 129 e.net.Shutdown() 130 e.net.Close() 131 132 e.rcvMu.Lock() 133 defer e.rcvMu.Unlock() 134 e.rcvClosed = true 135 e.rcvBufSize = 0 136 for !e.rcvList.Empty() { 137 p := e.rcvList.Front() 138 e.rcvList.Remove(p) 139 } 140 141 return true 142 }() 143 144 if notify { 145 e.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.ReadableEvents | waiter.WritableEvents) 146 } 147 } 148 149 // ModerateRecvBuf implements tcpip.Endpoint.ModerateRecvBuf. 150 func (*endpoint) ModerateRecvBuf(int) {} 151 152 // SetOwner implements tcpip.Endpoint.SetOwner. 153 func (e *endpoint) SetOwner(owner tcpip.PacketOwner) { 154 e.net.SetOwner(owner) 155 } 156 157 // Read implements tcpip.Endpoint.Read. 158 func (e *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResult, tcpip.Error) { 159 e.rcvMu.Lock() 160 161 if e.rcvList.Empty() { 162 var err tcpip.Error = &tcpip.ErrWouldBlock{} 163 if e.rcvClosed { 164 e.stats.ReadErrors.ReadClosed.Increment() 165 err = &tcpip.ErrClosedForReceive{} 166 } 167 e.rcvMu.Unlock() 168 return tcpip.ReadResult{}, err 169 } 170 171 p := e.rcvList.Front() 172 if !opts.Peek { 173 e.rcvList.Remove(p) 174 e.rcvBufSize -= p.data.Size() 175 } 176 177 e.rcvMu.Unlock() 178 179 res := tcpip.ReadResult{ 180 Total: p.data.Size(), 181 ControlMessages: tcpip.ControlMessages{ 182 HasTimestamp: true, 183 Timestamp: p.receivedAt, 184 }, 185 } 186 if opts.NeedRemoteAddr { 187 res.RemoteAddr = p.senderAddress 188 } 189 190 n, err := p.data.ReadTo(dst, opts.Peek) 191 if n == 0 && err != nil { 192 return res, &tcpip.ErrBadBuffer{} 193 } 194 res.Count = n 195 return res, nil 196 } 197 198 // prepareForWrite prepares the endpoint for sending data. In particular, it 199 // binds it if it's still in the initial state. To do so, it must first 200 // reacquire the mutex in exclusive mode. 201 // 202 // Returns true for retry if preparation should be retried. 203 // +checklocksread:e.mu 204 func (e *endpoint) prepareForWriteInner(to *tcpip.FullAddress) (retry bool, err tcpip.Error) { 205 switch e.net.State() { 206 case transport.DatagramEndpointStateInitial: 207 case transport.DatagramEndpointStateConnected: 208 return false, nil 209 case transport.DatagramEndpointStateBound: 210 if to == nil { 211 return false, &tcpip.ErrDestinationRequired{} 212 } 213 return false, nil 214 default: 215 return false, &tcpip.ErrInvalidEndpointState{} 216 } 217 218 e.mu.RUnlock() 219 e.mu.Lock() 220 defer e.mu.DowngradeLock() 221 222 // The state changed when we released the shared locked and re-acquired 223 // it in exclusive mode. Try again. 224 if e.net.State() != transport.DatagramEndpointStateInitial { 225 return true, nil 226 } 227 228 // The state is still 'initial', so try to bind the endpoint. 229 if err := e.bindLocked(tcpip.FullAddress{}); err != nil { 230 return false, err 231 } 232 233 return true, nil 234 } 235 236 // Write writes data to the endpoint's peer. This method does not block 237 // if the data cannot be written. 238 func (e *endpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, tcpip.Error) { 239 n, err := e.write(p, opts) 240 switch err.(type) { 241 case nil: 242 e.stats.PacketsSent.Increment() 243 case *tcpip.ErrMessageTooLong, *tcpip.ErrInvalidOptionValue: 244 e.stats.WriteErrors.InvalidArgs.Increment() 245 case *tcpip.ErrClosedForSend: 246 e.stats.WriteErrors.WriteClosed.Increment() 247 case *tcpip.ErrInvalidEndpointState: 248 e.stats.WriteErrors.InvalidEndpointState.Increment() 249 case *tcpip.ErrNoRoute, *tcpip.ErrBroadcastDisabled, *tcpip.ErrNetworkUnreachable: 250 // Errors indicating any problem with IP routing of the packet. 251 e.stats.SendErrors.NoRoute.Increment() 252 default: 253 // For all other errors when writing to the network layer. 254 e.stats.SendErrors.SendToNetworkFailed.Increment() 255 } 256 return n, err 257 } 258 259 func (e *endpoint) prepareForWrite(opts tcpip.WriteOptions) (network.WriteContext, uint16, tcpip.Error) { 260 e.mu.RLock() 261 defer e.mu.RUnlock() 262 263 // Prepare for write. 264 for { 265 retry, err := e.prepareForWriteInner(opts.To) 266 if err != nil { 267 return network.WriteContext{}, 0, err 268 } 269 270 if !retry { 271 break 272 } 273 } 274 275 ctx, err := e.net.AcquireContextForWrite(opts) 276 return ctx, e.ident, err 277 } 278 279 func (e *endpoint) write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, tcpip.Error) { 280 ctx, ident, err := e.prepareForWrite(opts) 281 if err != nil { 282 return 0, err 283 } 284 defer ctx.Release() 285 286 // TODO(https://gvisor.dev/issue/6538): Avoid this allocation. 287 v := make([]byte, p.Len()) 288 if _, err := io.ReadFull(p, v); err != nil { 289 return 0, &tcpip.ErrBadBuffer{} 290 } 291 292 switch netProto, pktInfo := e.net.NetProto(), ctx.PacketInfo(); netProto { 293 case header.IPv4ProtocolNumber: 294 if err := send4(e.stack, &ctx, ident, v, pktInfo.MaxHeaderLength); err != nil { 295 return 0, err 296 } 297 298 case header.IPv6ProtocolNumber: 299 if err := send6(e.stack, &ctx, ident, v, pktInfo.LocalAddress, pktInfo.RemoteAddress, pktInfo.MaxHeaderLength); err != nil { 300 return 0, err 301 } 302 default: 303 panic(fmt.Sprintf("unhandled network protocol = %d", netProto)) 304 } 305 306 return int64(len(v)), nil 307 } 308 309 var _ tcpip.SocketOptionsHandler = (*endpoint)(nil) 310 311 // HasNIC implements tcpip.SocketOptionsHandler. 312 func (e *endpoint) HasNIC(id int32) bool { 313 return e.stack.HasNIC(tcpip.NICID(id)) 314 } 315 316 // SetSockOpt implements tcpip.Endpoint. 317 func (e *endpoint) SetSockOpt(opt tcpip.SettableSocketOption) tcpip.Error { 318 return e.net.SetSockOpt(opt) 319 } 320 321 // SetSockOptInt implements tcpip.Endpoint. 322 func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) tcpip.Error { 323 return e.net.SetSockOptInt(opt, v) 324 } 325 326 // GetSockOptInt implements tcpip.Endpoint. 327 func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, tcpip.Error) { 328 switch opt { 329 case tcpip.ReceiveQueueSizeOption: 330 v := 0 331 e.rcvMu.Lock() 332 if !e.rcvList.Empty() { 333 p := e.rcvList.Front() 334 v = p.data.Size() 335 } 336 e.rcvMu.Unlock() 337 return v, nil 338 339 default: 340 return e.net.GetSockOptInt(opt) 341 } 342 } 343 344 // GetSockOpt implements tcpip.Endpoint. 345 func (e *endpoint) GetSockOpt(opt tcpip.GettableSocketOption) tcpip.Error { 346 return e.net.GetSockOpt(opt) 347 } 348 349 func send4(s *stack.Stack, ctx *network.WriteContext, ident uint16, data buffer.View, maxHeaderLength uint16) tcpip.Error { 350 if len(data) < header.ICMPv4MinimumSize { 351 return &tcpip.ErrInvalidEndpointState{} 352 } 353 354 pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 355 ReserveHeaderBytes: header.ICMPv4MinimumSize + int(maxHeaderLength), 356 }) 357 defer pkt.DecRef() 358 359 icmpv4 := header.ICMPv4(pkt.TransportHeader().Push(header.ICMPv4MinimumSize)) 360 pkt.TransportProtocolNumber = header.ICMPv4ProtocolNumber 361 copy(icmpv4, data) 362 // Set the ident to the user-specified port. Sequence number should 363 // already be set by the user. 364 icmpv4.SetIdent(ident) 365 data = data[header.ICMPv4MinimumSize:] 366 367 // Linux performs these basic checks. 368 if icmpv4.Type() != header.ICMPv4Echo || icmpv4.Code() != 0 { 369 return &tcpip.ErrInvalidEndpointState{} 370 } 371 372 icmpv4.SetChecksum(0) 373 icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) 374 pkt.Data().AppendView(data) 375 376 // Because this icmp endpoint is implemented in the transport layer, we can 377 // only increment the 'stack-wide' stats but we can't increment the 378 // 'per-NetworkEndpoint' stats. 379 stats := s.Stats().ICMP.V4.PacketsSent 380 381 if err := ctx.WritePacket(pkt, false /* headerIncluded */); err != nil { 382 stats.Dropped.Increment() 383 return err 384 } 385 386 stats.EchoRequest.Increment() 387 return nil 388 } 389 390 func send6(s *stack.Stack, ctx *network.WriteContext, ident uint16, data buffer.View, src, dst tcpip.Address, maxHeaderLength uint16) tcpip.Error { 391 if len(data) < header.ICMPv6EchoMinimumSize { 392 return &tcpip.ErrInvalidEndpointState{} 393 } 394 395 pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ 396 ReserveHeaderBytes: header.ICMPv6MinimumSize + int(maxHeaderLength), 397 }) 398 defer pkt.DecRef() 399 400 icmpv6 := header.ICMPv6(pkt.TransportHeader().Push(header.ICMPv6MinimumSize)) 401 pkt.TransportProtocolNumber = header.ICMPv6ProtocolNumber 402 copy(icmpv6, data) 403 // Set the ident. Sequence number is provided by the user. 404 icmpv6.SetIdent(ident) 405 data = data[header.ICMPv6MinimumSize:] 406 407 if icmpv6.Type() != header.ICMPv6EchoRequest || icmpv6.Code() != 0 { 408 return &tcpip.ErrInvalidEndpointState{} 409 } 410 411 pkt.Data().AppendView(data) 412 dataRange := pkt.Data().AsRange() 413 icmpv6.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{ 414 Header: icmpv6, 415 Src: src, 416 Dst: dst, 417 PayloadCsum: dataRange.Checksum(), 418 PayloadLen: dataRange.Size(), 419 })) 420 421 // Because this icmp endpoint is implemented in the transport layer, we can 422 // only increment the 'stack-wide' stats but we can't increment the 423 // 'per-NetworkEndpoint' stats. 424 stats := s.Stats().ICMP.V6.PacketsSent 425 426 if err := ctx.WritePacket(pkt, false /* headerIncluded */); err != nil { 427 stats.Dropped.Increment() 428 return err 429 } 430 431 stats.EchoRequest.Increment() 432 return nil 433 } 434 435 // Disconnect implements tcpip.Endpoint.Disconnect. 436 func (*endpoint) Disconnect() tcpip.Error { 437 return &tcpip.ErrNotSupported{} 438 } 439 440 // Connect connects the endpoint to its peer. Specifying a NIC is optional. 441 func (e *endpoint) Connect(addr tcpip.FullAddress) tcpip.Error { 442 e.mu.Lock() 443 defer e.mu.Unlock() 444 445 err := e.net.ConnectAndThen(addr, func(netProto tcpip.NetworkProtocolNumber, previousID, nextID stack.TransportEndpointID) tcpip.Error { 446 nextID.LocalPort = e.ident 447 448 nextID, err := e.registerWithStack(netProto, nextID) 449 if err != nil { 450 return err 451 } 452 453 e.ident = nextID.LocalPort 454 return nil 455 }) 456 if err != nil { 457 return err 458 } 459 460 e.rcvMu.Lock() 461 e.rcvReady = true 462 e.rcvMu.Unlock() 463 464 return nil 465 } 466 467 // ConnectEndpoint is not supported. 468 func (*endpoint) ConnectEndpoint(tcpip.Endpoint) tcpip.Error { 469 return &tcpip.ErrInvalidEndpointState{} 470 } 471 472 // Shutdown closes the read and/or write end of the endpoint connection 473 // to its peer. 474 func (e *endpoint) Shutdown(flags tcpip.ShutdownFlags) tcpip.Error { 475 e.mu.Lock() 476 defer e.mu.Unlock() 477 478 switch state := e.net.State(); state { 479 case transport.DatagramEndpointStateInitial, transport.DatagramEndpointStateClosed: 480 return &tcpip.ErrNotConnected{} 481 case transport.DatagramEndpointStateBound, transport.DatagramEndpointStateConnected: 482 default: 483 panic(fmt.Sprintf("unhandled state = %s", state)) 484 } 485 486 if flags&tcpip.ShutdownWrite != 0 { 487 if err := e.net.Shutdown(); err != nil { 488 return err 489 } 490 } 491 492 if flags&tcpip.ShutdownRead != 0 { 493 e.rcvMu.Lock() 494 wasClosed := e.rcvClosed 495 e.rcvClosed = true 496 e.rcvMu.Unlock() 497 498 if !wasClosed { 499 e.waiterQueue.Notify(waiter.ReadableEvents) 500 } 501 } 502 503 return nil 504 } 505 506 // Listen is not supported by UDP, it just fails. 507 func (*endpoint) Listen(int) tcpip.Error { 508 return &tcpip.ErrNotSupported{} 509 } 510 511 // Accept is not supported by UDP, it just fails. 512 func (*endpoint) Accept(*tcpip.FullAddress) (tcpip.Endpoint, *waiter.Queue, tcpip.Error) { 513 return nil, nil, &tcpip.ErrNotSupported{} 514 } 515 516 func (e *endpoint) registerWithStack(netProto tcpip.NetworkProtocolNumber, id stack.TransportEndpointID) (stack.TransportEndpointID, tcpip.Error) { 517 bindToDevice := tcpip.NICID(e.ops.GetBindToDevice()) 518 if id.LocalPort != 0 { 519 // The endpoint already has a local port, just attempt to 520 // register it. 521 return id, e.stack.RegisterTransportEndpoint([]tcpip.NetworkProtocolNumber{netProto}, e.transProto, id, e, ports.Flags{}, bindToDevice) 522 } 523 524 // We need to find a port for the endpoint. 525 _, err := e.stack.PickEphemeralPort(e.stack.Rand(), func(p uint16) (bool, tcpip.Error) { 526 id.LocalPort = p 527 err := e.stack.RegisterTransportEndpoint([]tcpip.NetworkProtocolNumber{netProto}, e.transProto, id, e, ports.Flags{}, bindToDevice) 528 switch err.(type) { 529 case nil: 530 return true, nil 531 case *tcpip.ErrPortInUse: 532 return false, nil 533 default: 534 return false, err 535 } 536 }) 537 538 return id, err 539 } 540 541 func (e *endpoint) bindLocked(addr tcpip.FullAddress) tcpip.Error { 542 // Don't allow binding once endpoint is not in the initial state 543 // anymore. 544 if e.net.State() != transport.DatagramEndpointStateInitial { 545 return &tcpip.ErrInvalidEndpointState{} 546 } 547 548 err := e.net.BindAndThen(addr, func(boundNetProto tcpip.NetworkProtocolNumber, boundAddr tcpip.Address) tcpip.Error { 549 id := stack.TransportEndpointID{ 550 LocalPort: addr.Port, 551 LocalAddress: addr.Addr, 552 } 553 id, err := e.registerWithStack(boundNetProto, id) 554 if err != nil { 555 return err 556 } 557 558 e.ident = id.LocalPort 559 return nil 560 }) 561 if err != nil { 562 return err 563 } 564 565 e.rcvMu.Lock() 566 e.rcvReady = true 567 e.rcvMu.Unlock() 568 569 return nil 570 } 571 572 func (e *endpoint) isBroadcastOrMulticast(nicID tcpip.NICID, addr tcpip.Address) bool { 573 return addr == header.IPv4Broadcast || 574 header.IsV4MulticastAddress(addr) || 575 header.IsV6MulticastAddress(addr) || 576 e.stack.IsSubnetBroadcast(nicID, e.net.NetProto(), addr) 577 } 578 579 // Bind binds the endpoint to a specific local address and port. 580 // Specifying a NIC is optional. 581 func (e *endpoint) Bind(addr tcpip.FullAddress) tcpip.Error { 582 if len(addr.Addr) != 0 && e.isBroadcastOrMulticast(addr.NIC, addr.Addr) { 583 return &tcpip.ErrBadLocalAddress{} 584 } 585 586 e.mu.Lock() 587 defer e.mu.Unlock() 588 589 return e.bindLocked(addr) 590 } 591 592 // GetLocalAddress returns the address to which the endpoint is bound. 593 func (e *endpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) { 594 e.mu.RLock() 595 defer e.mu.RUnlock() 596 597 addr := e.net.GetLocalAddress() 598 addr.Port = e.ident 599 return addr, nil 600 } 601 602 // GetRemoteAddress returns the address to which the endpoint is connected. 603 func (e *endpoint) GetRemoteAddress() (tcpip.FullAddress, tcpip.Error) { 604 e.mu.RLock() 605 defer e.mu.RUnlock() 606 607 if addr, connected := e.net.GetRemoteAddress(); connected { 608 return addr, nil 609 } 610 611 return tcpip.FullAddress{}, &tcpip.ErrNotConnected{} 612 } 613 614 // Readiness returns the current readiness of the endpoint. For example, if 615 // waiter.EventIn is set, the endpoint is immediately readable. 616 func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { 617 // The endpoint is always writable. 618 result := waiter.WritableEvents & mask 619 620 // Determine if the endpoint is readable if requested. 621 if (mask & waiter.ReadableEvents) != 0 { 622 e.rcvMu.Lock() 623 if !e.rcvList.Empty() || e.rcvClosed { 624 result |= waiter.ReadableEvents 625 } 626 e.rcvMu.Unlock() 627 } 628 629 return result 630 } 631 632 // HandlePacket is called by the stack when new packets arrive to this transport 633 // endpoint. 634 func (e *endpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketBuffer) { 635 // Only accept echo replies. 636 switch e.net.NetProto() { 637 case header.IPv4ProtocolNumber: 638 h := header.ICMPv4(pkt.TransportHeader().View()) 639 if len(h) < header.ICMPv4MinimumSize || h.Type() != header.ICMPv4EchoReply { 640 e.stack.Stats().DroppedPackets.Increment() 641 e.stats.ReceiveErrors.MalformedPacketsReceived.Increment() 642 return 643 } 644 case header.IPv6ProtocolNumber: 645 h := header.ICMPv6(pkt.TransportHeader().View()) 646 if len(h) < header.ICMPv6MinimumSize || h.Type() != header.ICMPv6EchoReply { 647 e.stack.Stats().DroppedPackets.Increment() 648 e.stats.ReceiveErrors.MalformedPacketsReceived.Increment() 649 return 650 } 651 } 652 653 e.rcvMu.Lock() 654 655 // Drop the packet if our buffer is currently full. 656 if !e.rcvReady || e.rcvClosed { 657 e.rcvMu.Unlock() 658 e.stack.Stats().DroppedPackets.Increment() 659 e.stats.ReceiveErrors.ClosedReceiver.Increment() 660 return 661 } 662 663 rcvBufSize := e.ops.GetReceiveBufferSize() 664 if e.frozen || e.rcvBufSize >= int(rcvBufSize) { 665 e.rcvMu.Unlock() 666 e.stack.Stats().DroppedPackets.Increment() 667 e.stats.ReceiveErrors.ReceiveBufferOverflow.Increment() 668 return 669 } 670 671 wasEmpty := e.rcvBufSize == 0 672 673 // Push new packet into receive list and increment the buffer size. 674 packet := &icmpPacket{ 675 senderAddress: tcpip.FullAddress{ 676 NIC: pkt.NICID, 677 Addr: id.RemoteAddress, 678 }, 679 } 680 681 // ICMP socket's data includes ICMP header. 682 packet.data = pkt.TransportHeader().View().ToVectorisedView() 683 packet.data.Append(pkt.Data().ExtractVV()) 684 685 e.rcvList.PushBack(packet) 686 e.rcvBufSize += packet.data.Size() 687 688 packet.receivedAt = e.stack.Clock().Now() 689 690 e.rcvMu.Unlock() 691 e.stats.PacketsReceived.Increment() 692 // Notify any waiters that there's data to be read now. 693 if wasEmpty { 694 e.waiterQueue.Notify(waiter.ReadableEvents) 695 } 696 } 697 698 // HandleError implements stack.TransportEndpoint. 699 func (*endpoint) HandleError(stack.TransportError, *stack.PacketBuffer) {} 700 701 // State implements tcpip.Endpoint.State. The ICMP endpoint currently doesn't 702 // expose internal socket state. 703 func (e *endpoint) State() uint32 { 704 return 0 705 } 706 707 // Info returns a copy of the endpoint info. 708 func (e *endpoint) Info() tcpip.EndpointInfo { 709 e.mu.RLock() 710 defer e.mu.RUnlock() 711 ret := e.net.Info() 712 ret.ID.LocalPort = e.ident 713 return &ret 714 } 715 716 // Stats returns a pointer to the endpoint stats. 717 func (e *endpoint) Stats() tcpip.EndpointStats { 718 return &e.stats 719 } 720 721 // Wait implements stack.TransportEndpoint.Wait. 722 func (*endpoint) Wait() {} 723 724 // LastError implements tcpip.Endpoint.LastError. 725 func (*endpoint) LastError() tcpip.Error { 726 return nil 727 } 728 729 // SocketOptions implements tcpip.Endpoint.SocketOptions. 730 func (e *endpoint) SocketOptions() *tcpip.SocketOptions { 731 return &e.ops 732 } 733 734 // freeze prevents any more packets from being delivered to the endpoint. 735 func (e *endpoint) freeze() { 736 e.mu.Lock() 737 e.frozen = true 738 e.mu.Unlock() 739 } 740 741 // thaw unfreezes a previously frozen endpoint using endpoint.freeze() allows 742 // new packets to be delivered again. 743 func (e *endpoint) thaw() { 744 e.mu.Lock() 745 e.frozen = false 746 e.mu.Unlock() 747 }