github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/types/types.go (about)

     1  // Package types contains types that are common across libnetwork project
     2  package types
     3  
     4  import (
     5  	"bytes"
     6  	"fmt"
     7  	"net"
     8  	"strconv"
     9  	"strings"
    10  
    11  	"github.com/Prakhar-Agarwal-byte/moby/errdefs"
    12  	"github.com/ishidawataru/sctp"
    13  )
    14  
    15  // constants for the IP address type
    16  // Deprecated: use the consts defined in github.com/Prakhar-Agarwal-byte/moby/libnetwork/resolvconf
    17  const (
    18  	IP = iota // IPv4 and IPv6
    19  	IPv4
    20  	IPv6
    21  )
    22  
    23  // EncryptionKey is the libnetwork representation of the key distributed by the lead
    24  // manager.
    25  type EncryptionKey struct {
    26  	Subsystem   string
    27  	Algorithm   int32
    28  	Key         []byte
    29  	LamportTime uint64
    30  }
    31  
    32  // QosPolicy represents a quality of service policy on an endpoint
    33  type QosPolicy struct {
    34  	MaxEgressBandwidth uint64
    35  }
    36  
    37  // TransportPort represents a local Layer 4 endpoint
    38  type TransportPort struct {
    39  	Proto Protocol
    40  	Port  uint16
    41  }
    42  
    43  // Equal checks if this instance of Transportport is equal to the passed one
    44  func (t *TransportPort) Equal(o *TransportPort) bool {
    45  	if t == o {
    46  		return true
    47  	}
    48  
    49  	if o == nil {
    50  		return false
    51  	}
    52  
    53  	if t.Proto != o.Proto || t.Port != o.Port {
    54  		return false
    55  	}
    56  
    57  	return true
    58  }
    59  
    60  // GetCopy returns a copy of this TransportPort structure instance
    61  func (t *TransportPort) GetCopy() TransportPort {
    62  	return TransportPort{Proto: t.Proto, Port: t.Port}
    63  }
    64  
    65  // String returns the TransportPort structure in string form
    66  func (t *TransportPort) String() string {
    67  	return fmt.Sprintf("%s/%d", t.Proto.String(), t.Port)
    68  }
    69  
    70  // PortBinding represents a port binding between the container and the host
    71  type PortBinding struct {
    72  	Proto       Protocol
    73  	IP          net.IP
    74  	Port        uint16
    75  	HostIP      net.IP
    76  	HostPort    uint16
    77  	HostPortEnd uint16
    78  }
    79  
    80  // HostAddr returns the host side transport address
    81  func (p PortBinding) HostAddr() (net.Addr, error) {
    82  	switch p.Proto {
    83  	case UDP:
    84  		return &net.UDPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
    85  	case TCP:
    86  		return &net.TCPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
    87  	case SCTP:
    88  		return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.HostIP}}, Port: int(p.HostPort)}, nil
    89  	default:
    90  		return nil, fmt.Errorf("invalid transport protocol: %s", p.Proto.String())
    91  	}
    92  }
    93  
    94  // ContainerAddr returns the container side transport address
    95  func (p PortBinding) ContainerAddr() (net.Addr, error) {
    96  	switch p.Proto {
    97  	case UDP:
    98  		return &net.UDPAddr{IP: p.IP, Port: int(p.Port)}, nil
    99  	case TCP:
   100  		return &net.TCPAddr{IP: p.IP, Port: int(p.Port)}, nil
   101  	case SCTP:
   102  		return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.IP}}, Port: int(p.Port)}, nil
   103  	default:
   104  		return nil, fmt.Errorf("invalid transport protocol: %s", p.Proto.String())
   105  	}
   106  }
   107  
   108  // GetCopy returns a copy of this PortBinding structure instance
   109  func (p *PortBinding) GetCopy() PortBinding {
   110  	return PortBinding{
   111  		Proto:       p.Proto,
   112  		IP:          GetIPCopy(p.IP),
   113  		Port:        p.Port,
   114  		HostIP:      GetIPCopy(p.HostIP),
   115  		HostPort:    p.HostPort,
   116  		HostPortEnd: p.HostPortEnd,
   117  	}
   118  }
   119  
   120  // String returns the PortBinding structure in string form
   121  func (p *PortBinding) String() string {
   122  	ret := fmt.Sprintf("%s/", p.Proto)
   123  	if p.IP != nil {
   124  		ret += p.IP.String()
   125  	}
   126  	ret = fmt.Sprintf("%s:%d/", ret, p.Port)
   127  	if p.HostIP != nil {
   128  		ret += p.HostIP.String()
   129  	}
   130  	ret = fmt.Sprintf("%s:%d", ret, p.HostPort)
   131  	return ret
   132  }
   133  
   134  const (
   135  	// ICMP is for the ICMP ip protocol
   136  	ICMP = 1
   137  	// TCP is for the TCP ip protocol
   138  	TCP = 6
   139  	// UDP is for the UDP ip protocol
   140  	UDP = 17
   141  	// SCTP is for the SCTP ip protocol
   142  	SCTP = 132
   143  )
   144  
   145  // Protocol represents an IP protocol number
   146  type Protocol uint8
   147  
   148  func (p Protocol) String() string {
   149  	switch p {
   150  	case ICMP:
   151  		return "icmp"
   152  	case TCP:
   153  		return "tcp"
   154  	case UDP:
   155  		return "udp"
   156  	case SCTP:
   157  		return "sctp"
   158  	default:
   159  		return strconv.Itoa(int(p))
   160  	}
   161  }
   162  
   163  // ParseProtocol returns the respective Protocol type for the passed string
   164  func ParseProtocol(s string) Protocol {
   165  	switch strings.ToLower(s) {
   166  	case "icmp":
   167  		return ICMP
   168  	case "udp":
   169  		return UDP
   170  	case "tcp":
   171  		return TCP
   172  	case "sctp":
   173  		return SCTP
   174  	default:
   175  		return 0
   176  	}
   177  }
   178  
   179  // GetMacCopy returns a copy of the passed MAC address
   180  func GetMacCopy(from net.HardwareAddr) net.HardwareAddr {
   181  	if from == nil {
   182  		return nil
   183  	}
   184  	to := make(net.HardwareAddr, len(from))
   185  	copy(to, from)
   186  	return to
   187  }
   188  
   189  // GetIPCopy returns a copy of the passed IP address
   190  func GetIPCopy(from net.IP) net.IP {
   191  	if from == nil {
   192  		return nil
   193  	}
   194  	to := make(net.IP, len(from))
   195  	copy(to, from)
   196  	return to
   197  }
   198  
   199  // GetIPNetCopy returns a copy of the passed IP Network
   200  func GetIPNetCopy(from *net.IPNet) *net.IPNet {
   201  	if from == nil {
   202  		return nil
   203  	}
   204  	bm := make(net.IPMask, len(from.Mask))
   205  	copy(bm, from.Mask)
   206  	return &net.IPNet{IP: GetIPCopy(from.IP), Mask: bm}
   207  }
   208  
   209  // GetIPNetCanonical returns the canonical form for the passed network
   210  func GetIPNetCanonical(nw *net.IPNet) *net.IPNet {
   211  	if nw == nil {
   212  		return nil
   213  	}
   214  	c := GetIPNetCopy(nw)
   215  	c.IP = c.IP.Mask(nw.Mask)
   216  	return c
   217  }
   218  
   219  // CompareIPNet returns equal if the two IP Networks are equal
   220  func CompareIPNet(a, b *net.IPNet) bool {
   221  	if a == b {
   222  		return true
   223  	}
   224  	if a == nil || b == nil {
   225  		return false
   226  	}
   227  	return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask)
   228  }
   229  
   230  // IsIPNetValid returns true if the ipnet is a valid network/mask
   231  // combination. Otherwise returns false.
   232  func IsIPNetValid(nw *net.IPNet) bool {
   233  	return nw.String() != "0.0.0.0/0"
   234  }
   235  
   236  var v4inV6MaskPrefix = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
   237  
   238  // compareIPMask checks if the passed ip and mask are semantically compatible.
   239  // It returns the byte indexes for the address and mask so that caller can
   240  // do bitwise operations without modifying address representation.
   241  func compareIPMask(ip net.IP, mask net.IPMask) (is int, ms int, err error) {
   242  	// Find the effective starting of address and mask
   243  	if len(ip) == net.IPv6len && ip.To4() != nil {
   244  		is = 12
   245  	}
   246  	if len(ip[is:]) == net.IPv4len && len(mask) == net.IPv6len && bytes.Equal(mask[:12], v4inV6MaskPrefix) {
   247  		ms = 12
   248  	}
   249  	// Check if address and mask are semantically compatible
   250  	if len(ip[is:]) != len(mask[ms:]) {
   251  		err = fmt.Errorf("ip and mask are not compatible: (%#v, %#v)", ip, mask)
   252  	}
   253  	return
   254  }
   255  
   256  // GetHostPartIP returns the host portion of the ip address identified by the mask.
   257  // IP address representation is not modified. If address and mask are not compatible
   258  // an error is returned.
   259  func GetHostPartIP(ip net.IP, mask net.IPMask) (net.IP, error) {
   260  	// Find the effective starting of address and mask
   261  	is, ms, err := compareIPMask(ip, mask)
   262  	if err != nil {
   263  		return nil, fmt.Errorf("cannot compute host portion ip address because %s", err)
   264  	}
   265  
   266  	// Compute host portion
   267  	out := GetIPCopy(ip)
   268  	for i := 0; i < len(mask[ms:]); i++ {
   269  		out[is+i] &= ^mask[ms+i]
   270  	}
   271  
   272  	return out, nil
   273  }
   274  
   275  // GetBroadcastIP returns the broadcast ip address for the passed network (ip and mask).
   276  // IP address representation is not modified. If address and mask are not compatible
   277  // an error is returned.
   278  func GetBroadcastIP(ip net.IP, mask net.IPMask) (net.IP, error) {
   279  	// Find the effective starting of address and mask
   280  	is, ms, err := compareIPMask(ip, mask)
   281  	if err != nil {
   282  		return nil, fmt.Errorf("cannot compute broadcast ip address because %s", err)
   283  	}
   284  
   285  	// Compute broadcast address
   286  	out := GetIPCopy(ip)
   287  	for i := 0; i < len(mask[ms:]); i++ {
   288  		out[is+i] |= ^mask[ms+i]
   289  	}
   290  
   291  	return out, nil
   292  }
   293  
   294  // ParseCIDR returns the *net.IPNet represented by the passed CIDR notation
   295  func ParseCIDR(cidr string) (n *net.IPNet, e error) {
   296  	var i net.IP
   297  	if i, n, e = net.ParseCIDR(cidr); e == nil {
   298  		n.IP = i
   299  	}
   300  	return
   301  }
   302  
   303  const (
   304  	// NEXTHOP indicates a StaticRoute with an IP next hop.
   305  	NEXTHOP = iota
   306  
   307  	// CONNECTED indicates a StaticRoute with an interface for directly connected peers.
   308  	CONNECTED
   309  )
   310  
   311  // StaticRoute is a statically-provisioned IP route.
   312  type StaticRoute struct {
   313  	Destination *net.IPNet
   314  
   315  	RouteType int // NEXT_HOP or CONNECTED
   316  
   317  	// NextHop will be resolved by the kernel (i.e. as a loose hop).
   318  	NextHop net.IP
   319  }
   320  
   321  // GetCopy returns a copy of this StaticRoute structure
   322  func (r *StaticRoute) GetCopy() *StaticRoute {
   323  	d := GetIPNetCopy(r.Destination)
   324  	nh := GetIPCopy(r.NextHop)
   325  	return &StaticRoute{
   326  		Destination: d,
   327  		RouteType:   r.RouteType,
   328  		NextHop:     nh,
   329  	}
   330  }
   331  
   332  // InterfaceStatistics represents the interface's statistics
   333  type InterfaceStatistics struct {
   334  	RxBytes   uint64
   335  	RxPackets uint64
   336  	RxErrors  uint64
   337  	RxDropped uint64
   338  	TxBytes   uint64
   339  	TxPackets uint64
   340  	TxErrors  uint64
   341  	TxDropped uint64
   342  }
   343  
   344  func (is *InterfaceStatistics) String() string {
   345  	return fmt.Sprintf("\nRxBytes: %d, RxPackets: %d, RxErrors: %d, RxDropped: %d, TxBytes: %d, TxPackets: %d, TxErrors: %d, TxDropped: %d",
   346  		is.RxBytes, is.RxPackets, is.RxErrors, is.RxDropped, is.TxBytes, is.TxPackets, is.TxErrors, is.TxDropped)
   347  }
   348  
   349  /******************************
   350   * Well-known Error Interfaces
   351   ******************************/
   352  
   353  // MaskableError is an interface for errors which can be ignored by caller
   354  type MaskableError interface {
   355  	// Maskable makes implementer into MaskableError type
   356  	Maskable()
   357  }
   358  
   359  // InvalidParameterError is an interface for errors originated by a bad request
   360  type InvalidParameterError interface {
   361  	// InvalidParameter makes implementer into InvalidParameterError type
   362  	InvalidParameter()
   363  }
   364  
   365  // NotFoundError is an interface for errors raised because a needed resource is not available
   366  type NotFoundError interface {
   367  	// NotFound makes implementer into NotFoundError type
   368  	NotFound()
   369  }
   370  
   371  // ForbiddenError is an interface for errors which denote a valid request that cannot be honored
   372  type ForbiddenError interface {
   373  	// Forbidden makes implementer into ForbiddenError type
   374  	Forbidden()
   375  }
   376  
   377  // UnavailableError is an interface for errors returned when the required service is not available
   378  type UnavailableError interface {
   379  	// Unavailable makes implementer into UnavailableError type
   380  	Unavailable()
   381  }
   382  
   383  // NotImplementedError is an interface for errors raised because of requested functionality is not yet implemented
   384  type NotImplementedError interface {
   385  	// NotImplemented makes implementer into NotImplementedError type
   386  	NotImplemented()
   387  }
   388  
   389  // InternalError is an interface for errors raised because of an internal error
   390  type InternalError interface {
   391  	// Internal makes implementer into InternalError type
   392  	Internal()
   393  }
   394  
   395  /******************************
   396   * Well-known Error Formatters
   397   ******************************/
   398  
   399  // InvalidParameterErrorf creates an instance of InvalidParameterError
   400  func InvalidParameterErrorf(format string, params ...interface{}) error {
   401  	return errdefs.InvalidParameter(fmt.Errorf(format, params...))
   402  }
   403  
   404  // NotFoundErrorf creates an instance of NotFoundError
   405  func NotFoundErrorf(format string, params ...interface{}) error {
   406  	return notFound(fmt.Sprintf(format, params...))
   407  }
   408  
   409  // ForbiddenErrorf creates an instance of ForbiddenError
   410  func ForbiddenErrorf(format string, params ...interface{}) error {
   411  	return forbidden(fmt.Sprintf(format, params...))
   412  }
   413  
   414  // UnavailableErrorf creates an instance of UnavailableError
   415  func UnavailableErrorf(format string, params ...interface{}) error {
   416  	return unavailable(fmt.Sprintf(format, params...))
   417  }
   418  
   419  // NotImplementedErrorf creates an instance of NotImplementedError
   420  func NotImplementedErrorf(format string, params ...interface{}) error {
   421  	return notImpl(fmt.Sprintf(format, params...))
   422  }
   423  
   424  // InternalErrorf creates an instance of InternalError
   425  func InternalErrorf(format string, params ...interface{}) error {
   426  	return internal(fmt.Sprintf(format, params...))
   427  }
   428  
   429  // InternalMaskableErrorf creates an instance of InternalError and MaskableError
   430  func InternalMaskableErrorf(format string, params ...interface{}) error {
   431  	return maskInternal(fmt.Sprintf(format, params...))
   432  }
   433  
   434  /***********************
   435   * Internal Error Types
   436   ***********************/
   437  type notFound string
   438  
   439  func (nf notFound) Error() string {
   440  	return string(nf)
   441  }
   442  func (nf notFound) NotFound() {}
   443  
   444  type forbidden string
   445  
   446  func (frb forbidden) Error() string {
   447  	return string(frb)
   448  }
   449  func (frb forbidden) Forbidden() {}
   450  
   451  type unavailable string
   452  
   453  func (ns unavailable) Error() string {
   454  	return string(ns)
   455  }
   456  func (ns unavailable) Unavailable() {}
   457  
   458  type notImpl string
   459  
   460  func (ni notImpl) Error() string {
   461  	return string(ni)
   462  }
   463  func (ni notImpl) NotImplemented() {}
   464  
   465  type internal string
   466  
   467  func (nt internal) Error() string {
   468  	return string(nt)
   469  }
   470  func (nt internal) Internal() {}
   471  
   472  type maskInternal string
   473  
   474  func (mnt maskInternal) Error() string {
   475  	return string(mnt)
   476  }
   477  func (mnt maskInternal) Internal() {}
   478  func (mnt maskInternal) Maskable() {}