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