github.com/google/netstack@v0.0.0-20191123085552-55fcc16cd0eb/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/google/netstack/tcpip/buffer" 43 "github.com/google/netstack/tcpip/iptables" 44 "github.com/google/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 uint64 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 atomic.LoadUint64(&s.count) 701 } 702 703 // IncrementBy increments the counter by v. 704 func (s *StatCounter) IncrementBy(v uint64) { 705 atomic.AddUint64(&s.count, 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