github.com/lightlus/netstack@v1.2.0/tcpip/tcpip.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 tcpip provides the interfaces and related types that users of the
    16  // tcpip stack will use in order to create endpoints used to send and receive
    17  // data over the network stack.
    18  //
    19  // The starting point is the creation and configuration of a stack. A stack can
    20  // be created by calling the New() function of the tcpip/stack/stack package;
    21  // configuring a stack involves creating NICs (via calls to Stack.CreateNIC()),
    22  // adding network addresses (via calls to Stack.AddAddress()), and
    23  // setting a route table (via a call to Stack.SetRouteTable()).
    24  //
    25  // Once a stack is configured, endpoints can be created by calling
    26  // Stack.NewEndpoint(). Such endpoints can be used to send/receive data, connect
    27  // to peers, listen for connections, accept connections, etc., depending on the
    28  // transport protocol selected.
    29  package tcpip
    30  
    31  import (
    32  	"errors"
    33  	"fmt"
    34  	"math/bits"
    35  	"reflect"
    36  	"strconv"
    37  	"strings"
    38  	"sync"
    39  	"sync/atomic"
    40  	"time"
    41  
    42  	"github.com/lightlus/netstack/tcpip/buffer"
    43  	"github.com/lightlus/netstack/tcpip/iptables"
    44  	"github.com/lightlus/netstack/waiter"
    45  )
    46  
    47  // Error represents an error in the netstack error space. Using a special type
    48  // ensures that errors outside of this space are not accidentally introduced.
    49  //
    50  // Note: to support save / restore, it is important that all tcpip errors have
    51  // distinct error messages.
    52  type Error struct {
    53  	msg string
    54  
    55  	ignoreStats bool
    56  }
    57  
    58  // String implements fmt.Stringer.String.
    59  func (e *Error) String() string {
    60  	if e == nil {
    61  		return "<nil>"
    62  	}
    63  	return e.msg
    64  }
    65  
    66  // IgnoreStats indicates whether this error type should be included in failure
    67  // counts in tcpip.Stats structs.
    68  func (e *Error) IgnoreStats() bool {
    69  	return e.ignoreStats
    70  }
    71  
    72  // Errors that can be returned by the network stack.
    73  var (
    74  	ErrUnknownProtocol           = &Error{msg: "unknown protocol"}
    75  	ErrUnknownNICID              = &Error{msg: "unknown nic id"}
    76  	ErrUnknownDevice             = &Error{msg: "unknown device"}
    77  	ErrUnknownProtocolOption     = &Error{msg: "unknown option for protocol"}
    78  	ErrDuplicateNICID            = &Error{msg: "duplicate nic id"}
    79  	ErrDuplicateAddress          = &Error{msg: "duplicate address"}
    80  	ErrNoRoute                   = &Error{msg: "no route"}
    81  	ErrBadLinkEndpoint           = &Error{msg: "bad link layer endpoint"}
    82  	ErrAlreadyBound              = &Error{msg: "endpoint already bound", ignoreStats: true}
    83  	ErrInvalidEndpointState      = &Error{msg: "endpoint is in invalid state"}
    84  	ErrAlreadyConnecting         = &Error{msg: "endpoint is already connecting", ignoreStats: true}
    85  	ErrAlreadyConnected          = &Error{msg: "endpoint is already connected", ignoreStats: true}
    86  	ErrNoPortAvailable           = &Error{msg: "no ports are available"}
    87  	ErrPortInUse                 = &Error{msg: "port is in use"}
    88  	ErrBadLocalAddress           = &Error{msg: "bad local address"}
    89  	ErrClosedForSend             = &Error{msg: "endpoint is closed for send"}
    90  	ErrClosedForReceive          = &Error{msg: "endpoint is closed for receive"}
    91  	ErrWouldBlock                = &Error{msg: "operation would block", ignoreStats: true}
    92  	ErrConnectionRefused         = &Error{msg: "connection was refused"}
    93  	ErrTimeout                   = &Error{msg: "operation timed out"}
    94  	ErrAborted                   = &Error{msg: "operation aborted"}
    95  	ErrConnectStarted            = &Error{msg: "connection attempt started", ignoreStats: true}
    96  	ErrDestinationRequired       = &Error{msg: "destination address is required"}
    97  	ErrNotSupported              = &Error{msg: "operation not supported"}
    98  	ErrQueueSizeNotSupported     = &Error{msg: "queue size querying not supported"}
    99  	ErrNotConnected              = &Error{msg: "endpoint not connected"}
   100  	ErrConnectionReset           = &Error{msg: "connection reset by peer"}
   101  	ErrConnectionAborted         = &Error{msg: "connection aborted"}
   102  	ErrNoSuchFile                = &Error{msg: "no such file"}
   103  	ErrInvalidOptionValue        = &Error{msg: "invalid option value specified"}
   104  	ErrNoLinkAddress             = &Error{msg: "no remote link address"}
   105  	ErrBadAddress                = &Error{msg: "bad address"}
   106  	ErrNetworkUnreachable        = &Error{msg: "network is unreachable"}
   107  	ErrMessageTooLong            = &Error{msg: "message too long"}
   108  	ErrNoBufferSpace             = &Error{msg: "no buffer space available"}
   109  	ErrBroadcastDisabled         = &Error{msg: "broadcast socket option disabled"}
   110  	ErrNotPermitted              = &Error{msg: "operation not permitted"}
   111  	ErrAddressFamilyNotSupported = &Error{msg: "address family not supported by protocol"}
   112  )
   113  
   114  // Errors related to Subnet
   115  var (
   116  	errSubnetLengthMismatch = errors.New("subnet length of address and mask differ")
   117  	errSubnetAddressMasked  = errors.New("subnet address has bits set outside the mask")
   118  )
   119  
   120  // ErrSaveRejection indicates a failed save due to unsupported networking state.
   121  // This type of errors is only used for save logic.
   122  type ErrSaveRejection struct {
   123  	Err error
   124  }
   125  
   126  // Error returns a sensible description of the save rejection error.
   127  func (e ErrSaveRejection) Error() string {
   128  	return "save rejected due to unsupported networking state: " + e.Err.Error()
   129  }
   130  
   131  // A Clock provides the current time.
   132  //
   133  // Times returned by a Clock should always be used for application-visible
   134  // time. Only monotonic times should be used for netstack internal timekeeping.
   135  type Clock interface {
   136  	// NowNanoseconds returns the current real time as a number of
   137  	// nanoseconds since the Unix epoch.
   138  	NowNanoseconds() int64
   139  
   140  	// NowMonotonic returns a monotonic time value.
   141  	NowMonotonic() int64
   142  }
   143  
   144  // Address is a byte slice cast as a string that represents the address of a
   145  // network node. Or, in the case of unix endpoints, it may represent a path.
   146  type Address string
   147  
   148  // AddressMask is a bitmask for an address.
   149  type AddressMask string
   150  
   151  // String implements Stringer.
   152  func (m AddressMask) String() string {
   153  	return Address(m).String()
   154  }
   155  
   156  // Prefix returns the number of bits before the first host bit.
   157  func (m AddressMask) Prefix() int {
   158  	p := 0
   159  	for _, b := range []byte(m) {
   160  		p += bits.LeadingZeros8(^b)
   161  	}
   162  	return p
   163  }
   164  
   165  // Subnet is a subnet defined by its address and mask.
   166  type Subnet struct {
   167  	address Address
   168  	mask    AddressMask
   169  }
   170  
   171  // NewSubnet creates a new Subnet, checking that the address and mask are the same length.
   172  func NewSubnet(a Address, m AddressMask) (Subnet, error) {
   173  	if len(a) != len(m) {
   174  		return Subnet{}, errSubnetLengthMismatch
   175  	}
   176  	for i := 0; i < len(a); i++ {
   177  		if a[i]&^m[i] != 0 {
   178  			return Subnet{}, errSubnetAddressMasked
   179  		}
   180  	}
   181  	return Subnet{a, m}, nil
   182  }
   183  
   184  // String implements Stringer.
   185  func (s Subnet) String() string {
   186  	return fmt.Sprintf("%s/%d", s.ID(), s.Prefix())
   187  }
   188  
   189  // Contains returns true iff the address is of the same length and matches the
   190  // subnet address and mask.
   191  func (s *Subnet) Contains(a Address) bool {
   192  	if len(a) != len(s.address) {
   193  		return false
   194  	}
   195  	for i := 0; i < len(a); i++ {
   196  		if a[i]&s.mask[i] != s.address[i] {
   197  			return false
   198  		}
   199  	}
   200  	return true
   201  }
   202  
   203  // ID returns the subnet ID.
   204  func (s *Subnet) ID() Address {
   205  	return s.address
   206  }
   207  
   208  // Bits returns the number of ones (network bits) and zeros (host bits) in the
   209  // subnet mask.
   210  func (s *Subnet) Bits() (ones int, zeros int) {
   211  	ones = s.mask.Prefix()
   212  	return ones, len(s.mask)*8 - ones
   213  }
   214  
   215  // Prefix returns the number of bits before the first host bit.
   216  func (s *Subnet) Prefix() int {
   217  	return s.mask.Prefix()
   218  }
   219  
   220  // Mask returns the subnet mask.
   221  func (s *Subnet) Mask() AddressMask {
   222  	return s.mask
   223  }
   224  
   225  // Broadcast returns the subnet's broadcast address.
   226  func (s *Subnet) Broadcast() Address {
   227  	addr := []byte(s.address)
   228  	for i := range addr {
   229  		addr[i] |= ^s.mask[i]
   230  	}
   231  	return Address(addr)
   232  }
   233  
   234  // Equal returns true if s equals o.
   235  //
   236  // Needed to use cmp.Equal on Subnet as its fields are unexported.
   237  func (s Subnet) Equal(o Subnet) bool {
   238  	return s == o
   239  }
   240  
   241  // NICID is a number that uniquely identifies a NIC.
   242  type NICID int32
   243  
   244  // ShutdownFlags represents flags that can be passed to the Shutdown() method
   245  // of the Endpoint interface.
   246  type ShutdownFlags int
   247  
   248  // Values of the flags that can be passed to the Shutdown() method. They can
   249  // be OR'ed together.
   250  const (
   251  	ShutdownRead ShutdownFlags = 1 << iota
   252  	ShutdownWrite
   253  )
   254  
   255  // FullAddress represents a full transport node address, as required by the
   256  // Connect() and Bind() methods.
   257  //
   258  // +stateify savable
   259  type FullAddress struct {
   260  	// NIC is the ID of the NIC this address refers to.
   261  	//
   262  	// This may not be used by all endpoint types.
   263  	NIC NICID
   264  
   265  	// Addr is the network or link layer address.
   266  	Addr Address
   267  
   268  	// Port is the transport port.
   269  	//
   270  	// This may not be used by all endpoint types.
   271  	Port uint16
   272  }
   273  
   274  // Payloader is an interface that provides data.
   275  //
   276  // This interface allows the endpoint to request the amount of data it needs
   277  // based on internal buffers without exposing them.
   278  type Payloader interface {
   279  	// FullPayload returns all available bytes.
   280  	FullPayload() ([]byte, *Error)
   281  
   282  	// Payload returns a slice containing at most size bytes.
   283  	Payload(size int) ([]byte, *Error)
   284  }
   285  
   286  // SlicePayload implements Payloader for slices.
   287  //
   288  // This is typically used for tests.
   289  type SlicePayload []byte
   290  
   291  // FullPayload implements Payloader.FullPayload.
   292  func (s SlicePayload) FullPayload() ([]byte, *Error) {
   293  	return s, nil
   294  }
   295  
   296  // Payload implements Payloader.Payload.
   297  func (s SlicePayload) Payload(size int) ([]byte, *Error) {
   298  	if size > len(s) {
   299  		size = len(s)
   300  	}
   301  	return s[:size], nil
   302  }
   303  
   304  // A ControlMessages contains socket control messages for IP sockets.
   305  //
   306  // +stateify savable
   307  type ControlMessages struct {
   308  	// HasTimestamp indicates whether Timestamp is valid/set.
   309  	HasTimestamp bool
   310  
   311  	// Timestamp is the time (in ns) that the last packed used to create
   312  	// the read data was received.
   313  	Timestamp int64
   314  
   315  	// HasInq indicates whether Inq is valid/set.
   316  	HasInq bool
   317  
   318  	// Inq is the number of bytes ready to be received.
   319  	Inq int32
   320  }
   321  
   322  // Endpoint is the interface implemented by transport protocols (e.g., tcp, udp)
   323  // that exposes functionality like read, write, connect, etc. to users of the
   324  // networking stack.
   325  type Endpoint interface {
   326  	// Close puts the endpoint in a closed state and frees all resources
   327  	// associated with it.
   328  	Close()
   329  
   330  	// Read reads data from the endpoint and optionally returns the sender.
   331  	//
   332  	// This method does not block if there is no data pending. It will also
   333  	// either return an error or data, never both.
   334  	Read(*FullAddress) (buffer.View, ControlMessages, *Error)
   335  
   336  	// Write writes data to the endpoint's peer. This method does not block if
   337  	// the data cannot be written.
   338  	//
   339  	// Unlike io.Writer.Write, Endpoint.Write transfers ownership of any bytes
   340  	// successfully written to the Endpoint. That is, if a call to
   341  	// Write(SlicePayload{data}) returns (n, err), it may retain data[:n], and
   342  	// the caller should not use data[:n] after Write returns.
   343  	//
   344  	// Note that unlike io.Writer.Write, it is not an error for Write to
   345  	// perform a partial write (if n > 0, no error may be returned). Only
   346  	// stream (TCP) Endpoints may return partial writes, and even then only
   347  	// in the case where writing additional data would block. Other Endpoints
   348  	// will either write the entire message or return an error.
   349  	//
   350  	// For UDP and Ping sockets if address resolution is required,
   351  	// ErrNoLinkAddress and a notification channel is returned for the caller to
   352  	// block. Channel is closed once address resolution is complete (success or
   353  	// not). The channel is only non-nil in this case.
   354  	Write(Payloader, WriteOptions) (int64, <-chan struct{}, *Error)
   355  
   356  	// Peek reads data without consuming it from the endpoint.
   357  	//
   358  	// This method does not block if there is no data pending.
   359  	Peek([][]byte) (int64, ControlMessages, *Error)
   360  
   361  	// Connect connects the endpoint to its peer. Specifying a NIC is
   362  	// optional.
   363  	//
   364  	// There are three classes of return values:
   365  	//	nil -- the attempt to connect succeeded.
   366  	//	ErrConnectStarted/ErrAlreadyConnecting -- the connect attempt started
   367  	//		but hasn't completed yet. In this case, the caller must call Connect
   368  	//		or GetSockOpt(ErrorOption) when the endpoint becomes writable to
   369  	//		get the actual result. The first call to Connect after the socket has
   370  	//		connected returns nil. Calling connect again results in ErrAlreadyConnected.
   371  	//	Anything else -- the attempt to connect failed.
   372  	//
   373  	// If address.Addr is empty, this means that Enpoint has to be
   374  	// disconnected if this is supported, otherwise
   375  	// ErrAddressFamilyNotSupported must be returned.
   376  	Connect(address FullAddress) *Error
   377  
   378  	// Disconnect disconnects the endpoint from its peer.
   379  	Disconnect() *Error
   380  
   381  	// Shutdown closes the read and/or write end of the endpoint connection
   382  	// to its peer.
   383  	Shutdown(flags ShutdownFlags) *Error
   384  
   385  	// Listen puts the endpoint in "listen" mode, which allows it to accept
   386  	// new connections.
   387  	Listen(backlog int) *Error
   388  
   389  	// Accept returns a new endpoint if a peer has established a connection
   390  	// to an endpoint previously set to listen mode. This method does not
   391  	// block if no new connections are available.
   392  	//
   393  	// The returned Queue is the wait queue for the newly created endpoint.
   394  	Accept() (Endpoint, *waiter.Queue, *Error)
   395  
   396  	// Bind binds the endpoint to a specific local address and port.
   397  	// Specifying a NIC is optional.
   398  	Bind(address FullAddress) *Error
   399  
   400  	// GetLocalAddress returns the address to which the endpoint is bound.
   401  	GetLocalAddress() (FullAddress, *Error)
   402  
   403  	// GetRemoteAddress returns the address to which the endpoint is
   404  	// connected.
   405  	GetRemoteAddress() (FullAddress, *Error)
   406  
   407  	// Readiness returns the current readiness of the endpoint. For example,
   408  	// if waiter.EventIn is set, the endpoint is immediately readable.
   409  	Readiness(mask waiter.EventMask) waiter.EventMask
   410  
   411  	// SetSockOpt sets a socket option. opt should be one of the *Option types.
   412  	SetSockOpt(opt interface{}) *Error
   413  
   414  	// SetSockOptInt sets a socket option, for simple cases where a value
   415  	// has the int type.
   416  	SetSockOptInt(opt SockOpt, v int) *Error
   417  
   418  	// GetSockOpt gets a socket option. opt should be a pointer to one of the
   419  	// *Option types.
   420  	GetSockOpt(opt interface{}) *Error
   421  
   422  	// GetSockOptInt gets a socket option for simple cases where a return
   423  	// value has the int type.
   424  	GetSockOptInt(SockOpt) (int, *Error)
   425  
   426  	// State returns a socket's lifecycle state. The returned value is
   427  	// protocol-specific and is primarily used for diagnostics.
   428  	State() uint32
   429  
   430  	// ModerateRecvBuf should be called everytime data is copied to the user
   431  	// space. This allows for dynamic tuning of recv buffer space for a
   432  	// given socket.
   433  	//
   434  	// NOTE: This method is a no-op for sockets other than TCP.
   435  	ModerateRecvBuf(copied int)
   436  
   437  	// IPTables returns the iptables for this endpoint's stack.
   438  	IPTables() (iptables.IPTables, error)
   439  
   440  	// Info returns a copy to the transport endpoint info.
   441  	Info() EndpointInfo
   442  
   443  	// Stats returns a reference to the endpoint stats.
   444  	Stats() EndpointStats
   445  }
   446  
   447  // EndpointInfo is the interface implemented by each endpoint info struct.
   448  type EndpointInfo interface {
   449  	// IsEndpointInfo is an empty method to implement the tcpip.EndpointInfo
   450  	// marker interface.
   451  	IsEndpointInfo()
   452  }
   453  
   454  // EndpointStats is the interface implemented by each endpoint stats struct.
   455  type EndpointStats interface {
   456  	// IsEndpointStats is an empty method to implement the tcpip.EndpointStats
   457  	// marker interface.
   458  	IsEndpointStats()
   459  }
   460  
   461  // WriteOptions contains options for Endpoint.Write.
   462  type WriteOptions struct {
   463  	// If To is not nil, write to the given address instead of the endpoint's
   464  	// peer.
   465  	To *FullAddress
   466  
   467  	// More has the same semantics as Linux's MSG_MORE.
   468  	More bool
   469  
   470  	// EndOfRecord has the same semantics as Linux's MSG_EOR.
   471  	EndOfRecord bool
   472  
   473  	// Atomic means that all data fetched from Payloader must be written to the
   474  	// endpoint. If Atomic is false, then data fetched from the Payloader may be
   475  	// discarded if available endpoint buffer space is unsufficient.
   476  	Atomic bool
   477  }
   478  
   479  // SockOpt represents socket options which values have the int type.
   480  type SockOpt int
   481  
   482  const (
   483  	// ReceiveQueueSizeOption is used in GetSockOptInt to specify that the
   484  	// number of unread bytes in the input buffer should be returned.
   485  	ReceiveQueueSizeOption SockOpt = iota
   486  
   487  	// SendBufferSizeOption is used by SetSockOptInt/GetSockOptInt to
   488  	// specify the send buffer size option.
   489  	SendBufferSizeOption
   490  
   491  	// ReceiveBufferSizeOption is used by SetSockOptInt/GetSockOptInt to
   492  	// specify the receive buffer size option.
   493  	ReceiveBufferSizeOption
   494  
   495  	// SendQueueSizeOption is used in GetSockOptInt to specify that the
   496  	// number of unread bytes in the output buffer should be returned.
   497  	SendQueueSizeOption
   498  
   499  	// DelayOption is used by SetSockOpt/GetSockOpt to specify if data
   500  	// should be sent out immediately by the transport protocol. For TCP,
   501  	// it determines if the Nagle algorithm is on or off.
   502  	DelayOption
   503  
   504  	// TODO(b/137664753): convert all int socket options to be handled via
   505  	// GetSockOptInt.
   506  )
   507  
   508  // ErrorOption is used in GetSockOpt to specify that the last error reported by
   509  // the endpoint should be cleared and returned.
   510  type ErrorOption struct{}
   511  
   512  // V6OnlyOption is used by SetSockOpt/GetSockOpt to specify whether an IPv6
   513  // socket is to be restricted to sending and receiving IPv6 packets only.
   514  type V6OnlyOption int
   515  
   516  // CorkOption is used by SetSockOpt/GetSockOpt to specify if data should be
   517  // held until segments are full by the TCP transport protocol.
   518  type CorkOption int
   519  
   520  // ReuseAddressOption is used by SetSockOpt/GetSockOpt to specify whether Bind()
   521  // should allow reuse of local address.
   522  type ReuseAddressOption int
   523  
   524  // ReusePortOption is used by SetSockOpt/GetSockOpt to permit multiple sockets
   525  // to be bound to an identical socket address.
   526  type ReusePortOption int
   527  
   528  // BindToDeviceOption is used by SetSockOpt/GetSockOpt to specify that sockets
   529  // should bind only on a specific NIC.
   530  type BindToDeviceOption string
   531  
   532  // QuickAckOption is stubbed out in SetSockOpt/GetSockOpt.
   533  type QuickAckOption int
   534  
   535  // PasscredOption is used by SetSockOpt/GetSockOpt to specify whether
   536  // SCM_CREDENTIALS socket control messages are enabled.
   537  //
   538  // Only supported on Unix sockets.
   539  type PasscredOption int
   540  
   541  // TCPInfoOption is used by GetSockOpt to expose TCP statistics.
   542  //
   543  // TODO(b/64800844): Add and populate stat fields.
   544  type TCPInfoOption struct {
   545  	RTT    time.Duration
   546  	RTTVar time.Duration
   547  }
   548  
   549  // KeepaliveEnabledOption is used by SetSockOpt/GetSockOpt to specify whether
   550  // TCP keepalive is enabled for this socket.
   551  type KeepaliveEnabledOption int
   552  
   553  // KeepaliveIdleOption is used by SetSockOpt/GetSockOpt to specify the time a
   554  // connection must remain idle before the first TCP keepalive packet is sent.
   555  // Once this time is reached, KeepaliveIntervalOption is used instead.
   556  type KeepaliveIdleOption time.Duration
   557  
   558  // KeepaliveIntervalOption is used by SetSockOpt/GetSockOpt to specify the
   559  // interval between sending TCP keepalive packets.
   560  type KeepaliveIntervalOption time.Duration
   561  
   562  // KeepaliveCountOption is used by SetSockOpt/GetSockOpt to specify the number
   563  // of un-ACKed TCP keepalives that will be sent before the connection is
   564  // closed.
   565  type KeepaliveCountOption int
   566  
   567  // CongestionControlOption is used by SetSockOpt/GetSockOpt to set/get
   568  // the current congestion control algorithm.
   569  type CongestionControlOption string
   570  
   571  // AvailableCongestionControlOption is used to query the supported congestion
   572  // control algorithms.
   573  type AvailableCongestionControlOption string
   574  
   575  // ModerateReceiveBufferOption allows the caller to enable/disable TCP receive
   576  // buffer moderation.
   577  type ModerateReceiveBufferOption bool
   578  
   579  // MaxSegOption is used by SetSockOpt/GetSockOpt to set/get the current
   580  // Maximum Segment Size(MSS) value as specified using the TCP_MAXSEG option.
   581  type MaxSegOption int
   582  
   583  // TTLOption is used by SetSockOpt/GetSockOpt to control the default TTL/hop
   584  // limit value for unicast messages. The default is protocol specific.
   585  //
   586  // A zero value indicates the default.
   587  type TTLOption uint8
   588  
   589  // TCPLingerTimeoutOption is used by SetSockOpt/GetSockOpt to set/get the
   590  // maximum duration for which a socket lingers in the TCP_FIN_WAIT_2 state
   591  // before being marked closed.
   592  type TCPLingerTimeoutOption time.Duration
   593  
   594  // TCPTimeWaitTimeoutOption is used by SetSockOpt/GetSockOpt to set/get the
   595  // maximum duration for which a socket lingers in the TIME_WAIT state
   596  // before being marked closed.
   597  type TCPTimeWaitTimeoutOption time.Duration
   598  
   599  // MulticastTTLOption is used by SetSockOpt/GetSockOpt to control the default
   600  // TTL value for multicast messages. The default is 1.
   601  type MulticastTTLOption uint8
   602  
   603  // MulticastInterfaceOption is used by SetSockOpt/GetSockOpt to specify a
   604  // default interface for multicast.
   605  type MulticastInterfaceOption struct {
   606  	NIC           NICID
   607  	InterfaceAddr Address
   608  }
   609  
   610  // MulticastLoopOption is used by SetSockOpt/GetSockOpt to specify whether
   611  // multicast packets sent over a non-loopback interface will be looped back.
   612  type MulticastLoopOption bool
   613  
   614  // MembershipOption is used by SetSockOpt/GetSockOpt as an argument to
   615  // AddMembershipOption and RemoveMembershipOption.
   616  type MembershipOption struct {
   617  	NIC           NICID
   618  	InterfaceAddr Address
   619  	MulticastAddr Address
   620  }
   621  
   622  // AddMembershipOption is used by SetSockOpt/GetSockOpt to join a multicast
   623  // group identified by the given multicast address, on the interface matching
   624  // the given interface address.
   625  type AddMembershipOption MembershipOption
   626  
   627  // RemoveMembershipOption is used by SetSockOpt/GetSockOpt to leave a multicast
   628  // group identified by the given multicast address, on the interface matching
   629  // the given interface address.
   630  type RemoveMembershipOption MembershipOption
   631  
   632  // OutOfBandInlineOption is used by SetSockOpt/GetSockOpt to specify whether
   633  // TCP out-of-band data is delivered along with the normal in-band data.
   634  type OutOfBandInlineOption int
   635  
   636  // BroadcastOption is used by SetSockOpt/GetSockOpt to specify whether
   637  // datagram sockets are allowed to send packets to a broadcast address.
   638  type BroadcastOption int
   639  
   640  // DefaultTTLOption is used by stack.(*Stack).NetworkProtocolOption to specify
   641  // a default TTL.
   642  type DefaultTTLOption uint8
   643  
   644  // IPv4TOSOption is used by SetSockOpt/GetSockOpt to specify TOS
   645  // for all subsequent outgoing IPv4 packets from the endpoint.
   646  type IPv4TOSOption uint8
   647  
   648  // IPv6TrafficClassOption is used by SetSockOpt/GetSockOpt to specify TOS
   649  // for all subsequent outgoing IPv6 packets from the endpoint.
   650  type IPv6TrafficClassOption uint8
   651  
   652  // Route is a row in the routing table. It specifies through which NIC (and
   653  // gateway) sets of packets should be routed. A row is considered viable if the
   654  // masked target address matches the destination address in the row.
   655  type Route struct {
   656  	// Destination must contain the target address for this row to be viable.
   657  	Destination Subnet
   658  
   659  	// Gateway is the gateway to be used if this row is viable.
   660  	Gateway Address
   661  
   662  	// NIC is the id of the nic to be used if this row is viable.
   663  	NIC NICID
   664  }
   665  
   666  // String implements the fmt.Stringer interface.
   667  func (r Route) String() string {
   668  	var out strings.Builder
   669  	fmt.Fprintf(&out, "%s", r.Destination)
   670  	if len(r.Gateway) > 0 {
   671  		fmt.Fprintf(&out, " via %s", r.Gateway)
   672  	}
   673  	fmt.Fprintf(&out, " nic %d", r.NIC)
   674  	return out.String()
   675  }
   676  
   677  // TransportProtocolNumber is the number of a transport protocol.
   678  type TransportProtocolNumber uint32
   679  
   680  // NetworkProtocolNumber is the number of a network protocol.
   681  type NetworkProtocolNumber uint32
   682  
   683  // A StatCounter keeps track of a statistic.
   684  type StatCounter struct {
   685  	count uint32
   686  }
   687  
   688  // Increment adds one to the counter.
   689  func (s *StatCounter) Increment() {
   690  	s.IncrementBy(1)
   691  }
   692  
   693  // Decrement minuses one to the counter.
   694  func (s *StatCounter) Decrement() {
   695  	s.IncrementBy(^uint64(0))
   696  }
   697  
   698  // Value returns the current value of the counter.
   699  func (s *StatCounter) Value() uint64 {
   700  	return uint64(atomic.LoadUint32(&s.count))
   701  }
   702  
   703  // IncrementBy increments the counter by v.
   704  func (s *StatCounter) IncrementBy(v uint64) {
   705  	atomic.AddUint32(&s.count, uint32(v))
   706  }
   707  
   708  func (s *StatCounter) String() string {
   709  	return strconv.FormatUint(s.Value(), 10)
   710  }
   711  
   712  // ICMPv4PacketStats enumerates counts for all ICMPv4 packet types.
   713  type ICMPv4PacketStats struct {
   714  	// Echo is the total number of ICMPv4 echo packets counted.
   715  	Echo *StatCounter
   716  
   717  	// EchoReply is the total number of ICMPv4 echo reply packets counted.
   718  	EchoReply *StatCounter
   719  
   720  	// DstUnreachable is the total number of ICMPv4 destination unreachable
   721  	// packets counted.
   722  	DstUnreachable *StatCounter
   723  
   724  	// SrcQuench is the total number of ICMPv4 source quench packets
   725  	// counted.
   726  	SrcQuench *StatCounter
   727  
   728  	// Redirect is the total number of ICMPv4 redirect packets counted.
   729  	Redirect *StatCounter
   730  
   731  	// TimeExceeded is the total number of ICMPv4 time exceeded packets
   732  	// counted.
   733  	TimeExceeded *StatCounter
   734  
   735  	// ParamProblem is the total number of ICMPv4 parameter problem packets
   736  	// counted.
   737  	ParamProblem *StatCounter
   738  
   739  	// Timestamp is the total number of ICMPv4 timestamp packets counted.
   740  	Timestamp *StatCounter
   741  
   742  	// TimestampReply is the total number of ICMPv4 timestamp reply packets
   743  	// counted.
   744  	TimestampReply *StatCounter
   745  
   746  	// InfoRequest is the total number of ICMPv4 information request
   747  	// packets counted.
   748  	InfoRequest *StatCounter
   749  
   750  	// InfoReply is the total number of ICMPv4 information reply packets
   751  	// counted.
   752  	InfoReply *StatCounter
   753  }
   754  
   755  // ICMPv6PacketStats enumerates counts for all ICMPv6 packet types.
   756  type ICMPv6PacketStats struct {
   757  	// EchoRequest is the total number of ICMPv6 echo request packets
   758  	// counted.
   759  	EchoRequest *StatCounter
   760  
   761  	// EchoReply is the total number of ICMPv6 echo reply packets counted.
   762  	EchoReply *StatCounter
   763  
   764  	// DstUnreachable is the total number of ICMPv6 destination unreachable
   765  	// packets counted.
   766  	DstUnreachable *StatCounter
   767  
   768  	// PacketTooBig is the total number of ICMPv6 packet too big packets
   769  	// counted.
   770  	PacketTooBig *StatCounter
   771  
   772  	// TimeExceeded is the total number of ICMPv6 time exceeded packets
   773  	// counted.
   774  	TimeExceeded *StatCounter
   775  
   776  	// ParamProblem is the total number of ICMPv6 parameter problem packets
   777  	// counted.
   778  	ParamProblem *StatCounter
   779  
   780  	// RouterSolicit is the total number of ICMPv6 router solicit packets
   781  	// counted.
   782  	RouterSolicit *StatCounter
   783  
   784  	// RouterAdvert is the total number of ICMPv6 router advert packets
   785  	// counted.
   786  	RouterAdvert *StatCounter
   787  
   788  	// NeighborSolicit is the total number of ICMPv6 neighbor solicit
   789  	// packets counted.
   790  	NeighborSolicit *StatCounter
   791  
   792  	// NeighborAdvert is the total number of ICMPv6 neighbor advert packets
   793  	// counted.
   794  	NeighborAdvert *StatCounter
   795  
   796  	// RedirectMsg is the total number of ICMPv6 redirect message packets
   797  	// counted.
   798  	RedirectMsg *StatCounter
   799  }
   800  
   801  // ICMPv4SentPacketStats collects outbound ICMPv4-specific stats.
   802  type ICMPv4SentPacketStats struct {
   803  	ICMPv4PacketStats
   804  
   805  	// Dropped is the total number of ICMPv4 packets dropped due to link
   806  	// layer errors.
   807  	Dropped *StatCounter
   808  
   809  	// RateLimited is the total number of ICMPv6 packets dropped due to
   810  	// rate limit being exceeded.
   811  	RateLimited *StatCounter
   812  }
   813  
   814  // ICMPv4ReceivedPacketStats collects inbound ICMPv4-specific stats.
   815  type ICMPv4ReceivedPacketStats struct {
   816  	ICMPv4PacketStats
   817  
   818  	// Invalid is the total number of ICMPv4 packets received that the
   819  	// transport layer could not parse.
   820  	Invalid *StatCounter
   821  }
   822  
   823  // ICMPv6SentPacketStats collects outbound ICMPv6-specific stats.
   824  type ICMPv6SentPacketStats struct {
   825  	ICMPv6PacketStats
   826  
   827  	// Dropped is the total number of ICMPv6 packets dropped due to link
   828  	// layer errors.
   829  	Dropped *StatCounter
   830  
   831  	// RateLimited is the total number of ICMPv6 packets dropped due to
   832  	// rate limit being exceeded.
   833  	RateLimited *StatCounter
   834  }
   835  
   836  // ICMPv6ReceivedPacketStats collects inbound ICMPv6-specific stats.
   837  type ICMPv6ReceivedPacketStats struct {
   838  	ICMPv6PacketStats
   839  
   840  	// Invalid is the total number of ICMPv6 packets received that the
   841  	// transport layer could not parse.
   842  	Invalid *StatCounter
   843  }
   844  
   845  // ICMPStats collects ICMP-specific stats (both v4 and v6).
   846  type ICMPStats struct {
   847  	// ICMPv4SentPacketStats contains counts of sent packets by ICMPv4 packet type
   848  	// and a single count of packets which failed to write to the link
   849  	// layer.
   850  	V4PacketsSent ICMPv4SentPacketStats
   851  
   852  	// ICMPv4ReceivedPacketStats contains counts of received packets by ICMPv4
   853  	// packet type and a single count of invalid packets received.
   854  	V4PacketsReceived ICMPv4ReceivedPacketStats
   855  
   856  	// ICMPv6SentPacketStats contains counts of sent packets by ICMPv6 packet type
   857  	// and a single count of packets which failed to write to the link
   858  	// layer.
   859  	V6PacketsSent ICMPv6SentPacketStats
   860  
   861  	// ICMPv6ReceivedPacketStats contains counts of received packets by ICMPv6
   862  	// packet type and a single count of invalid packets received.
   863  	V6PacketsReceived ICMPv6ReceivedPacketStats
   864  }
   865  
   866  // IPStats collects IP-specific stats (both v4 and v6).
   867  type IPStats struct {
   868  	// PacketsReceived is the total number of IP packets received from the
   869  	// link layer in nic.DeliverNetworkPacket.
   870  	PacketsReceived *StatCounter
   871  
   872  	// InvalidAddressesReceived is the total number of IP packets received
   873  	// with an unknown or invalid destination address.
   874  	InvalidAddressesReceived *StatCounter
   875  
   876  	// PacketsDelivered is the total number of incoming IP packets that
   877  	// are successfully delivered to the transport layer via HandlePacket.
   878  	PacketsDelivered *StatCounter
   879  
   880  	// PacketsSent is the total number of IP packets sent via WritePacket.
   881  	PacketsSent *StatCounter
   882  
   883  	// OutgoingPacketErrors is the total number of IP packets which failed
   884  	// to write to a link-layer endpoint.
   885  	OutgoingPacketErrors *StatCounter
   886  
   887  	// MalformedPacketsReceived is the total number of IP Packets that were
   888  	// dropped due to the IP packet header failing validation checks.
   889  	MalformedPacketsReceived *StatCounter
   890  
   891  	// MalformedFragmentsReceived is the total number of IP Fragments that were
   892  	// dropped due to the fragment failing validation checks.
   893  	MalformedFragmentsReceived *StatCounter
   894  }
   895  
   896  // TCPStats collects TCP-specific stats.
   897  type TCPStats struct {
   898  	// ActiveConnectionOpenings is the number of connections opened
   899  	// successfully via Connect.
   900  	ActiveConnectionOpenings *StatCounter
   901  
   902  	// PassiveConnectionOpenings is the number of connections opened
   903  	// successfully via Listen.
   904  	PassiveConnectionOpenings *StatCounter
   905  
   906  	// CurrentEstablished is the number of TCP connections for which the
   907  	// current state is either ESTABLISHED or CLOSE-WAIT.
   908  	CurrentEstablished *StatCounter
   909  
   910  	// EstablishedResets is the number of times TCP connections have made
   911  	// a direct transition to the CLOSED state from either the
   912  	// ESTABLISHED state or the CLOSE-WAIT state.
   913  	EstablishedResets *StatCounter
   914  
   915  	// ListenOverflowSynDrop is the number of times the listen queue overflowed
   916  	// and a SYN was dropped.
   917  	ListenOverflowSynDrop *StatCounter
   918  
   919  	// ListenOverflowAckDrop is the number of times the final ACK
   920  	// in the handshake was dropped due to overflow.
   921  	ListenOverflowAckDrop *StatCounter
   922  
   923  	// ListenOverflowCookieSent is the number of times a SYN cookie was sent.
   924  	ListenOverflowSynCookieSent *StatCounter
   925  
   926  	// ListenOverflowSynCookieRcvd is the number of times a valid SYN
   927  	// cookie was received.
   928  	ListenOverflowSynCookieRcvd *StatCounter
   929  
   930  	// ListenOverflowInvalidSynCookieRcvd is the number of times an invalid SYN cookie
   931  	// was received.
   932  	ListenOverflowInvalidSynCookieRcvd *StatCounter
   933  
   934  	// FailedConnectionAttempts is the number of calls to Connect or Listen
   935  	// (active and passive openings, respectively) that end in an error.
   936  	FailedConnectionAttempts *StatCounter
   937  
   938  	// ValidSegmentsReceived is the number of TCP segments received that
   939  	// the transport layer successfully parsed.
   940  	ValidSegmentsReceived *StatCounter
   941  
   942  	// InvalidSegmentsReceived is the number of TCP segments received that
   943  	// the transport layer could not parse.
   944  	InvalidSegmentsReceived *StatCounter
   945  
   946  	// SegmentsSent is the number of TCP segments sent.
   947  	SegmentsSent *StatCounter
   948  
   949  	// SegmentSendErrors is the number of TCP segments failed to be sent.
   950  	SegmentSendErrors *StatCounter
   951  
   952  	// ResetsSent is the number of TCP resets sent.
   953  	ResetsSent *StatCounter
   954  
   955  	// ResetsReceived is the number of TCP resets received.
   956  	ResetsReceived *StatCounter
   957  
   958  	// Retransmits is the number of TCP segments retransmitted.
   959  	Retransmits *StatCounter
   960  
   961  	// FastRecovery is the number of times Fast Recovery was used to
   962  	// recover from packet loss.
   963  	FastRecovery *StatCounter
   964  
   965  	// SACKRecovery is the number of times SACK Recovery was used to
   966  	// recover from packet loss.
   967  	SACKRecovery *StatCounter
   968  
   969  	// SlowStartRetransmits is the number of segments retransmitted in slow
   970  	// start.
   971  	SlowStartRetransmits *StatCounter
   972  
   973  	// FastRetransmit is the number of segments retransmitted in fast
   974  	// recovery.
   975  	FastRetransmit *StatCounter
   976  
   977  	// Timeouts is the number of times the RTO expired.
   978  	Timeouts *StatCounter
   979  
   980  	// ChecksumErrors is the number of segments dropped due to bad checksums.
   981  	ChecksumErrors *StatCounter
   982  }
   983  
   984  // UDPStats collects UDP-specific stats.
   985  type UDPStats struct {
   986  	// PacketsReceived is the number of UDP datagrams received via
   987  	// HandlePacket.
   988  	PacketsReceived *StatCounter
   989  
   990  	// UnknownPortErrors is the number of incoming UDP datagrams dropped
   991  	// because they did not have a known destination port.
   992  	UnknownPortErrors *StatCounter
   993  
   994  	// ReceiveBufferErrors is the number of incoming UDP datagrams dropped
   995  	// due to the receiving buffer being in an invalid state.
   996  	ReceiveBufferErrors *StatCounter
   997  
   998  	// MalformedPacketsReceived is the number of incoming UDP datagrams
   999  	// dropped due to the UDP header being in a malformed state.
  1000  	MalformedPacketsReceived *StatCounter
  1001  
  1002  	// PacketsSent is the number of UDP datagrams sent via sendUDP.
  1003  	PacketsSent *StatCounter
  1004  
  1005  	// PacketSendErrors is the number of datagrams failed to be sent.
  1006  	PacketSendErrors *StatCounter
  1007  }
  1008  
  1009  // Stats holds statistics about the networking stack.
  1010  //
  1011  // All fields are optional.
  1012  type Stats struct {
  1013  	// UnknownProtocolRcvdPackets is the number of packets received by the
  1014  	// stack that were for an unknown or unsupported protocol.
  1015  	UnknownProtocolRcvdPackets *StatCounter
  1016  
  1017  	// MalformedRcvdPackets is the number of packets received by the stack
  1018  	// that were deemed malformed.
  1019  	MalformedRcvdPackets *StatCounter
  1020  
  1021  	// DroppedPackets is the number of packets dropped due to full queues.
  1022  	DroppedPackets *StatCounter
  1023  
  1024  	// ICMP breaks out ICMP-specific stats (both v4 and v6).
  1025  	ICMP ICMPStats
  1026  
  1027  	// IP breaks out IP-specific stats (both v4 and v6).
  1028  	IP IPStats
  1029  
  1030  	// TCP breaks out TCP-specific stats.
  1031  	TCP TCPStats
  1032  
  1033  	// UDP breaks out UDP-specific stats.
  1034  	UDP UDPStats
  1035  }
  1036  
  1037  // ReceiveErrors collects packet receive errors within transport endpoint.
  1038  type ReceiveErrors struct {
  1039  	// ReceiveBufferOverflow is the number of received packets dropped
  1040  	// due to the receive buffer being full.
  1041  	ReceiveBufferOverflow StatCounter
  1042  
  1043  	// MalformedPacketsReceived is the number of incoming packets
  1044  	// dropped due to the packet header being in a malformed state.
  1045  	MalformedPacketsReceived StatCounter
  1046  
  1047  	// ClosedReceiver is the number of received packets dropped because
  1048  	// of receiving endpoint state being closed.
  1049  	ClosedReceiver StatCounter
  1050  }
  1051  
  1052  // SendErrors collects packet send errors within the transport layer for
  1053  // an endpoint.
  1054  type SendErrors struct {
  1055  	// SendToNetworkFailed is the number of packets failed to be written to
  1056  	// the network endpoint.
  1057  	SendToNetworkFailed StatCounter
  1058  
  1059  	// NoRoute is the number of times we failed to resolve IP route.
  1060  	NoRoute StatCounter
  1061  
  1062  	// NoLinkAddr is the number of times we failed to resolve ARP.
  1063  	NoLinkAddr StatCounter
  1064  }
  1065  
  1066  // ReadErrors collects segment read errors from an endpoint read call.
  1067  type ReadErrors struct {
  1068  	// ReadClosed is the number of received packet drops because the endpoint
  1069  	// was shutdown for read.
  1070  	ReadClosed StatCounter
  1071  
  1072  	// InvalidEndpointState is the number of times we found the endpoint state
  1073  	// to be unexpected.
  1074  	InvalidEndpointState StatCounter
  1075  }
  1076  
  1077  // WriteErrors collects packet write errors from an endpoint write call.
  1078  type WriteErrors struct {
  1079  	// WriteClosed is the number of packet drops because the endpoint
  1080  	// was shutdown for write.
  1081  	WriteClosed StatCounter
  1082  
  1083  	// InvalidEndpointState is the number of times we found the endpoint state
  1084  	// to be unexpected.
  1085  	InvalidEndpointState StatCounter
  1086  
  1087  	// InvalidArgs is the number of times invalid input arguments were
  1088  	// provided for endpoint Write call.
  1089  	InvalidArgs StatCounter
  1090  }
  1091  
  1092  // TransportEndpointStats collects statistics about the endpoint.
  1093  type TransportEndpointStats struct {
  1094  	// PacketsReceived is the number of successful packet receives.
  1095  	PacketsReceived StatCounter
  1096  
  1097  	// PacketsSent is the number of successful packet sends.
  1098  	PacketsSent StatCounter
  1099  
  1100  	// ReceiveErrors collects packet receive errors within transport layer.
  1101  	ReceiveErrors ReceiveErrors
  1102  
  1103  	// ReadErrors collects packet read errors from an endpoint read call.
  1104  	ReadErrors ReadErrors
  1105  
  1106  	// SendErrors collects packet send errors within the transport layer.
  1107  	SendErrors SendErrors
  1108  
  1109  	// WriteErrors collects packet write errors from an endpoint write call.
  1110  	WriteErrors WriteErrors
  1111  }
  1112  
  1113  // IsEndpointStats is an empty method to implement the tcpip.EndpointStats
  1114  // marker interface.
  1115  func (*TransportEndpointStats) IsEndpointStats() {}
  1116  
  1117  func fillIn(v reflect.Value) {
  1118  	for i := 0; i < v.NumField(); i++ {
  1119  		v := v.Field(i)
  1120  		if s, ok := v.Addr().Interface().(**StatCounter); ok {
  1121  			if *s == nil {
  1122  				*s = new(StatCounter)
  1123  			}
  1124  		} else {
  1125  			fillIn(v)
  1126  		}
  1127  	}
  1128  }
  1129  
  1130  // FillIn returns a copy of s with nil fields initialized to new StatCounters.
  1131  func (s Stats) FillIn() Stats {
  1132  	fillIn(reflect.ValueOf(&s).Elem())
  1133  	return s
  1134  }
  1135  
  1136  // Clone returns a copy of the TransportEndpointStats by atomically reading
  1137  // each field.
  1138  func (src *TransportEndpointStats) Clone() TransportEndpointStats {
  1139  	var dst TransportEndpointStats
  1140  	clone(reflect.ValueOf(&dst).Elem(), reflect.ValueOf(src).Elem())
  1141  	return dst
  1142  }
  1143  
  1144  func clone(dst reflect.Value, src reflect.Value) {
  1145  	for i := 0; i < dst.NumField(); i++ {
  1146  		d := dst.Field(i)
  1147  		s := src.Field(i)
  1148  		if c, ok := s.Addr().Interface().(*StatCounter); ok {
  1149  			d.Addr().Interface().(*StatCounter).IncrementBy(c.Value())
  1150  		} else {
  1151  			clone(d, s)
  1152  		}
  1153  	}
  1154  }
  1155  
  1156  // String implements the fmt.Stringer interface.
  1157  func (a Address) String() string {
  1158  	switch len(a) {
  1159  	case 4:
  1160  		return fmt.Sprintf("%d.%d.%d.%d", int(a[0]), int(a[1]), int(a[2]), int(a[3]))
  1161  	case 16:
  1162  		// Find the longest subsequence of hexadecimal zeros.
  1163  		start, end := -1, -1
  1164  		for i := 0; i < len(a); i += 2 {
  1165  			j := i
  1166  			for j < len(a) && a[j] == 0 && a[j+1] == 0 {
  1167  				j += 2
  1168  			}
  1169  			if j > i+2 && j-i > end-start {
  1170  				start, end = i, j
  1171  			}
  1172  		}
  1173  
  1174  		var b strings.Builder
  1175  		for i := 0; i < len(a); i += 2 {
  1176  			if i == start {
  1177  				b.WriteString("::")
  1178  				i = end
  1179  				if end >= len(a) {
  1180  					break
  1181  				}
  1182  			} else if i > 0 {
  1183  				b.WriteByte(':')
  1184  			}
  1185  			v := uint16(a[i+0])<<8 | uint16(a[i+1])
  1186  			if v == 0 {
  1187  				b.WriteByte('0')
  1188  			} else {
  1189  				const digits = "0123456789abcdef"
  1190  				for i := uint(3); i < 4; i-- {
  1191  					if v := v >> (i * 4); v != 0 {
  1192  						b.WriteByte(digits[v&0xf])
  1193  					}
  1194  				}
  1195  			}
  1196  		}
  1197  		return b.String()
  1198  	default:
  1199  		return fmt.Sprintf("%x", []byte(a))
  1200  	}
  1201  }
  1202  
  1203  // To4 converts the IPv4 address to a 4-byte representation.
  1204  // If the address is not an IPv4 address, To4 returns "".
  1205  func (a Address) To4() Address {
  1206  	const (
  1207  		ipv4len = 4
  1208  		ipv6len = 16
  1209  	)
  1210  	if len(a) == ipv4len {
  1211  		return a
  1212  	}
  1213  	if len(a) == ipv6len &&
  1214  		isZeros(a[0:10]) &&
  1215  		a[10] == 0xff &&
  1216  		a[11] == 0xff {
  1217  		return a[12:16]
  1218  	}
  1219  	return ""
  1220  }
  1221  
  1222  // isZeros reports whether a is all zeros.
  1223  func isZeros(a Address) bool {
  1224  	for i := 0; i < len(a); i++ {
  1225  		if a[i] != 0 {
  1226  			return false
  1227  		}
  1228  	}
  1229  	return true
  1230  }
  1231  
  1232  // LinkAddress is a byte slice cast as a string that represents a link address.
  1233  // It is typically a 6-byte MAC address.
  1234  type LinkAddress string
  1235  
  1236  // String implements the fmt.Stringer interface.
  1237  func (a LinkAddress) String() string {
  1238  	switch len(a) {
  1239  	case 6:
  1240  		return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x", a[0], a[1], a[2], a[3], a[4], a[5])
  1241  	default:
  1242  		return fmt.Sprintf("%x", []byte(a))
  1243  	}
  1244  }
  1245  
  1246  // ParseMACAddress parses an IEEE 802 address.
  1247  //
  1248  // It must be in the format aa:bb:cc:dd:ee:ff or aa-bb-cc-dd-ee-ff.
  1249  func ParseMACAddress(s string) (LinkAddress, error) {
  1250  	parts := strings.FieldsFunc(s, func(c rune) bool {
  1251  		return c == ':' || c == '-'
  1252  	})
  1253  	if len(parts) != 6 {
  1254  		return "", fmt.Errorf("inconsistent parts: %s", s)
  1255  	}
  1256  	addr := make([]byte, 0, len(parts))
  1257  	for _, part := range parts {
  1258  		u, err := strconv.ParseUint(part, 16, 8)
  1259  		if err != nil {
  1260  			return "", fmt.Errorf("invalid hex digits: %s", s)
  1261  		}
  1262  		addr = append(addr, byte(u))
  1263  	}
  1264  	return LinkAddress(addr), nil
  1265  }
  1266  
  1267  // AddressWithPrefix is an address with its subnet prefix length.
  1268  type AddressWithPrefix struct {
  1269  	// Address is a network address.
  1270  	Address Address
  1271  
  1272  	// PrefixLen is the subnet prefix length.
  1273  	PrefixLen int
  1274  }
  1275  
  1276  // String implements the fmt.Stringer interface.
  1277  func (a AddressWithPrefix) String() string {
  1278  	return fmt.Sprintf("%s/%d", a.Address, a.PrefixLen)
  1279  }
  1280  
  1281  // Subnet converts the address and prefix into a Subnet value and returns it.
  1282  func (a AddressWithPrefix) Subnet() Subnet {
  1283  	addrLen := len(a.Address)
  1284  	if a.PrefixLen <= 0 {
  1285  		return Subnet{
  1286  			address: Address(strings.Repeat("\x00", addrLen)),
  1287  			mask:    AddressMask(strings.Repeat("\x00", addrLen)),
  1288  		}
  1289  	}
  1290  	if a.PrefixLen >= addrLen*8 {
  1291  		return Subnet{
  1292  			address: a.Address,
  1293  			mask:    AddressMask(strings.Repeat("\xff", addrLen)),
  1294  		}
  1295  	}
  1296  
  1297  	sa := make([]byte, addrLen)
  1298  	sm := make([]byte, addrLen)
  1299  	n := uint(a.PrefixLen)
  1300  	for i := 0; i < addrLen; i++ {
  1301  		if n >= 8 {
  1302  			sa[i] = a.Address[i]
  1303  			sm[i] = 0xff
  1304  			n -= 8
  1305  			continue
  1306  		}
  1307  		sm[i] = ^byte(0xff >> n)
  1308  		sa[i] = a.Address[i] & sm[i]
  1309  		n = 0
  1310  	}
  1311  
  1312  	// For extra caution, call NewSubnet rather than directly creating the Subnet
  1313  	// value. If that fails it indicates a serious bug in this code, so panic is
  1314  	// in order.
  1315  	s, err := NewSubnet(Address(sa), AddressMask(sm))
  1316  	if err != nil {
  1317  		panic("invalid subnet: " + err.Error())
  1318  	}
  1319  	return s
  1320  }
  1321  
  1322  // ProtocolAddress is an address and the network protocol it is associated
  1323  // with.
  1324  type ProtocolAddress struct {
  1325  	// Protocol is the protocol of the address.
  1326  	Protocol NetworkProtocolNumber
  1327  
  1328  	// AddressWithPrefix is a network address with its subnet prefix length.
  1329  	AddressWithPrefix AddressWithPrefix
  1330  }
  1331  
  1332  var (
  1333  	// danglingEndpointsMu protects access to danglingEndpoints.
  1334  	danglingEndpointsMu sync.Mutex
  1335  
  1336  	// danglingEndpoints tracks all dangling endpoints no longer owned by the app.
  1337  	danglingEndpoints = make(map[Endpoint]struct{})
  1338  )
  1339  
  1340  // GetDanglingEndpoints returns all dangling endpoints.
  1341  func GetDanglingEndpoints() []Endpoint {
  1342  	danglingEndpointsMu.Lock()
  1343  	es := make([]Endpoint, 0, len(danglingEndpoints))
  1344  	for e := range danglingEndpoints {
  1345  		es = append(es, e)
  1346  	}
  1347  	danglingEndpointsMu.Unlock()
  1348  	return es
  1349  }
  1350  
  1351  // AddDanglingEndpoint adds a dangling endpoint.
  1352  func AddDanglingEndpoint(e Endpoint) {
  1353  	danglingEndpointsMu.Lock()
  1354  	danglingEndpoints[e] = struct{}{}
  1355  	danglingEndpointsMu.Unlock()
  1356  }
  1357  
  1358  // DeleteDanglingEndpoint removes a dangling endpoint.
  1359  func DeleteDanglingEndpoint(e Endpoint) {
  1360  	danglingEndpointsMu.Lock()
  1361  	delete(danglingEndpoints, e)
  1362  	danglingEndpointsMu.Unlock()
  1363  }
  1364  
  1365  // AsyncLoading is the global barrier for asynchronous endpoint loading
  1366  // activities.
  1367  var AsyncLoading sync.WaitGroup