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  }