github.com/lightlus/netstack@v1.2.0/tcpip/transport/udp/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 udp
    16  
    17  import (
    18  	"sync"
    19  
    20  	"github.com/lightlus/netstack/tcpip"
    21  	"github.com/lightlus/netstack/tcpip/buffer"
    22  	"github.com/lightlus/netstack/tcpip/header"
    23  	"github.com/lightlus/netstack/tcpip/iptables"
    24  	"github.com/lightlus/netstack/tcpip/stack"
    25  	"github.com/lightlus/netstack/waiter"
    26  )
    27  
    28  // +stateify savable
    29  type udpPacket struct {
    30  	udpPacketEntry
    31  	senderAddress tcpip.FullAddress
    32  	data          buffer.VectorisedView
    33  	timestamp     int64
    34  }
    35  
    36  // EndpointState represents the state of a UDP endpoint.
    37  type EndpointState uint32
    38  
    39  // Endpoint states. Note that are represented in a netstack-specific manner and
    40  // may not be meaningful externally. Specifically, they need to be translated to
    41  // Linux's representation for these states if presented to userspace.
    42  const (
    43  	StateInitial EndpointState = iota
    44  	StateBound
    45  	StateConnected
    46  	StateClosed
    47  )
    48  
    49  // String implements fmt.Stringer.String.
    50  func (s EndpointState) String() string {
    51  	switch s {
    52  	case StateInitial:
    53  		return "INITIAL"
    54  	case StateBound:
    55  		return "BOUND"
    56  	case StateConnected:
    57  		return "CONNECTING"
    58  	case StateClosed:
    59  		return "CLOSED"
    60  	default:
    61  		return "UNKNOWN"
    62  	}
    63  }
    64  
    65  // endpoint represents a UDP endpoint. This struct serves as the interface
    66  // between users of the endpoint and the protocol implementation; it is legal to
    67  // have concurrent goroutines make calls into the endpoint, they are properly
    68  // synchronized.
    69  //
    70  // It implements tcpip.Endpoint.
    71  //
    72  // +stateify savable
    73  type endpoint struct {
    74  	stack.TransportEndpointInfo
    75  
    76  	// The following fields are initialized at creation time and do not
    77  	// change throughout the lifetime of the endpoint.
    78  	stack       *stack.Stack
    79  	waiterQueue *waiter.Queue
    80  	uniqueID    uint64
    81  
    82  	// The following fields are used to manage the receive queue, and are
    83  	// protected by rcvMu.
    84  	rcvMu         sync.Mutex
    85  	rcvReady      bool
    86  	rcvList       udpPacketList
    87  	rcvBufSizeMax int
    88  	rcvBufSize    int
    89  	rcvClosed     bool
    90  
    91  	// The following fields are protected by the mu mutex.
    92  	mu             sync.RWMutex
    93  	sndBufSize     int
    94  	state          EndpointState
    95  	route          stack.Route
    96  	dstPort        uint16
    97  	v6only         bool
    98  	ttl            uint8
    99  	multicastTTL   uint8
   100  	multicastAddr  tcpip.Address
   101  	multicastNICID tcpip.NICID
   102  	multicastLoop  bool
   103  	reusePort      bool
   104  	bindToDevice   tcpip.NICID
   105  	broadcast      bool
   106  
   107  	// sendTOS represents IPv4 TOS or IPv6 TrafficClass,
   108  	// applied while sending packets. Defaults to 0 as on Linux.
   109  	sendTOS uint8
   110  
   111  	// shutdownFlags represent the current shutdown state of the endpoint.
   112  	shutdownFlags tcpip.ShutdownFlags
   113  
   114  	// multicastMemberships that need to be remvoed when the endpoint is
   115  	// closed. Protected by the mu mutex.
   116  	multicastMemberships []multicastMembership
   117  
   118  	// effectiveNetProtos contains the network protocols actually in use. In
   119  	// most cases it will only contain "netProto", but in cases like IPv6
   120  	// endpoints with v6only set to false, this could include multiple
   121  	// protocols (e.g., IPv6 and IPv4) or a single different protocol (e.g.,
   122  	// IPv4 when IPv6 endpoint is bound or connected to an IPv4 mapped
   123  	// address).
   124  	effectiveNetProtos []tcpip.NetworkProtocolNumber
   125  
   126  	// TODO(b/142022063): Add ability to save and restore per endpoint stats.
   127  	stats tcpip.TransportEndpointStats
   128  }
   129  
   130  // +stateify savable
   131  type multicastMembership struct {
   132  	nicID         tcpip.NICID
   133  	multicastAddr tcpip.Address
   134  }
   135  
   136  func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) *endpoint {
   137  	return &endpoint{
   138  		stack: s,
   139  		TransportEndpointInfo: stack.TransportEndpointInfo{
   140  			NetProto:   netProto,
   141  			TransProto: header.UDPProtocolNumber,
   142  		},
   143  		waiterQueue: waiterQueue,
   144  		// RFC 1075 section 5.4 recommends a TTL of 1 for membership
   145  		// requests.
   146  		//
   147  		// RFC 5135 4.2.1 appears to assume that IGMP messages have a
   148  		// TTL of 1.
   149  		//
   150  		// RFC 5135 Appendix A defines TTL=1: A multicast source that
   151  		// wants its traffic to not traverse a router (e.g., leave a
   152  		// home network) may find it useful to send traffic with IP
   153  		// TTL=1.
   154  		//
   155  		// Linux defaults to TTL=1.
   156  		multicastTTL:  1,
   157  		multicastLoop: true,
   158  		rcvBufSizeMax: 32 * 1024,
   159  		sndBufSize:    32 * 1024,
   160  		state:         StateInitial,
   161  		uniqueID:      s.UniqueID(),
   162  	}
   163  }
   164  
   165  // UniqueID implements stack.TransportEndpoint.UniqueID.
   166  func (e *endpoint) UniqueID() uint64 {
   167  	return e.uniqueID
   168  }
   169  
   170  // Close puts the endpoint in a closed state and frees all resources
   171  // associated with it.
   172  func (e *endpoint) Close() {
   173  	e.mu.Lock()
   174  	e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite
   175  
   176  	switch e.state {
   177  	case StateBound, StateConnected:
   178  		e.stack.UnregisterTransportEndpoint(e.RegisterNICID, e.effectiveNetProtos, ProtocolNumber, e.ID, e, e.bindToDevice)
   179  		e.stack.ReleasePort(e.effectiveNetProtos, ProtocolNumber, e.ID.LocalAddress, e.ID.LocalPort, e.bindToDevice)
   180  	}
   181  
   182  	for _, mem := range e.multicastMemberships {
   183  		e.stack.LeaveGroup(e.NetProto, mem.nicID, mem.multicastAddr)
   184  	}
   185  	e.multicastMemberships = nil
   186  
   187  	// Close the receive list and drain it.
   188  	e.rcvMu.Lock()
   189  	e.rcvClosed = true
   190  	e.rcvBufSize = 0
   191  	for !e.rcvList.Empty() {
   192  		p := e.rcvList.Front()
   193  		e.rcvList.Remove(p)
   194  	}
   195  	e.rcvMu.Unlock()
   196  
   197  	e.route.Release()
   198  
   199  	// Update the state.
   200  	e.state = StateClosed
   201  
   202  	e.mu.Unlock()
   203  
   204  	e.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.EventIn | waiter.EventOut)
   205  }
   206  
   207  // ModerateRecvBuf implements tcpip.Endpoint.ModerateRecvBuf.
   208  func (e *endpoint) ModerateRecvBuf(copied int) {}
   209  
   210  // IPTables implements tcpip.Endpoint.IPTables.
   211  func (e *endpoint) IPTables() (iptables.IPTables, error) {
   212  	return e.stack.IPTables(), nil
   213  }
   214  
   215  // Read reads data from the endpoint. This method does not block if
   216  // there is no data pending.
   217  func (e *endpoint) Read(addr *tcpip.FullAddress) (buffer.View, tcpip.ControlMessages, *tcpip.Error) {
   218  	e.rcvMu.Lock()
   219  
   220  	if e.rcvList.Empty() {
   221  		err := tcpip.ErrWouldBlock
   222  		if e.rcvClosed {
   223  			e.stats.ReadErrors.ReadClosed.Increment()
   224  			err = tcpip.ErrClosedForReceive
   225  		}
   226  		e.rcvMu.Unlock()
   227  		return buffer.View{}, tcpip.ControlMessages{}, err
   228  	}
   229  
   230  	p := e.rcvList.Front()
   231  	e.rcvList.Remove(p)
   232  	e.rcvBufSize -= p.data.Size()
   233  	e.rcvMu.Unlock()
   234  
   235  	if addr != nil {
   236  		*addr = p.senderAddress
   237  	}
   238  
   239  	return p.data.ToView(), tcpip.ControlMessages{HasTimestamp: true, Timestamp: p.timestamp}, nil
   240  }
   241  
   242  // prepareForWrite prepares the endpoint for sending data. In particular, it
   243  // binds it if it's still in the initial state. To do so, it must first
   244  // reacquire the mutex in exclusive mode.
   245  //
   246  // Returns true for retry if preparation should be retried.
   247  func (e *endpoint) prepareForWrite(to *tcpip.FullAddress) (retry bool, err *tcpip.Error) {
   248  	switch e.state {
   249  	case StateInitial:
   250  	case StateConnected:
   251  		return false, nil
   252  
   253  	case StateBound:
   254  		if to == nil {
   255  			return false, tcpip.ErrDestinationRequired
   256  		}
   257  		return false, nil
   258  	default:
   259  		return false, tcpip.ErrInvalidEndpointState
   260  	}
   261  
   262  	e.mu.RUnlock()
   263  	defer e.mu.RLock()
   264  
   265  	e.mu.Lock()
   266  	defer e.mu.Unlock()
   267  
   268  	// The state changed when we released the shared locked and re-acquired
   269  	// it in exclusive mode. Try again.
   270  	if e.state != StateInitial {
   271  		return true, nil
   272  	}
   273  
   274  	// The state is still 'initial', so try to bind the endpoint.
   275  	if err := e.bindLocked(tcpip.FullAddress{}); err != nil {
   276  		return false, err
   277  	}
   278  
   279  	return true, nil
   280  }
   281  
   282  // connectRoute establishes a route to the specified interface or the
   283  // configured multicast interface if no interface is specified and the
   284  // specified address is a multicast address.
   285  func (e *endpoint) connectRoute(nicID tcpip.NICID, addr tcpip.FullAddress, netProto tcpip.NetworkProtocolNumber) (stack.Route, tcpip.NICID, *tcpip.Error) {
   286  	localAddr := e.ID.LocalAddress
   287  	if isBroadcastOrMulticast(localAddr) {
   288  		// A packet can only originate from a unicast address (i.e., an interface).
   289  		localAddr = ""
   290  	}
   291  
   292  	if header.IsV4MulticastAddress(addr.Addr) || header.IsV6MulticastAddress(addr.Addr) {
   293  		if nicID == 0 {
   294  			nicID = e.multicastNICID
   295  		}
   296  		if localAddr == "" && nicID == 0 {
   297  			localAddr = e.multicastAddr
   298  		}
   299  	}
   300  
   301  	// Find a route to the desired destination.
   302  	r, err := e.stack.FindRoute(nicID, localAddr, addr.Addr, netProto, e.multicastLoop)
   303  	if err != nil {
   304  		return stack.Route{}, 0, err
   305  	}
   306  	return r, nicID, nil
   307  }
   308  
   309  // Write writes data to the endpoint's peer. This method does not block
   310  // if the data cannot be written.
   311  func (e *endpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, <-chan struct{}, *tcpip.Error) {
   312  	n, ch, err := e.write(p, opts)
   313  	switch err {
   314  	case nil:
   315  		e.stats.PacketsSent.Increment()
   316  	case tcpip.ErrMessageTooLong, tcpip.ErrInvalidOptionValue:
   317  		e.stats.WriteErrors.InvalidArgs.Increment()
   318  	case tcpip.ErrClosedForSend:
   319  		e.stats.WriteErrors.WriteClosed.Increment()
   320  	case tcpip.ErrInvalidEndpointState:
   321  		e.stats.WriteErrors.InvalidEndpointState.Increment()
   322  	case tcpip.ErrNoLinkAddress:
   323  		e.stats.SendErrors.NoLinkAddr.Increment()
   324  	case tcpip.ErrNoRoute, tcpip.ErrBroadcastDisabled, tcpip.ErrNetworkUnreachable:
   325  		// Errors indicating any problem with IP routing of the packet.
   326  		e.stats.SendErrors.NoRoute.Increment()
   327  	default:
   328  		// For all other errors when writing to the network layer.
   329  		e.stats.SendErrors.SendToNetworkFailed.Increment()
   330  	}
   331  	return n, ch, err
   332  }
   333  
   334  func (e *endpoint) write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, <-chan struct{}, *tcpip.Error) {
   335  	// MSG_MORE is unimplemented. (This also means that MSG_EOR is a no-op.)
   336  	if opts.More {
   337  		return 0, nil, tcpip.ErrInvalidOptionValue
   338  	}
   339  
   340  	to := opts.To
   341  
   342  	e.mu.RLock()
   343  	defer e.mu.RUnlock()
   344  
   345  	// If we've shutdown with SHUT_WR we are in an invalid state for sending.
   346  	if e.shutdownFlags&tcpip.ShutdownWrite != 0 {
   347  		return 0, nil, tcpip.ErrClosedForSend
   348  	}
   349  
   350  	// Prepare for write.
   351  	for {
   352  		retry, err := e.prepareForWrite(to)
   353  		if err != nil {
   354  			return 0, nil, err
   355  		}
   356  
   357  		if !retry {
   358  			break
   359  		}
   360  	}
   361  
   362  	var route *stack.Route
   363  	var dstPort uint16
   364  	if to == nil {
   365  		route = &e.route
   366  		dstPort = e.dstPort
   367  
   368  		if route.IsResolutionRequired() {
   369  			// Promote lock to exclusive if using a shared route, given that it may need to
   370  			// change in Route.Resolve() call below.
   371  			e.mu.RUnlock()
   372  			defer e.mu.RLock()
   373  
   374  			e.mu.Lock()
   375  			defer e.mu.Unlock()
   376  
   377  			// Recheck state after lock was re-acquired.
   378  			if e.state != StateConnected {
   379  				return 0, nil, tcpip.ErrInvalidEndpointState
   380  			}
   381  		}
   382  	} else {
   383  		// Reject destination address if it goes through a different
   384  		// NIC than the endpoint was bound to.
   385  		nicID := to.NIC
   386  		if e.BindNICID != 0 {
   387  			if nicID != 0 && nicID != e.BindNICID {
   388  				return 0, nil, tcpip.ErrNoRoute
   389  			}
   390  
   391  			nicID = e.BindNICID
   392  		}
   393  
   394  		if to.Addr == header.IPv4Broadcast && !e.broadcast {
   395  			return 0, nil, tcpip.ErrBroadcastDisabled
   396  		}
   397  
   398  		netProto, err := e.checkV4Mapped(to, false)
   399  		if err != nil {
   400  			return 0, nil, err
   401  		}
   402  
   403  		r, _, err := e.connectRoute(nicID, *to, netProto)
   404  		if err != nil {
   405  			return 0, nil, err
   406  		}
   407  		defer r.Release()
   408  
   409  		route = &r
   410  		dstPort = to.Port
   411  	}
   412  
   413  	if route.IsResolutionRequired() {
   414  		if ch, err := route.Resolve(nil); err != nil {
   415  			if err == tcpip.ErrWouldBlock {
   416  				return 0, ch, tcpip.ErrNoLinkAddress
   417  			}
   418  			return 0, nil, err
   419  		}
   420  	}
   421  
   422  	v, err := p.FullPayload()
   423  	if err != nil {
   424  		return 0, nil, err
   425  	}
   426  	if len(v) > header.UDPMaximumPacketSize {
   427  		// Payload can't possibly fit in a packet.
   428  		return 0, nil, tcpip.ErrMessageTooLong
   429  	}
   430  
   431  	ttl := e.ttl
   432  	useDefaultTTL := ttl == 0
   433  
   434  	if header.IsV4MulticastAddress(route.RemoteAddress) || header.IsV6MulticastAddress(route.RemoteAddress) {
   435  		ttl = e.multicastTTL
   436  		// Multicast allows a 0 TTL.
   437  		useDefaultTTL = false
   438  	}
   439  
   440  	if err := sendUDP(route, buffer.View(v).ToVectorisedView(), e.ID.LocalPort, dstPort, ttl, useDefaultTTL, e.sendTOS); err != nil {
   441  		return 0, nil, err
   442  	}
   443  	return int64(len(v)), nil, nil
   444  }
   445  
   446  // Peek only returns data from a single datagram, so do nothing here.
   447  func (e *endpoint) Peek([][]byte) (int64, tcpip.ControlMessages, *tcpip.Error) {
   448  	return 0, tcpip.ControlMessages{}, nil
   449  }
   450  
   451  // SetSockOptInt implements tcpip.Endpoint.SetSockOptInt.
   452  func (e *endpoint) SetSockOptInt(opt tcpip.SockOpt, v int) *tcpip.Error {
   453  	return nil
   454  }
   455  
   456  // SetSockOpt implements tcpip.Endpoint.SetSockOpt.
   457  func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error {
   458  	switch v := opt.(type) {
   459  	case tcpip.V6OnlyOption:
   460  		// We only recognize this option on v6 endpoints.
   461  		if e.NetProto != header.IPv6ProtocolNumber {
   462  			return tcpip.ErrInvalidEndpointState
   463  		}
   464  
   465  		e.mu.Lock()
   466  		defer e.mu.Unlock()
   467  
   468  		// We only allow this to be set when we're in the initial state.
   469  		if e.state != StateInitial {
   470  			return tcpip.ErrInvalidEndpointState
   471  		}
   472  
   473  		e.v6only = v != 0
   474  
   475  	case tcpip.TTLOption:
   476  		e.mu.Lock()
   477  		e.ttl = uint8(v)
   478  		e.mu.Unlock()
   479  
   480  	case tcpip.MulticastTTLOption:
   481  		e.mu.Lock()
   482  		e.multicastTTL = uint8(v)
   483  		e.mu.Unlock()
   484  
   485  	case tcpip.MulticastInterfaceOption:
   486  		e.mu.Lock()
   487  		defer e.mu.Unlock()
   488  
   489  		fa := tcpip.FullAddress{Addr: v.InterfaceAddr}
   490  		netProto, err := e.checkV4Mapped(&fa, false)
   491  		if err != nil {
   492  			return err
   493  		}
   494  		nic := v.NIC
   495  		addr := fa.Addr
   496  
   497  		if nic == 0 && addr == "" {
   498  			e.multicastAddr = ""
   499  			e.multicastNICID = 0
   500  			break
   501  		}
   502  
   503  		if nic != 0 {
   504  			if !e.stack.CheckNIC(nic) {
   505  				return tcpip.ErrBadLocalAddress
   506  			}
   507  		} else {
   508  			nic = e.stack.CheckLocalAddress(0, netProto, addr)
   509  			if nic == 0 {
   510  				return tcpip.ErrBadLocalAddress
   511  			}
   512  		}
   513  
   514  		if e.BindNICID != 0 && e.BindNICID != nic {
   515  			return tcpip.ErrInvalidEndpointState
   516  		}
   517  
   518  		e.multicastNICID = nic
   519  		e.multicastAddr = addr
   520  
   521  	case tcpip.AddMembershipOption:
   522  		if !header.IsV4MulticastAddress(v.MulticastAddr) && !header.IsV6MulticastAddress(v.MulticastAddr) {
   523  			return tcpip.ErrInvalidOptionValue
   524  		}
   525  
   526  		nicID := v.NIC
   527  
   528  		// The interface address is considered not-set if it is empty or contains
   529  		// all-zeros. The former represent the zero-value in golang, the latter the
   530  		// same in a setsockopt(IP_ADD_MEMBERSHIP, &ip_mreqn) syscall.
   531  		allZeros := header.IPv4Any
   532  		if len(v.InterfaceAddr) == 0 || v.InterfaceAddr == allZeros {
   533  			if nicID == 0 {
   534  				r, err := e.stack.FindRoute(0, "", v.MulticastAddr, header.IPv4ProtocolNumber, false /* multicastLoop */)
   535  				if err == nil {
   536  					nicID = r.NICID()
   537  					r.Release()
   538  				}
   539  			}
   540  		} else {
   541  			nicID = e.stack.CheckLocalAddress(nicID, e.NetProto, v.InterfaceAddr)
   542  		}
   543  		if nicID == 0 {
   544  			return tcpip.ErrUnknownDevice
   545  		}
   546  
   547  		memToInsert := multicastMembership{nicID: nicID, multicastAddr: v.MulticastAddr}
   548  
   549  		e.mu.Lock()
   550  		defer e.mu.Unlock()
   551  
   552  		for _, mem := range e.multicastMemberships {
   553  			if mem == memToInsert {
   554  				return tcpip.ErrPortInUse
   555  			}
   556  		}
   557  
   558  		if err := e.stack.JoinGroup(e.NetProto, nicID, v.MulticastAddr); err != nil {
   559  			return err
   560  		}
   561  
   562  		e.multicastMemberships = append(e.multicastMemberships, memToInsert)
   563  
   564  	case tcpip.RemoveMembershipOption:
   565  		if !header.IsV4MulticastAddress(v.MulticastAddr) && !header.IsV6MulticastAddress(v.MulticastAddr) {
   566  			return tcpip.ErrInvalidOptionValue
   567  		}
   568  
   569  		nicID := v.NIC
   570  		if v.InterfaceAddr == header.IPv4Any {
   571  			if nicID == 0 {
   572  				r, err := e.stack.FindRoute(0, "", v.MulticastAddr, header.IPv4ProtocolNumber, false /* multicastLoop */)
   573  				if err == nil {
   574  					nicID = r.NICID()
   575  					r.Release()
   576  				}
   577  			}
   578  		} else {
   579  			nicID = e.stack.CheckLocalAddress(nicID, e.NetProto, v.InterfaceAddr)
   580  		}
   581  		if nicID == 0 {
   582  			return tcpip.ErrUnknownDevice
   583  		}
   584  
   585  		memToRemove := multicastMembership{nicID: nicID, multicastAddr: v.MulticastAddr}
   586  		memToRemoveIndex := -1
   587  
   588  		e.mu.Lock()
   589  		defer e.mu.Unlock()
   590  
   591  		for i, mem := range e.multicastMemberships {
   592  			if mem == memToRemove {
   593  				memToRemoveIndex = i
   594  				break
   595  			}
   596  		}
   597  		if memToRemoveIndex == -1 {
   598  			return tcpip.ErrBadLocalAddress
   599  		}
   600  
   601  		if err := e.stack.LeaveGroup(e.NetProto, nicID, v.MulticastAddr); err != nil {
   602  			return err
   603  		}
   604  
   605  		e.multicastMemberships[memToRemoveIndex] = e.multicastMemberships[len(e.multicastMemberships)-1]
   606  		e.multicastMemberships = e.multicastMemberships[:len(e.multicastMemberships)-1]
   607  
   608  	case tcpip.MulticastLoopOption:
   609  		e.mu.Lock()
   610  		e.multicastLoop = bool(v)
   611  		e.mu.Unlock()
   612  
   613  	case tcpip.ReusePortOption:
   614  		e.mu.Lock()
   615  		e.reusePort = v != 0
   616  		e.mu.Unlock()
   617  
   618  	case tcpip.BindToDeviceOption:
   619  		e.mu.Lock()
   620  		defer e.mu.Unlock()
   621  		if v == "" {
   622  			e.bindToDevice = 0
   623  			return nil
   624  		}
   625  		for nicID, nic := range e.stack.NICInfo() {
   626  			if nic.Name == string(v) {
   627  				e.bindToDevice = nicID
   628  				return nil
   629  			}
   630  		}
   631  		return tcpip.ErrUnknownDevice
   632  
   633  	case tcpip.BroadcastOption:
   634  		e.mu.Lock()
   635  		e.broadcast = v != 0
   636  		e.mu.Unlock()
   637  
   638  		return nil
   639  
   640  	case tcpip.IPv4TOSOption:
   641  		e.mu.Lock()
   642  		e.sendTOS = uint8(v)
   643  		e.mu.Unlock()
   644  		return nil
   645  
   646  	case tcpip.IPv6TrafficClassOption:
   647  		e.mu.Lock()
   648  		e.sendTOS = uint8(v)
   649  		e.mu.Unlock()
   650  		return nil
   651  	}
   652  	return nil
   653  }
   654  
   655  // GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
   656  func (e *endpoint) GetSockOptInt(opt tcpip.SockOpt) (int, *tcpip.Error) {
   657  	switch opt {
   658  	case tcpip.ReceiveQueueSizeOption:
   659  		v := 0
   660  		e.rcvMu.Lock()
   661  		if !e.rcvList.Empty() {
   662  			p := e.rcvList.Front()
   663  			v = p.data.Size()
   664  		}
   665  		e.rcvMu.Unlock()
   666  		return v, nil
   667  
   668  	case tcpip.SendBufferSizeOption:
   669  		e.mu.Lock()
   670  		v := e.sndBufSize
   671  		e.mu.Unlock()
   672  		return v, nil
   673  
   674  	case tcpip.ReceiveBufferSizeOption:
   675  		e.rcvMu.Lock()
   676  		v := e.rcvBufSizeMax
   677  		e.rcvMu.Unlock()
   678  		return v, nil
   679  	}
   680  
   681  	return -1, tcpip.ErrUnknownProtocolOption
   682  }
   683  
   684  // GetSockOpt implements tcpip.Endpoint.GetSockOpt.
   685  func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
   686  	switch o := opt.(type) {
   687  	case tcpip.ErrorOption:
   688  		return nil
   689  
   690  	case *tcpip.V6OnlyOption:
   691  		// We only recognize this option on v6 endpoints.
   692  		if e.NetProto != header.IPv6ProtocolNumber {
   693  			return tcpip.ErrUnknownProtocolOption
   694  		}
   695  
   696  		e.mu.Lock()
   697  		v := e.v6only
   698  		e.mu.Unlock()
   699  
   700  		*o = 0
   701  		if v {
   702  			*o = 1
   703  		}
   704  		return nil
   705  
   706  	case *tcpip.TTLOption:
   707  		e.mu.Lock()
   708  		*o = tcpip.TTLOption(e.ttl)
   709  		e.mu.Unlock()
   710  		return nil
   711  
   712  	case *tcpip.MulticastTTLOption:
   713  		e.mu.Lock()
   714  		*o = tcpip.MulticastTTLOption(e.multicastTTL)
   715  		e.mu.Unlock()
   716  		return nil
   717  
   718  	case *tcpip.MulticastInterfaceOption:
   719  		e.mu.Lock()
   720  		*o = tcpip.MulticastInterfaceOption{
   721  			e.multicastNICID,
   722  			e.multicastAddr,
   723  		}
   724  		e.mu.Unlock()
   725  		return nil
   726  
   727  	case *tcpip.MulticastLoopOption:
   728  		e.mu.RLock()
   729  		v := e.multicastLoop
   730  		e.mu.RUnlock()
   731  
   732  		*o = tcpip.MulticastLoopOption(v)
   733  		return nil
   734  
   735  	case *tcpip.ReuseAddressOption:
   736  		*o = 0
   737  		return nil
   738  
   739  	case *tcpip.ReusePortOption:
   740  		e.mu.RLock()
   741  		v := e.reusePort
   742  		e.mu.RUnlock()
   743  
   744  		*o = 0
   745  		if v {
   746  			*o = 1
   747  		}
   748  		return nil
   749  
   750  	case *tcpip.BindToDeviceOption:
   751  		e.mu.RLock()
   752  		defer e.mu.RUnlock()
   753  		if nic, ok := e.stack.NICInfo()[e.bindToDevice]; ok {
   754  			*o = tcpip.BindToDeviceOption(nic.Name)
   755  			return nil
   756  		}
   757  		*o = tcpip.BindToDeviceOption("")
   758  		return nil
   759  
   760  	case *tcpip.KeepaliveEnabledOption:
   761  		*o = 0
   762  		return nil
   763  
   764  	case *tcpip.BroadcastOption:
   765  		e.mu.RLock()
   766  		v := e.broadcast
   767  		e.mu.RUnlock()
   768  
   769  		*o = 0
   770  		if v {
   771  			*o = 1
   772  		}
   773  		return nil
   774  
   775  	case *tcpip.IPv4TOSOption:
   776  		e.mu.RLock()
   777  		*o = tcpip.IPv4TOSOption(e.sendTOS)
   778  		e.mu.RUnlock()
   779  		return nil
   780  
   781  	case *tcpip.IPv6TrafficClassOption:
   782  		e.mu.RLock()
   783  		*o = tcpip.IPv6TrafficClassOption(e.sendTOS)
   784  		e.mu.RUnlock()
   785  		return nil
   786  
   787  	default:
   788  		return tcpip.ErrUnknownProtocolOption
   789  	}
   790  }
   791  
   792  // sendUDP sends a UDP segment via the provided network endpoint and under the
   793  // provided identity.
   794  func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, ttl uint8, useDefaultTTL bool, tos uint8) *tcpip.Error {
   795  	// Allocate a buffer for the UDP header.
   796  	hdr := buffer.NewPrependable(header.UDPMinimumSize + int(r.MaxHeaderLength()))
   797  
   798  	// Initialize the header.
   799  	udp := header.UDP(hdr.Prepend(header.UDPMinimumSize))
   800  
   801  	length := uint16(hdr.UsedLength() + data.Size())
   802  	udp.Encode(&header.UDPFields{
   803  		SrcPort: localPort,
   804  		DstPort: remotePort,
   805  		Length:  length,
   806  	})
   807  
   808  	// Only calculate the checksum if offloading isn't supported.
   809  	if r.Capabilities()&stack.CapabilityTXChecksumOffload == 0 {
   810  		xsum := r.PseudoHeaderChecksum(ProtocolNumber, length)
   811  		for _, v := range data.Views() {
   812  			xsum = header.Checksum(v, xsum)
   813  		}
   814  		udp.SetChecksum(^udp.CalculateChecksum(xsum))
   815  	}
   816  
   817  	if useDefaultTTL {
   818  		ttl = r.DefaultTTL()
   819  	}
   820  	if err := r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{Protocol: ProtocolNumber, TTL: ttl, TOS: tos}, tcpip.PacketBuffer{
   821  		Header: hdr,
   822  		Data:   data,
   823  	}); err != nil {
   824  		r.Stats().UDP.PacketSendErrors.Increment()
   825  		return err
   826  	}
   827  
   828  	// Track count of packets sent.
   829  	r.Stats().UDP.PacketsSent.Increment()
   830  	return nil
   831  }
   832  
   833  func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) {
   834  	netProto := e.NetProto
   835  	if len(addr.Addr) == 0 {
   836  		return netProto, nil
   837  	}
   838  	if header.IsV4MappedAddress(addr.Addr) {
   839  		// Fail if using a v4 mapped address on a v6only endpoint.
   840  		if e.v6only {
   841  			return 0, tcpip.ErrNoRoute
   842  		}
   843  
   844  		netProto = header.IPv4ProtocolNumber
   845  		addr.Addr = addr.Addr[header.IPv6AddressSize-header.IPv4AddressSize:]
   846  		if addr.Addr == header.IPv4Any {
   847  			addr.Addr = ""
   848  		}
   849  
   850  		// Fail if we are bound to an IPv6 address.
   851  		if !allowMismatch && len(e.ID.LocalAddress) == 16 {
   852  			return 0, tcpip.ErrNetworkUnreachable
   853  		}
   854  	}
   855  
   856  	// Fail if we're bound to an address length different from the one we're
   857  	// checking.
   858  	if l := len(e.ID.LocalAddress); l != 0 && l != len(addr.Addr) {
   859  		return 0, tcpip.ErrInvalidEndpointState
   860  	}
   861  
   862  	return netProto, nil
   863  }
   864  
   865  // Disconnect implements tcpip.Endpoint.Disconnect.
   866  func (e *endpoint) Disconnect() *tcpip.Error {
   867  	e.mu.Lock()
   868  	defer e.mu.Unlock()
   869  
   870  	if e.state != StateConnected {
   871  		return nil
   872  	}
   873  	id := stack.TransportEndpointID{}
   874  	// Exclude ephemerally bound endpoints.
   875  	if e.BindNICID != 0 || e.ID.LocalAddress == "" {
   876  		var err *tcpip.Error
   877  		id = stack.TransportEndpointID{
   878  			LocalPort:    e.ID.LocalPort,
   879  			LocalAddress: e.ID.LocalAddress,
   880  		}
   881  		id, err = e.registerWithStack(e.RegisterNICID, e.effectiveNetProtos, id)
   882  		if err != nil {
   883  			return err
   884  		}
   885  		e.state = StateBound
   886  	} else {
   887  		if e.ID.LocalPort != 0 {
   888  			// Release the ephemeral port.
   889  			e.stack.ReleasePort(e.effectiveNetProtos, ProtocolNumber, e.ID.LocalAddress, e.ID.LocalPort, e.bindToDevice)
   890  		}
   891  		e.state = StateInitial
   892  	}
   893  
   894  	e.stack.UnregisterTransportEndpoint(e.RegisterNICID, e.effectiveNetProtos, ProtocolNumber, e.ID, e, e.bindToDevice)
   895  	e.ID = id
   896  	e.route.Release()
   897  	e.route = stack.Route{}
   898  	e.dstPort = 0
   899  
   900  	return nil
   901  }
   902  
   903  // Connect connects the endpoint to its peer. Specifying a NIC is optional.
   904  func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error {
   905  	netProto, err := e.checkV4Mapped(&addr, false)
   906  	if err != nil {
   907  		return err
   908  	}
   909  	if addr.Port == 0 {
   910  		// We don't support connecting to port zero.
   911  		return tcpip.ErrInvalidEndpointState
   912  	}
   913  
   914  	e.mu.Lock()
   915  	defer e.mu.Unlock()
   916  
   917  	nicID := addr.NIC
   918  	var localPort uint16
   919  	switch e.state {
   920  	case StateInitial:
   921  	case StateBound, StateConnected:
   922  		localPort = e.ID.LocalPort
   923  		if e.BindNICID == 0 {
   924  			break
   925  		}
   926  
   927  		if nicID != 0 && nicID != e.BindNICID {
   928  			return tcpip.ErrInvalidEndpointState
   929  		}
   930  
   931  		nicID = e.BindNICID
   932  	default:
   933  		return tcpip.ErrInvalidEndpointState
   934  	}
   935  
   936  	r, nicID, err := e.connectRoute(nicID, addr, netProto)
   937  	if err != nil {
   938  		return err
   939  	}
   940  	defer r.Release()
   941  
   942  	id := stack.TransportEndpointID{
   943  		LocalAddress:  e.ID.LocalAddress,
   944  		LocalPort:     localPort,
   945  		RemotePort:    addr.Port,
   946  		RemoteAddress: r.RemoteAddress,
   947  	}
   948  
   949  	if e.state == StateInitial {
   950  		id.LocalAddress = r.LocalAddress
   951  	}
   952  
   953  	// Even if we're connected, this endpoint can still be used to send
   954  	// packets on a different network protocol, so we register both even if
   955  	// v6only is set to false and this is an ipv6 endpoint.
   956  	netProtos := []tcpip.NetworkProtocolNumber{netProto}
   957  	if netProto == header.IPv6ProtocolNumber && !e.v6only {
   958  		netProtos = []tcpip.NetworkProtocolNumber{
   959  			header.IPv4ProtocolNumber,
   960  			header.IPv6ProtocolNumber,
   961  		}
   962  	}
   963  
   964  	id, err = e.registerWithStack(nicID, netProtos, id)
   965  	if err != nil {
   966  		return err
   967  	}
   968  
   969  	// Remove the old registration.
   970  	if e.ID.LocalPort != 0 {
   971  		e.stack.UnregisterTransportEndpoint(e.RegisterNICID, e.effectiveNetProtos, ProtocolNumber, e.ID, e, e.bindToDevice)
   972  	}
   973  
   974  	e.ID = id
   975  	e.route = r.Clone()
   976  	e.dstPort = addr.Port
   977  	e.RegisterNICID = nicID
   978  	e.effectiveNetProtos = netProtos
   979  
   980  	e.state = StateConnected
   981  
   982  	e.rcvMu.Lock()
   983  	e.rcvReady = true
   984  	e.rcvMu.Unlock()
   985  
   986  	return nil
   987  }
   988  
   989  // ConnectEndpoint is not supported.
   990  func (*endpoint) ConnectEndpoint(tcpip.Endpoint) *tcpip.Error {
   991  	return tcpip.ErrInvalidEndpointState
   992  }
   993  
   994  // Shutdown closes the read and/or write end of the endpoint connection
   995  // to its peer.
   996  func (e *endpoint) Shutdown(flags tcpip.ShutdownFlags) *tcpip.Error {
   997  	e.mu.Lock()
   998  	defer e.mu.Unlock()
   999  
  1000  	// A socket in the bound state can still receive multicast messages,
  1001  	// so we need to notify waiters on shutdown.
  1002  	if e.state != StateBound && e.state != StateConnected {
  1003  		return tcpip.ErrNotConnected
  1004  	}
  1005  
  1006  	e.shutdownFlags |= flags
  1007  
  1008  	if flags&tcpip.ShutdownRead != 0 {
  1009  		e.rcvMu.Lock()
  1010  		wasClosed := e.rcvClosed
  1011  		e.rcvClosed = true
  1012  		e.rcvMu.Unlock()
  1013  
  1014  		if !wasClosed {
  1015  			e.waiterQueue.Notify(waiter.EventIn)
  1016  		}
  1017  	}
  1018  
  1019  	return nil
  1020  }
  1021  
  1022  // Listen is not supported by UDP, it just fails.
  1023  func (*endpoint) Listen(int) *tcpip.Error {
  1024  	return tcpip.ErrNotSupported
  1025  }
  1026  
  1027  // Accept is not supported by UDP, it just fails.
  1028  func (*endpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) {
  1029  	return nil, nil, tcpip.ErrNotSupported
  1030  }
  1031  
  1032  func (e *endpoint) registerWithStack(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, id stack.TransportEndpointID) (stack.TransportEndpointID, *tcpip.Error) {
  1033  	if e.ID.LocalPort == 0 {
  1034  		port, err := e.stack.ReservePort(netProtos, ProtocolNumber, id.LocalAddress, id.LocalPort, e.reusePort, e.bindToDevice)
  1035  		if err != nil {
  1036  			return id, err
  1037  		}
  1038  		id.LocalPort = port
  1039  	}
  1040  
  1041  	err := e.stack.RegisterTransportEndpoint(nicID, netProtos, ProtocolNumber, id, e, e.reusePort, e.bindToDevice)
  1042  	if err != nil {
  1043  		e.stack.ReleasePort(netProtos, ProtocolNumber, id.LocalAddress, id.LocalPort, e.bindToDevice)
  1044  	}
  1045  	return id, err
  1046  }
  1047  
  1048  func (e *endpoint) bindLocked(addr tcpip.FullAddress) *tcpip.Error {
  1049  	// Don't allow binding once endpoint is not in the initial state
  1050  	// anymore.
  1051  	if e.state != StateInitial {
  1052  		return tcpip.ErrInvalidEndpointState
  1053  	}
  1054  
  1055  	netProto, err := e.checkV4Mapped(&addr, true)
  1056  	if err != nil {
  1057  		return err
  1058  	}
  1059  
  1060  	// Expand netProtos to include v4 and v6 if the caller is binding to a
  1061  	// wildcard (empty) address, and this is an IPv6 endpoint with v6only
  1062  	// set to false.
  1063  	netProtos := []tcpip.NetworkProtocolNumber{netProto}
  1064  	if netProto == header.IPv6ProtocolNumber && !e.v6only && addr.Addr == "" {
  1065  		netProtos = []tcpip.NetworkProtocolNumber{
  1066  			header.IPv6ProtocolNumber,
  1067  			header.IPv4ProtocolNumber,
  1068  		}
  1069  	}
  1070  
  1071  	nicID := addr.NIC
  1072  	if len(addr.Addr) != 0 && !isBroadcastOrMulticast(addr.Addr) {
  1073  		// A local unicast address was specified, verify that it's valid.
  1074  		nicID = e.stack.CheckLocalAddress(addr.NIC, netProto, addr.Addr)
  1075  		if nicID == 0 {
  1076  			return tcpip.ErrBadLocalAddress
  1077  		}
  1078  	}
  1079  
  1080  	id := stack.TransportEndpointID{
  1081  		LocalPort:    addr.Port,
  1082  		LocalAddress: addr.Addr,
  1083  	}
  1084  	id, err = e.registerWithStack(nicID, netProtos, id)
  1085  	if err != nil {
  1086  		return err
  1087  	}
  1088  
  1089  	e.ID = id
  1090  	e.RegisterNICID = nicID
  1091  	e.effectiveNetProtos = netProtos
  1092  
  1093  	// Mark endpoint as bound.
  1094  	e.state = StateBound
  1095  
  1096  	e.rcvMu.Lock()
  1097  	e.rcvReady = true
  1098  	e.rcvMu.Unlock()
  1099  
  1100  	return nil
  1101  }
  1102  
  1103  // Bind binds the endpoint to a specific local address and port.
  1104  // Specifying a NIC is optional.
  1105  func (e *endpoint) Bind(addr tcpip.FullAddress) *tcpip.Error {
  1106  	e.mu.Lock()
  1107  	defer e.mu.Unlock()
  1108  
  1109  	err := e.bindLocked(addr)
  1110  	if err != nil {
  1111  		return err
  1112  	}
  1113  
  1114  	// Save the effective NICID generated by bindLocked.
  1115  	e.BindNICID = e.RegisterNICID
  1116  
  1117  	return nil
  1118  }
  1119  
  1120  // GetLocalAddress returns the address to which the endpoint is bound.
  1121  func (e *endpoint) GetLocalAddress() (tcpip.FullAddress, *tcpip.Error) {
  1122  	e.mu.RLock()
  1123  	defer e.mu.RUnlock()
  1124  
  1125  	return tcpip.FullAddress{
  1126  		NIC:  e.RegisterNICID,
  1127  		Addr: e.ID.LocalAddress,
  1128  		Port: e.ID.LocalPort,
  1129  	}, nil
  1130  }
  1131  
  1132  // GetRemoteAddress returns the address to which the endpoint is connected.
  1133  func (e *endpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Error) {
  1134  	e.mu.RLock()
  1135  	defer e.mu.RUnlock()
  1136  
  1137  	if e.state != StateConnected {
  1138  		return tcpip.FullAddress{}, tcpip.ErrNotConnected
  1139  	}
  1140  
  1141  	return tcpip.FullAddress{
  1142  		NIC:  e.RegisterNICID,
  1143  		Addr: e.ID.RemoteAddress,
  1144  		Port: e.ID.RemotePort,
  1145  	}, nil
  1146  }
  1147  
  1148  // Readiness returns the current readiness of the endpoint. For example, if
  1149  // waiter.EventIn is set, the endpoint is immediately readable.
  1150  func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask {
  1151  	// The endpoint is always writable.
  1152  	result := waiter.EventOut & mask
  1153  
  1154  	// Determine if the endpoint is readable if requested.
  1155  	if (mask & waiter.EventIn) != 0 {
  1156  		e.rcvMu.Lock()
  1157  		if !e.rcvList.Empty() || e.rcvClosed {
  1158  			result |= waiter.EventIn
  1159  		}
  1160  		e.rcvMu.Unlock()
  1161  	}
  1162  
  1163  	return result
  1164  }
  1165  
  1166  // HandlePacket is called by the stack when new packets arrive to this transport
  1167  // endpoint.
  1168  func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, pkt tcpip.PacketBuffer) {
  1169  	// Get the header then trim it from the view.
  1170  	hdr := header.UDP(pkt.Data.First())
  1171  	if int(hdr.Length()) > pkt.Data.Size() {
  1172  		// Malformed packet.
  1173  		e.stack.Stats().UDP.MalformedPacketsReceived.Increment()
  1174  		e.stats.ReceiveErrors.MalformedPacketsReceived.Increment()
  1175  		return
  1176  	}
  1177  
  1178  	pkt.Data.TrimFront(header.UDPMinimumSize)
  1179  
  1180  	e.rcvMu.Lock()
  1181  	e.stack.Stats().UDP.PacketsReceived.Increment()
  1182  	e.stats.PacketsReceived.Increment()
  1183  
  1184  	// Drop the packet if our buffer is currently full.
  1185  	if !e.rcvReady || e.rcvClosed {
  1186  		e.rcvMu.Unlock()
  1187  		e.stack.Stats().UDP.ReceiveBufferErrors.Increment()
  1188  		e.stats.ReceiveErrors.ClosedReceiver.Increment()
  1189  		return
  1190  	}
  1191  
  1192  	if e.rcvBufSize >= e.rcvBufSizeMax {
  1193  		e.rcvMu.Unlock()
  1194  		e.stack.Stats().UDP.ReceiveBufferErrors.Increment()
  1195  		e.stats.ReceiveErrors.ReceiveBufferOverflow.Increment()
  1196  		return
  1197  	}
  1198  
  1199  	wasEmpty := e.rcvBufSize == 0
  1200  
  1201  	// Push new packet into receive list and increment the buffer size.
  1202  	packet := &udpPacket{
  1203  		senderAddress: tcpip.FullAddress{
  1204  			NIC:  r.NICID(),
  1205  			Addr: id.RemoteAddress,
  1206  			Port: hdr.SourcePort(),
  1207  		},
  1208  	}
  1209  	packet.data = pkt.Data
  1210  	e.rcvList.PushBack(packet)
  1211  	e.rcvBufSize += pkt.Data.Size()
  1212  
  1213  	packet.timestamp = e.stack.NowNanoseconds()
  1214  
  1215  	e.rcvMu.Unlock()
  1216  
  1217  	// Notify any waiters that there's data to be read now.
  1218  	if wasEmpty {
  1219  		e.waiterQueue.Notify(waiter.EventIn)
  1220  	}
  1221  }
  1222  
  1223  // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket.
  1224  func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, pkt tcpip.PacketBuffer) {
  1225  }
  1226  
  1227  // State implements tcpip.Endpoint.State.
  1228  func (e *endpoint) State() uint32 {
  1229  	e.mu.Lock()
  1230  	defer e.mu.Unlock()
  1231  	return uint32(e.state)
  1232  }
  1233  
  1234  // Info returns a copy of the endpoint info.
  1235  func (e *endpoint) Info() tcpip.EndpointInfo {
  1236  	e.mu.RLock()
  1237  	// Make a copy of the endpoint info.
  1238  	ret := e.TransportEndpointInfo
  1239  	e.mu.RUnlock()
  1240  	return &ret
  1241  }
  1242  
  1243  // Stats returns a pointer to the endpoint stats.
  1244  func (e *endpoint) Stats() tcpip.EndpointStats {
  1245  	return &e.stats
  1246  }
  1247  
  1248  // Wait implements tcpip.Endpoint.Wait.
  1249  func (*endpoint) Wait() {}
  1250  
  1251  func isBroadcastOrMulticast(a tcpip.Address) bool {
  1252  	return a == header.IPv4Broadcast || header.IsV4MulticastAddress(a) || header.IsV6MulticastAddress(a)
  1253  }