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  }