github.com/flowerwrong/netstack@v0.0.0-20191009141956-e5848263af28/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  	"sync"
    19  
    20  	"github.com/FlowerWrong/netstack/tcpip"
    21  	"github.com/FlowerWrong/netstack/tcpip/buffer"
    22  	"github.com/FlowerWrong/netstack/tcpip/header"
    23  	"github.com/FlowerWrong/netstack/tcpip/iptables"
    24  	"github.com/FlowerWrong/netstack/tcpip/stack"
    25  	"github.com/FlowerWrong/netstack/waiter"
    26  )
    27  
    28  // +stateify savable
    29  type icmpPacket struct {
    30  	icmpPacketEntry
    31  	senderAddress tcpip.FullAddress
    32  	data          buffer.VectorisedView
    33  	timestamp     int64
    34  	// views is used as buffer for data when its length is large
    35  	// enough to store a VectorisedView.
    36  	views [8]buffer.View
    37  }
    38  
    39  type endpointState int
    40  
    41  const (
    42  	stateInitial endpointState = iota
    43  	stateBound
    44  	stateConnected
    45  	stateClosed
    46  )
    47  
    48  // endpoint represents an ICMP endpoint. This struct serves as the interface
    49  // between users of the endpoint and the protocol implementation; it is legal to
    50  // have concurrent goroutines make calls into the endpoint, they are properly
    51  // synchronized.
    52  //
    53  // +stateify savable
    54  type endpoint struct {
    55  	// The following fields are initialized at creation time and are
    56  	// immutable.
    57  	stack       *stack.Stack
    58  	netProto    tcpip.NetworkProtocolNumber
    59  	transProto  tcpip.TransportProtocolNumber
    60  	waiterQueue *waiter.Queue
    61  
    62  	// The following fields are used to manage the receive queue, and are
    63  	// protected by rcvMu.
    64  	rcvMu         sync.Mutex
    65  	rcvReady      bool
    66  	rcvList       icmpPacketList
    67  	rcvBufSizeMax int
    68  	rcvBufSize    int
    69  	rcvClosed     bool
    70  
    71  	// The following fields are protected by the mu mutex.
    72  	mu         sync.RWMutex
    73  	sndBufSize int
    74  	// shutdownFlags represent the current shutdown state of the endpoint.
    75  	shutdownFlags tcpip.ShutdownFlags
    76  	id            stack.TransportEndpointID
    77  	state         endpointState
    78  	// bindNICID and bindAddr are set via calls to Bind(). They are used to
    79  	// reject attempts to send data or connect via a different NIC or
    80  	// address
    81  	bindNICID tcpip.NICID
    82  	bindAddr  tcpip.Address
    83  	// regNICID is the default NIC to be used when callers don't specify a
    84  	// NIC.
    85  	regNICID tcpip.NICID
    86  	route    stack.Route
    87  	ttl      uint8
    88  }
    89  
    90  func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) {
    91  	return &endpoint{
    92  		stack:         stack,
    93  		netProto:      netProto,
    94  		transProto:    transProto,
    95  		waiterQueue:   waiterQueue,
    96  		rcvBufSizeMax: 32 * 1024,
    97  		sndBufSize:    32 * 1024,
    98  	}, nil
    99  }
   100  
   101  // Close puts the endpoint in a closed state and frees all resources
   102  // associated with it.
   103  func (e *endpoint) Close() {
   104  	e.mu.Lock()
   105  	e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite
   106  	switch e.state {
   107  	case stateBound, stateConnected:
   108  		e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id, e, 0 /* bindToDevice */)
   109  	}
   110  
   111  	// Close the receive list and drain it.
   112  	e.rcvMu.Lock()
   113  	e.rcvClosed = true
   114  	e.rcvBufSize = 0
   115  	for !e.rcvList.Empty() {
   116  		p := e.rcvList.Front()
   117  		e.rcvList.Remove(p)
   118  	}
   119  	e.rcvMu.Unlock()
   120  
   121  	e.route.Release()
   122  
   123  	// Update the state.
   124  	e.state = stateClosed
   125  
   126  	e.mu.Unlock()
   127  
   128  	e.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.EventIn | waiter.EventOut)
   129  }
   130  
   131  // ModerateRecvBuf implements tcpip.Endpoint.ModerateRecvBuf.
   132  func (e *endpoint) ModerateRecvBuf(copied int) {}
   133  
   134  // IPTables implements tcpip.Endpoint.IPTables.
   135  func (e *endpoint) IPTables() (iptables.IPTables, error) {
   136  	return e.stack.IPTables(), nil
   137  }
   138  
   139  // Read reads data from the endpoint. This method does not block if
   140  // there is no data pending.
   141  func (e *endpoint) Read(addr *tcpip.FullAddress) (buffer.View, tcpip.ControlMessages, *tcpip.Error) {
   142  	e.rcvMu.Lock()
   143  
   144  	if e.rcvList.Empty() {
   145  		err := tcpip.ErrWouldBlock
   146  		if e.rcvClosed {
   147  			err = tcpip.ErrClosedForReceive
   148  		}
   149  		e.rcvMu.Unlock()
   150  		return buffer.View{}, tcpip.ControlMessages{}, err
   151  	}
   152  
   153  	p := e.rcvList.Front()
   154  	e.rcvList.Remove(p)
   155  	e.rcvBufSize -= p.data.Size()
   156  
   157  	e.rcvMu.Unlock()
   158  
   159  	if addr != nil {
   160  		*addr = p.senderAddress
   161  	}
   162  
   163  	return p.data.ToView(), tcpip.ControlMessages{HasTimestamp: true, Timestamp: p.timestamp}, nil
   164  }
   165  
   166  // prepareForWrite prepares the endpoint for sending data. In particular, it
   167  // binds it if it's still in the initial state. To do so, it must first
   168  // reacquire the mutex in exclusive mode.
   169  //
   170  // Returns true for retry if preparation should be retried.
   171  func (e *endpoint) prepareForWrite(to *tcpip.FullAddress) (retry bool, err *tcpip.Error) {
   172  	switch e.state {
   173  	case stateInitial:
   174  	case stateConnected:
   175  		return false, nil
   176  
   177  	case stateBound:
   178  		if to == nil {
   179  			return false, tcpip.ErrDestinationRequired
   180  		}
   181  		return false, nil
   182  	default:
   183  		return false, tcpip.ErrInvalidEndpointState
   184  	}
   185  
   186  	e.mu.RUnlock()
   187  	defer e.mu.RLock()
   188  
   189  	e.mu.Lock()
   190  	defer e.mu.Unlock()
   191  
   192  	// The state changed when we released the shared locked and re-acquired
   193  	// it in exclusive mode. Try again.
   194  	if e.state != stateInitial {
   195  		return true, nil
   196  	}
   197  
   198  	// The state is still 'initial', so try to bind the endpoint.
   199  	if err := e.bindLocked(tcpip.FullAddress{}); err != nil {
   200  		return false, err
   201  	}
   202  
   203  	return true, nil
   204  }
   205  
   206  // Write writes data to the endpoint's peer. This method does not block
   207  // if the data cannot be written.
   208  func (e *endpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, <-chan struct{}, *tcpip.Error) {
   209  	// MSG_MORE is unimplemented. (This also means that MSG_EOR is a no-op.)
   210  	if opts.More {
   211  		return 0, nil, tcpip.ErrInvalidOptionValue
   212  	}
   213  
   214  	to := opts.To
   215  
   216  	e.mu.RLock()
   217  	defer e.mu.RUnlock()
   218  
   219  	// If we've shutdown with SHUT_WR we are in an invalid state for sending.
   220  	if e.shutdownFlags&tcpip.ShutdownWrite != 0 {
   221  		return 0, nil, tcpip.ErrClosedForSend
   222  	}
   223  
   224  	// Prepare for write.
   225  	for {
   226  		retry, err := e.prepareForWrite(to)
   227  		if err != nil {
   228  			return 0, nil, err
   229  		}
   230  
   231  		if !retry {
   232  			break
   233  		}
   234  	}
   235  
   236  	var route *stack.Route
   237  	if to == nil {
   238  		route = &e.route
   239  
   240  		if route.IsResolutionRequired() {
   241  			// Promote lock to exclusive if using a shared route,
   242  			// given that it may need to change in Route.Resolve()
   243  			// call below.
   244  			e.mu.RUnlock()
   245  			defer e.mu.RLock()
   246  
   247  			e.mu.Lock()
   248  			defer e.mu.Unlock()
   249  
   250  			// Recheck state after lock was re-acquired.
   251  			if e.state != stateConnected {
   252  				return 0, nil, tcpip.ErrInvalidEndpointState
   253  			}
   254  		}
   255  	} else {
   256  		// Reject destination address if it goes through a different
   257  		// NIC than the endpoint was bound to.
   258  		nicid := to.NIC
   259  		if e.bindNICID != 0 {
   260  			if nicid != 0 && nicid != e.bindNICID {
   261  				return 0, nil, tcpip.ErrNoRoute
   262  			}
   263  
   264  			nicid = e.bindNICID
   265  		}
   266  
   267  		toCopy := *to
   268  		to = &toCopy
   269  		netProto, err := e.checkV4Mapped(to, true)
   270  		if err != nil {
   271  			return 0, nil, err
   272  		}
   273  
   274  		// Find the enpoint.
   275  		r, err := e.stack.FindRoute(nicid, e.bindAddr, to.Addr, netProto, false /* multicastLoop */)
   276  		if err != nil {
   277  			return 0, nil, err
   278  		}
   279  		defer r.Release()
   280  
   281  		route = &r
   282  	}
   283  
   284  	if route.IsResolutionRequired() {
   285  		if ch, err := route.Resolve(nil); err != nil {
   286  			if err == tcpip.ErrWouldBlock {
   287  				return 0, ch, tcpip.ErrNoLinkAddress
   288  			}
   289  			return 0, nil, err
   290  		}
   291  	}
   292  
   293  	v, err := p.FullPayload()
   294  	if err != nil {
   295  		return 0, nil, err
   296  	}
   297  
   298  	switch e.netProto {
   299  	case header.IPv4ProtocolNumber:
   300  		err = send4(route, e.id.LocalPort, v, e.ttl)
   301  
   302  	case header.IPv6ProtocolNumber:
   303  		err = send6(route, e.id.LocalPort, v, e.ttl)
   304  	}
   305  
   306  	if err != nil {
   307  		return 0, nil, err
   308  	}
   309  
   310  	return int64(len(v)), nil, nil
   311  }
   312  
   313  // Peek only returns data from a single datagram, so do nothing here.
   314  func (e *endpoint) Peek([][]byte) (int64, tcpip.ControlMessages, *tcpip.Error) {
   315  	return 0, tcpip.ControlMessages{}, nil
   316  }
   317  
   318  // SetSockOpt sets a socket option.
   319  func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
   320  	switch o := opt.(type) {
   321  	case tcpip.TTLOption:
   322  		e.mu.Lock()
   323  		e.ttl = uint8(o)
   324  		e.mu.Unlock()
   325  	}
   326  
   327  	return nil
   328  }
   329  
   330  // SetSockOptInt sets a socket option. Currently not supported.
   331  func (e *endpoint) SetSockOptInt(opt tcpip.SockOpt, v int) *tcpip.Error {
   332  	return nil
   333  }
   334  
   335  // GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
   336  func (e *endpoint) GetSockOptInt(opt tcpip.SockOpt) (int, *tcpip.Error) {
   337  	switch opt {
   338  	case tcpip.ReceiveQueueSizeOption:
   339  		v := 0
   340  		e.rcvMu.Lock()
   341  		if !e.rcvList.Empty() {
   342  			p := e.rcvList.Front()
   343  			v = p.data.Size()
   344  		}
   345  		e.rcvMu.Unlock()
   346  		return v, nil
   347  	case tcpip.SendBufferSizeOption:
   348  		e.mu.Lock()
   349  		v := e.sndBufSize
   350  		e.mu.Unlock()
   351  		return v, nil
   352  
   353  	case tcpip.ReceiveBufferSizeOption:
   354  		e.rcvMu.Lock()
   355  		v := e.rcvBufSizeMax
   356  		e.rcvMu.Unlock()
   357  		return v, nil
   358  
   359  	}
   360  	return -1, tcpip.ErrUnknownProtocolOption
   361  }
   362  
   363  // GetSockOpt implements tcpip.Endpoint.GetSockOpt.
   364  func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
   365  	switch o := opt.(type) {
   366  	case tcpip.ErrorOption:
   367  		return nil
   368  
   369  	case *tcpip.KeepaliveEnabledOption:
   370  		*o = 0
   371  		return nil
   372  
   373  	case *tcpip.TTLOption:
   374  		e.rcvMu.Lock()
   375  		*o = tcpip.TTLOption(e.ttl)
   376  		e.rcvMu.Unlock()
   377  		return nil
   378  
   379  	default:
   380  		return tcpip.ErrUnknownProtocolOption
   381  	}
   382  }
   383  
   384  func send4(r *stack.Route, ident uint16, data buffer.View, ttl uint8) *tcpip.Error {
   385  	if len(data) < header.ICMPv4MinimumSize {
   386  		return tcpip.ErrInvalidEndpointState
   387  	}
   388  
   389  	hdr := buffer.NewPrependable(header.ICMPv4MinimumSize + int(r.MaxHeaderLength()))
   390  
   391  	icmpv4 := header.ICMPv4(hdr.Prepend(header.ICMPv4MinimumSize))
   392  	copy(icmpv4, data)
   393  	// Set the ident to the user-specified port. Sequence number should
   394  	// already be set by the user.
   395  	icmpv4.SetIdent(ident)
   396  	data = data[header.ICMPv4MinimumSize:]
   397  
   398  	// Linux performs these basic checks.
   399  	if icmpv4.Type() != header.ICMPv4Echo || icmpv4.Code() != 0 {
   400  		return tcpip.ErrInvalidEndpointState
   401  	}
   402  
   403  	icmpv4.SetChecksum(0)
   404  	icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0)))
   405  
   406  	return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, ttl, ttl == 0 /* useDefaultTTL */)
   407  }
   408  
   409  func send6(r *stack.Route, ident uint16, data buffer.View, ttl uint8) *tcpip.Error {
   410  	if len(data) < header.ICMPv6EchoMinimumSize {
   411  		return tcpip.ErrInvalidEndpointState
   412  	}
   413  
   414  	hdr := buffer.NewPrependable(header.ICMPv6MinimumSize + int(r.MaxHeaderLength()))
   415  
   416  	icmpv6 := header.ICMPv6(hdr.Prepend(header.ICMPv6MinimumSize))
   417  	copy(icmpv6, data)
   418  	// Set the ident. Sequence number is provided by the user.
   419  	icmpv6.SetIdent(ident)
   420  	data = data[header.ICMPv6MinimumSize:]
   421  
   422  	if icmpv6.Type() != header.ICMPv6EchoRequest || icmpv6.Code() != 0 {
   423  		return tcpip.ErrInvalidEndpointState
   424  	}
   425  
   426  	icmpv6.SetChecksum(0)
   427  	icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0)))
   428  
   429  	return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), header.ICMPv6ProtocolNumber, ttl, ttl == 0 /* useDefaultTTL */)
   430  }
   431  
   432  func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) {
   433  	netProto := e.netProto
   434  	if header.IsV4MappedAddress(addr.Addr) {
   435  		return 0, tcpip.ErrNoRoute
   436  	}
   437  
   438  	// Fail if we're bound to an address length different from the one we're
   439  	// checking.
   440  	if l := len(e.id.LocalAddress); !allowMismatch && l != 0 && l != len(addr.Addr) {
   441  		return 0, tcpip.ErrInvalidEndpointState
   442  	}
   443  
   444  	return netProto, nil
   445  }
   446  
   447  // Disconnect implements tcpip.Endpoint.Disconnect.
   448  func (*endpoint) Disconnect() *tcpip.Error {
   449  	return tcpip.ErrNotSupported
   450  }
   451  
   452  // Connect connects the endpoint to its peer. Specifying a NIC is optional.
   453  func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error {
   454  	e.mu.Lock()
   455  	defer e.mu.Unlock()
   456  
   457  	nicid := addr.NIC
   458  	localPort := uint16(0)
   459  	switch e.state {
   460  	case stateBound, stateConnected:
   461  		localPort = e.id.LocalPort
   462  		if e.bindNICID == 0 {
   463  			break
   464  		}
   465  
   466  		if nicid != 0 && nicid != e.bindNICID {
   467  			return tcpip.ErrInvalidEndpointState
   468  		}
   469  
   470  		nicid = e.bindNICID
   471  	default:
   472  		return tcpip.ErrInvalidEndpointState
   473  	}
   474  
   475  	netProto, err := e.checkV4Mapped(&addr, false)
   476  	if err != nil {
   477  		return err
   478  	}
   479  
   480  	// Find a route to the desired destination.
   481  	r, err := e.stack.FindRoute(nicid, e.bindAddr, addr.Addr, netProto, false /* multicastLoop */)
   482  	if err != nil {
   483  		return err
   484  	}
   485  	defer r.Release()
   486  
   487  	id := stack.TransportEndpointID{
   488  		LocalAddress:  r.LocalAddress,
   489  		LocalPort:     localPort,
   490  		RemoteAddress: r.RemoteAddress,
   491  	}
   492  
   493  	// Even if we're connected, this endpoint can still be used to send
   494  	// packets on a different network protocol, so we register both even if
   495  	// v6only is set to false and this is an ipv6 endpoint.
   496  	netProtos := []tcpip.NetworkProtocolNumber{netProto}
   497  
   498  	id, err = e.registerWithStack(nicid, netProtos, id)
   499  	if err != nil {
   500  		return err
   501  	}
   502  
   503  	e.id = id
   504  	e.route = r.Clone()
   505  	e.regNICID = nicid
   506  
   507  	e.state = stateConnected
   508  
   509  	e.rcvMu.Lock()
   510  	e.rcvReady = true
   511  	e.rcvMu.Unlock()
   512  
   513  	return nil
   514  }
   515  
   516  // ConnectEndpoint is not supported.
   517  func (*endpoint) ConnectEndpoint(tcpip.Endpoint) *tcpip.Error {
   518  	return tcpip.ErrInvalidEndpointState
   519  }
   520  
   521  // Shutdown closes the read and/or write end of the endpoint connection
   522  // to its peer.
   523  func (e *endpoint) Shutdown(flags tcpip.ShutdownFlags) *tcpip.Error {
   524  	e.mu.Lock()
   525  	defer e.mu.Unlock()
   526  	e.shutdownFlags |= flags
   527  
   528  	if e.state != stateConnected {
   529  		return tcpip.ErrNotConnected
   530  	}
   531  
   532  	if flags&tcpip.ShutdownRead != 0 {
   533  		e.rcvMu.Lock()
   534  		wasClosed := e.rcvClosed
   535  		e.rcvClosed = true
   536  		e.rcvMu.Unlock()
   537  
   538  		if !wasClosed {
   539  			e.waiterQueue.Notify(waiter.EventIn)
   540  		}
   541  	}
   542  
   543  	return nil
   544  }
   545  
   546  // Listen is not supported by UDP, it just fails.
   547  func (*endpoint) Listen(int) *tcpip.Error {
   548  	return tcpip.ErrNotSupported
   549  }
   550  
   551  // Accept is not supported by UDP, it just fails.
   552  func (*endpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) {
   553  	return nil, nil, tcpip.ErrNotSupported
   554  }
   555  
   556  func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, id stack.TransportEndpointID) (stack.TransportEndpointID, *tcpip.Error) {
   557  	if id.LocalPort != 0 {
   558  		// The endpoint already has a local port, just attempt to
   559  		// register it.
   560  		err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e, false /* reuse */, 0 /* bindToDevice */)
   561  		return id, err
   562  	}
   563  
   564  	// We need to find a port for the endpoint.
   565  	_, err := e.stack.PickEphemeralPort(func(p uint16) (bool, *tcpip.Error) {
   566  		id.LocalPort = p
   567  		err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e, false /* reuse */, 0 /* bindtodevice */)
   568  		switch err {
   569  		case nil:
   570  			return true, nil
   571  		case tcpip.ErrPortInUse:
   572  			return false, nil
   573  		default:
   574  			return false, err
   575  		}
   576  	})
   577  
   578  	return id, err
   579  }
   580  
   581  func (e *endpoint) bindLocked(addr tcpip.FullAddress) *tcpip.Error {
   582  	// Don't allow binding once endpoint is not in the initial state
   583  	// anymore.
   584  	if e.state != stateInitial {
   585  		return tcpip.ErrInvalidEndpointState
   586  	}
   587  
   588  	netProto, err := e.checkV4Mapped(&addr, false)
   589  	if err != nil {
   590  		return err
   591  	}
   592  
   593  	// Expand netProtos to include v4 and v6 if the caller is binding to a
   594  	// wildcard (empty) address, and this is an IPv6 endpoint with v6only
   595  	// set to false.
   596  	netProtos := []tcpip.NetworkProtocolNumber{netProto}
   597  
   598  	if len(addr.Addr) != 0 {
   599  		// A local address was specified, verify that it's valid.
   600  		if e.stack.CheckLocalAddress(addr.NIC, netProto, addr.Addr) == 0 {
   601  			return tcpip.ErrBadLocalAddress
   602  		}
   603  	}
   604  
   605  	id := stack.TransportEndpointID{
   606  		LocalPort:    addr.Port,
   607  		LocalAddress: addr.Addr,
   608  	}
   609  	id, err = e.registerWithStack(addr.NIC, netProtos, id)
   610  	if err != nil {
   611  		return err
   612  	}
   613  
   614  	e.id = id
   615  	e.regNICID = addr.NIC
   616  
   617  	// Mark endpoint as bound.
   618  	e.state = stateBound
   619  
   620  	e.rcvMu.Lock()
   621  	e.rcvReady = true
   622  	e.rcvMu.Unlock()
   623  
   624  	return nil
   625  }
   626  
   627  // Bind binds the endpoint to a specific local address and port.
   628  // Specifying a NIC is optional.
   629  func (e *endpoint) Bind(addr tcpip.FullAddress) *tcpip.Error {
   630  	e.mu.Lock()
   631  	defer e.mu.Unlock()
   632  
   633  	err := e.bindLocked(addr)
   634  	if err != nil {
   635  		return err
   636  	}
   637  
   638  	e.bindNICID = addr.NIC
   639  	e.bindAddr = addr.Addr
   640  
   641  	return nil
   642  }
   643  
   644  // GetLocalAddress returns the address to which the endpoint is bound.
   645  func (e *endpoint) GetLocalAddress() (tcpip.FullAddress, *tcpip.Error) {
   646  	e.mu.RLock()
   647  	defer e.mu.RUnlock()
   648  
   649  	return tcpip.FullAddress{
   650  		NIC:  e.regNICID,
   651  		Addr: e.id.LocalAddress,
   652  		Port: e.id.LocalPort,
   653  	}, nil
   654  }
   655  
   656  // GetRemoteAddress returns the address to which the endpoint is connected.
   657  func (e *endpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Error) {
   658  	e.mu.RLock()
   659  	defer e.mu.RUnlock()
   660  
   661  	if e.state != stateConnected {
   662  		return tcpip.FullAddress{}, tcpip.ErrNotConnected
   663  	}
   664  
   665  	return tcpip.FullAddress{
   666  		NIC:  e.regNICID,
   667  		Addr: e.id.RemoteAddress,
   668  		Port: e.id.RemotePort,
   669  	}, nil
   670  }
   671  
   672  // Readiness returns the current readiness of the endpoint. For example, if
   673  // waiter.EventIn is set, the endpoint is immediately readable.
   674  func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask {
   675  	// The endpoint is always writable.
   676  	result := waiter.EventOut & mask
   677  
   678  	// Determine if the endpoint is readable if requested.
   679  	if (mask & waiter.EventIn) != 0 {
   680  		e.rcvMu.Lock()
   681  		if !e.rcvList.Empty() || e.rcvClosed {
   682  			result |= waiter.EventIn
   683  		}
   684  		e.rcvMu.Unlock()
   685  	}
   686  
   687  	return result
   688  }
   689  
   690  // HandlePacket is called by the stack when new packets arrive to this transport
   691  // endpoint.
   692  func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) {
   693  	// Only accept echo replies.
   694  	switch e.netProto {
   695  	case header.IPv4ProtocolNumber:
   696  		h := header.ICMPv4(vv.First())
   697  		if h.Type() != header.ICMPv4EchoReply {
   698  			e.stack.Stats().DroppedPackets.Increment()
   699  			return
   700  		}
   701  	case header.IPv6ProtocolNumber:
   702  		h := header.ICMPv6(vv.First())
   703  		if h.Type() != header.ICMPv6EchoReply {
   704  			e.stack.Stats().DroppedPackets.Increment()
   705  			return
   706  		}
   707  	}
   708  
   709  	e.rcvMu.Lock()
   710  
   711  	// Drop the packet if our buffer is currently full.
   712  	if !e.rcvReady || e.rcvClosed || e.rcvBufSize >= e.rcvBufSizeMax {
   713  		e.stack.Stats().DroppedPackets.Increment()
   714  		e.rcvMu.Unlock()
   715  		return
   716  	}
   717  
   718  	wasEmpty := e.rcvBufSize == 0
   719  
   720  	// Push new packet into receive list and increment the buffer size.
   721  	pkt := &icmpPacket{
   722  		senderAddress: tcpip.FullAddress{
   723  			NIC:  r.NICID(),
   724  			Addr: id.RemoteAddress,
   725  		},
   726  	}
   727  
   728  	pkt.data = vv.Clone(pkt.views[:])
   729  
   730  	e.rcvList.PushBack(pkt)
   731  	e.rcvBufSize += pkt.data.Size()
   732  
   733  	pkt.timestamp = e.stack.NowNanoseconds()
   734  
   735  	e.rcvMu.Unlock()
   736  
   737  	// Notify any waiters that there's data to be read now.
   738  	if wasEmpty {
   739  		e.waiterQueue.Notify(waiter.EventIn)
   740  	}
   741  }
   742  
   743  // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket.
   744  func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, vv buffer.VectorisedView) {
   745  }
   746  
   747  // State implements tcpip.Endpoint.State. The ICMP endpoint currently doesn't
   748  // expose internal socket state.
   749  func (e *endpoint) State() uint32 {
   750  	return 0
   751  }