github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/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/ishidawataru/sctp"
    12  )
    13  
    14  // constants for the IP address type
    15  const (
    16  	IP = iota // IPv4 and IPv6
    17  	IPv4
    18  	IPv6
    19  )
    20  
    21  // EncryptionKey is the libnetwork representation of the key distributed by the lead
    22  // manager.
    23  type EncryptionKey struct {
    24  	Subsystem   string
    25  	Algorithm   int32
    26  	Key         []byte
    27  	LamportTime uint64
    28  }
    29  
    30  // UUID represents a globally unique ID of various resources like network and endpoint
    31  type UUID string
    32  
    33  // QosPolicy represents a quality of service policy on an endpoint
    34  type QosPolicy struct {
    35  	MaxEgressBandwidth uint64
    36  }
    37  
    38  // TransportPort represents a local Layer 4 endpoint
    39  type TransportPort struct {
    40  	Proto Protocol
    41  	Port  uint16
    42  }
    43  
    44  // Equal checks if this instance of Transportport is equal to the passed one
    45  func (t *TransportPort) Equal(o *TransportPort) bool {
    46  	if t == o {
    47  		return true
    48  	}
    49  
    50  	if o == nil {
    51  		return false
    52  	}
    53  
    54  	if t.Proto != o.Proto || t.Port != o.Port {
    55  		return false
    56  	}
    57  
    58  	return true
    59  }
    60  
    61  // GetCopy returns a copy of this TransportPort structure instance
    62  func (t *TransportPort) GetCopy() TransportPort {
    63  	return TransportPort{Proto: t.Proto, Port: t.Port}
    64  }
    65  
    66  // String returns the TransportPort structure in string form
    67  func (t *TransportPort) String() string {
    68  	return fmt.Sprintf("%s/%d", t.Proto.String(), t.Port)
    69  }
    70  
    71  // FromString reads the TransportPort structure from string
    72  func (t *TransportPort) FromString(s string) error {
    73  	ps := strings.Split(s, "/")
    74  	if len(ps) == 2 {
    75  		t.Proto = ParseProtocol(ps[0])
    76  		if p, err := strconv.ParseUint(ps[1], 10, 16); err == nil {
    77  			t.Port = uint16(p)
    78  			return nil
    79  		}
    80  	}
    81  	return BadRequestErrorf("invalid format for transport port: %s", s)
    82  }
    83  
    84  // PortBinding represents a port binding between the container and the host
    85  type PortBinding struct {
    86  	Proto       Protocol
    87  	IP          net.IP
    88  	Port        uint16
    89  	HostIP      net.IP
    90  	HostPort    uint16
    91  	HostPortEnd uint16
    92  }
    93  
    94  // HostAddr returns the host side transport address
    95  func (p PortBinding) HostAddr() (net.Addr, error) {
    96  	switch p.Proto {
    97  	case UDP:
    98  		return &net.UDPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
    99  	case TCP:
   100  		return &net.TCPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
   101  	case SCTP:
   102  		return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.HostIP}}, Port: int(p.HostPort)}, nil
   103  	default:
   104  		return nil, ErrInvalidProtocolBinding(p.Proto.String())
   105  	}
   106  }
   107  
   108  // ContainerAddr returns the container side transport address
   109  func (p PortBinding) ContainerAddr() (net.Addr, error) {
   110  	switch p.Proto {
   111  	case UDP:
   112  		return &net.UDPAddr{IP: p.IP, Port: int(p.Port)}, nil
   113  	case TCP:
   114  		return &net.TCPAddr{IP: p.IP, Port: int(p.Port)}, nil
   115  	case SCTP:
   116  		return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.IP}}, Port: int(p.Port)}, nil
   117  	default:
   118  		return nil, ErrInvalidProtocolBinding(p.Proto.String())
   119  	}
   120  }
   121  
   122  // GetCopy returns a copy of this PortBinding structure instance
   123  func (p *PortBinding) GetCopy() PortBinding {
   124  	return PortBinding{
   125  		Proto:       p.Proto,
   126  		IP:          GetIPCopy(p.IP),
   127  		Port:        p.Port,
   128  		HostIP:      GetIPCopy(p.HostIP),
   129  		HostPort:    p.HostPort,
   130  		HostPortEnd: p.HostPortEnd,
   131  	}
   132  }
   133  
   134  // String returns the PortBinding structure in string form
   135  func (p *PortBinding) String() string {
   136  	ret := fmt.Sprintf("%s/", p.Proto)
   137  	if p.IP != nil {
   138  		ret += p.IP.String()
   139  	}
   140  	ret = fmt.Sprintf("%s:%d/", ret, p.Port)
   141  	if p.HostIP != nil {
   142  		ret += p.HostIP.String()
   143  	}
   144  	ret = fmt.Sprintf("%s:%d", ret, p.HostPort)
   145  	return ret
   146  }
   147  
   148  // FromString reads the PortBinding structure from string s.
   149  // String s is a triple of "protocol/containerIP:port/hostIP:port"
   150  // containerIP and hostIP can be in dotted decimal ("192.0.2.1") or IPv6 ("2001:db8::68") form.
   151  // Zoned addresses ("169.254.0.23%eth0" or "fe80::1ff:fe23:4567:890a%eth0") are not supported.
   152  // If string s is incorrectly formatted or the IP addresses or ports cannot be parsed, FromString
   153  // returns an error.
   154  func (p *PortBinding) FromString(s string) error {
   155  	ps := strings.Split(s, "/")
   156  	if len(ps) != 3 {
   157  		return BadRequestErrorf("invalid format for port binding: %s", s)
   158  	}
   159  
   160  	p.Proto = ParseProtocol(ps[0])
   161  
   162  	var err error
   163  	if p.IP, p.Port, err = parseIPPort(ps[1]); err != nil {
   164  		return BadRequestErrorf("failed to parse Container IP/Port in port binding: %s", err.Error())
   165  	}
   166  
   167  	if p.HostIP, p.HostPort, err = parseIPPort(ps[2]); err != nil {
   168  		return BadRequestErrorf("failed to parse Host IP/Port in port binding: %s", err.Error())
   169  	}
   170  
   171  	return nil
   172  }
   173  
   174  func parseIPPort(s string) (net.IP, uint16, error) {
   175  	hoststr, portstr, err := net.SplitHostPort(s)
   176  	if err != nil {
   177  		return nil, 0, err
   178  	}
   179  
   180  	ip := net.ParseIP(hoststr)
   181  	if ip == nil {
   182  		return nil, 0, BadRequestErrorf("invalid ip: %s", hoststr)
   183  	}
   184  
   185  	port, err := strconv.ParseUint(portstr, 10, 16)
   186  	if err != nil {
   187  		return nil, 0, BadRequestErrorf("invalid port: %s", portstr)
   188  	}
   189  
   190  	return ip, uint16(port), nil
   191  }
   192  
   193  // Equal checks if this instance of PortBinding is equal to the passed one
   194  func (p *PortBinding) Equal(o *PortBinding) bool {
   195  	if p == o {
   196  		return true
   197  	}
   198  
   199  	if o == nil {
   200  		return false
   201  	}
   202  
   203  	if p.Proto != o.Proto || p.Port != o.Port ||
   204  		p.HostPort != o.HostPort || p.HostPortEnd != o.HostPortEnd {
   205  		return false
   206  	}
   207  
   208  	if p.IP != nil {
   209  		if !p.IP.Equal(o.IP) {
   210  			return false
   211  		}
   212  	} else {
   213  		if o.IP != nil {
   214  			return false
   215  		}
   216  	}
   217  
   218  	if p.HostIP != nil {
   219  		if !p.HostIP.Equal(o.HostIP) {
   220  			return false
   221  		}
   222  	} else {
   223  		if o.HostIP != nil {
   224  			return false
   225  		}
   226  	}
   227  
   228  	return true
   229  }
   230  
   231  // ErrInvalidProtocolBinding is returned when the port binding protocol is not valid.
   232  type ErrInvalidProtocolBinding string
   233  
   234  func (ipb ErrInvalidProtocolBinding) Error() string {
   235  	return fmt.Sprintf("invalid transport protocol: %s", string(ipb))
   236  }
   237  
   238  const (
   239  	// ICMP is for the ICMP ip protocol
   240  	ICMP = 1
   241  	// TCP is for the TCP ip protocol
   242  	TCP = 6
   243  	// UDP is for the UDP ip protocol
   244  	UDP = 17
   245  	// SCTP is for the SCTP ip protocol
   246  	SCTP = 132
   247  )
   248  
   249  // Protocol represents an IP protocol number
   250  type Protocol uint8
   251  
   252  func (p Protocol) String() string {
   253  	switch p {
   254  	case ICMP:
   255  		return "icmp"
   256  	case TCP:
   257  		return "tcp"
   258  	case UDP:
   259  		return "udp"
   260  	case SCTP:
   261  		return "sctp"
   262  	default:
   263  		return fmt.Sprintf("%d", p)
   264  	}
   265  }
   266  
   267  // ParseProtocol returns the respective Protocol type for the passed string
   268  func ParseProtocol(s string) Protocol {
   269  	switch strings.ToLower(s) {
   270  	case "icmp":
   271  		return ICMP
   272  	case "udp":
   273  		return UDP
   274  	case "tcp":
   275  		return TCP
   276  	case "sctp":
   277  		return SCTP
   278  	default:
   279  		return 0
   280  	}
   281  }
   282  
   283  // GetMacCopy returns a copy of the passed MAC address
   284  func GetMacCopy(from net.HardwareAddr) net.HardwareAddr {
   285  	if from == nil {
   286  		return nil
   287  	}
   288  	to := make(net.HardwareAddr, len(from))
   289  	copy(to, from)
   290  	return to
   291  }
   292  
   293  // GetIPCopy returns a copy of the passed IP address
   294  func GetIPCopy(from net.IP) net.IP {
   295  	if from == nil {
   296  		return nil
   297  	}
   298  	to := make(net.IP, len(from))
   299  	copy(to, from)
   300  	return to
   301  }
   302  
   303  // GetIPNetCopy returns a copy of the passed IP Network
   304  func GetIPNetCopy(from *net.IPNet) *net.IPNet {
   305  	if from == nil {
   306  		return nil
   307  	}
   308  	bm := make(net.IPMask, len(from.Mask))
   309  	copy(bm, from.Mask)
   310  	return &net.IPNet{IP: GetIPCopy(from.IP), Mask: bm}
   311  }
   312  
   313  // GetIPNetCanonical returns the canonical form for the passed network
   314  func GetIPNetCanonical(nw *net.IPNet) *net.IPNet {
   315  	if nw == nil {
   316  		return nil
   317  	}
   318  	c := GetIPNetCopy(nw)
   319  	c.IP = c.IP.Mask(nw.Mask)
   320  	return c
   321  }
   322  
   323  // CompareIPNet returns equal if the two IP Networks are equal
   324  func CompareIPNet(a, b *net.IPNet) bool {
   325  	if a == b {
   326  		return true
   327  	}
   328  	if a == nil || b == nil {
   329  		return false
   330  	}
   331  	return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask)
   332  }
   333  
   334  // GetMinimalIP returns the address in its shortest form
   335  // If ip contains an IPv4-mapped IPv6 address, the 4-octet form of the IPv4 address will be returned.
   336  // Otherwise ip is returned unchanged.
   337  func GetMinimalIP(ip net.IP) net.IP {
   338  	if ip != nil && ip.To4() != nil {
   339  		return ip.To4()
   340  	}
   341  	return ip
   342  }
   343  
   344  // GetMinimalIPNet returns a copy of the passed IP Network with congruent ip and mask notation
   345  func GetMinimalIPNet(nw *net.IPNet) *net.IPNet {
   346  	if nw == nil {
   347  		return nil
   348  	}
   349  	if len(nw.IP) == 16 && nw.IP.To4() != nil {
   350  		m := nw.Mask
   351  		if len(m) == 16 {
   352  			m = m[12:16]
   353  		}
   354  		return &net.IPNet{IP: nw.IP.To4(), Mask: m}
   355  	}
   356  	return nw
   357  }
   358  
   359  // IsIPNetValid returns true if the ipnet is a valid network/mask
   360  // combination. Otherwise returns false.
   361  func IsIPNetValid(nw *net.IPNet) bool {
   362  	return nw.String() != "0.0.0.0/0"
   363  }
   364  
   365  var v4inV6MaskPrefix = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
   366  
   367  // compareIPMask checks if the passed ip and mask are semantically compatible.
   368  // It returns the byte indexes for the address and mask so that caller can
   369  // do bitwise operations without modifying address representation.
   370  func compareIPMask(ip net.IP, mask net.IPMask) (is int, ms int, err error) {
   371  	// Find the effective starting of address and mask
   372  	if len(ip) == net.IPv6len && ip.To4() != nil {
   373  		is = 12
   374  	}
   375  	if len(ip[is:]) == net.IPv4len && len(mask) == net.IPv6len && bytes.Equal(mask[:12], v4inV6MaskPrefix) {
   376  		ms = 12
   377  	}
   378  	// Check if address and mask are semantically compatible
   379  	if len(ip[is:]) != len(mask[ms:]) {
   380  		err = fmt.Errorf("ip and mask are not compatible: (%#v, %#v)", ip, mask)
   381  	}
   382  	return
   383  }
   384  
   385  // GetHostPartIP returns the host portion of the ip address identified by the mask.
   386  // IP address representation is not modified. If address and mask are not compatible
   387  // an error is returned.
   388  func GetHostPartIP(ip net.IP, mask net.IPMask) (net.IP, error) {
   389  	// Find the effective starting of address and mask
   390  	is, ms, err := compareIPMask(ip, mask)
   391  	if err != nil {
   392  		return nil, fmt.Errorf("cannot compute host portion ip address because %s", err)
   393  	}
   394  
   395  	// Compute host portion
   396  	out := GetIPCopy(ip)
   397  	for i := 0; i < len(mask[ms:]); i++ {
   398  		out[is+i] &= ^mask[ms+i]
   399  	}
   400  
   401  	return out, nil
   402  }
   403  
   404  // GetBroadcastIP returns the broadcast ip address for the passed network (ip and mask).
   405  // IP address representation is not modified. If address and mask are not compatible
   406  // an error is returned.
   407  func GetBroadcastIP(ip net.IP, mask net.IPMask) (net.IP, error) {
   408  	// Find the effective starting of address and mask
   409  	is, ms, err := compareIPMask(ip, mask)
   410  	if err != nil {
   411  		return nil, fmt.Errorf("cannot compute broadcast ip address because %s", err)
   412  	}
   413  
   414  	// Compute broadcast address
   415  	out := GetIPCopy(ip)
   416  	for i := 0; i < len(mask[ms:]); i++ {
   417  		out[is+i] |= ^mask[ms+i]
   418  	}
   419  
   420  	return out, nil
   421  }
   422  
   423  // ParseCIDR returns the *net.IPNet represented by the passed CIDR notation
   424  func ParseCIDR(cidr string) (n *net.IPNet, e error) {
   425  	var i net.IP
   426  	if i, n, e = net.ParseCIDR(cidr); e == nil {
   427  		n.IP = i
   428  	}
   429  	return
   430  }
   431  
   432  const (
   433  	// NEXTHOP indicates a StaticRoute with an IP next hop.
   434  	NEXTHOP = iota
   435  
   436  	// CONNECTED indicates a StaticRoute with an interface for directly connected peers.
   437  	CONNECTED
   438  )
   439  
   440  // StaticRoute is a statically-provisioned IP route.
   441  type StaticRoute struct {
   442  	Destination *net.IPNet
   443  
   444  	RouteType int // NEXT_HOP or CONNECTED
   445  
   446  	// NextHop will be resolved by the kernel (i.e. as a loose hop).
   447  	NextHop net.IP
   448  }
   449  
   450  // GetCopy returns a copy of this StaticRoute structure
   451  func (r *StaticRoute) GetCopy() *StaticRoute {
   452  	d := GetIPNetCopy(r.Destination)
   453  	nh := GetIPCopy(r.NextHop)
   454  	return &StaticRoute{Destination: d,
   455  		RouteType: r.RouteType,
   456  		NextHop:   nh,
   457  	}
   458  }
   459  
   460  // InterfaceStatistics represents the interface's statistics
   461  type InterfaceStatistics struct {
   462  	RxBytes   uint64
   463  	RxPackets uint64
   464  	RxErrors  uint64
   465  	RxDropped uint64
   466  	TxBytes   uint64
   467  	TxPackets uint64
   468  	TxErrors  uint64
   469  	TxDropped uint64
   470  }
   471  
   472  func (is *InterfaceStatistics) String() string {
   473  	return fmt.Sprintf("\nRxBytes: %d, RxPackets: %d, RxErrors: %d, RxDropped: %d, TxBytes: %d, TxPackets: %d, TxErrors: %d, TxDropped: %d",
   474  		is.RxBytes, is.RxPackets, is.RxErrors, is.RxDropped, is.TxBytes, is.TxPackets, is.TxErrors, is.TxDropped)
   475  }
   476  
   477  /******************************
   478   * Well-known Error Interfaces
   479   ******************************/
   480  
   481  // MaskableError is an interface for errors which can be ignored by caller
   482  type MaskableError interface {
   483  	// Maskable makes implementer into MaskableError type
   484  	Maskable()
   485  }
   486  
   487  // RetryError is an interface for errors which might get resolved through retry
   488  type RetryError interface {
   489  	// Retry makes implementer into RetryError type
   490  	Retry()
   491  }
   492  
   493  // BadRequestError is an interface for errors originated by a bad request
   494  type BadRequestError interface {
   495  	// BadRequest makes implementer into BadRequestError type
   496  	BadRequest()
   497  }
   498  
   499  // NotFoundError is an interface for errors raised because a needed resource is not available
   500  type NotFoundError interface {
   501  	// NotFound makes implementer into NotFoundError type
   502  	NotFound()
   503  }
   504  
   505  // ForbiddenError is an interface for errors which denote a valid request that cannot be honored
   506  type ForbiddenError interface {
   507  	// Forbidden makes implementer into ForbiddenError type
   508  	Forbidden()
   509  }
   510  
   511  // NoServiceError is an interface for errors returned when the required service is not available
   512  type NoServiceError interface {
   513  	// NoService makes implementer into NoServiceError type
   514  	NoService()
   515  }
   516  
   517  // TimeoutError is an interface for errors raised because of timeout
   518  type TimeoutError interface {
   519  	// Timeout makes implementer into TimeoutError type
   520  	Timeout()
   521  }
   522  
   523  // NotImplementedError is an interface for errors raised because of requested functionality is not yet implemented
   524  type NotImplementedError interface {
   525  	// NotImplemented makes implementer into NotImplementedError type
   526  	NotImplemented()
   527  }
   528  
   529  // InternalError is an interface for errors raised because of an internal error
   530  type InternalError interface {
   531  	// Internal makes implementer into InternalError type
   532  	Internal()
   533  }
   534  
   535  /******************************
   536   * Well-known Error Formatters
   537   ******************************/
   538  
   539  // BadRequestErrorf creates an instance of BadRequestError
   540  func BadRequestErrorf(format string, params ...interface{}) error {
   541  	return badRequest(fmt.Sprintf(format, params...))
   542  }
   543  
   544  // NotFoundErrorf creates an instance of NotFoundError
   545  func NotFoundErrorf(format string, params ...interface{}) error {
   546  	return notFound(fmt.Sprintf(format, params...))
   547  }
   548  
   549  // ForbiddenErrorf creates an instance of ForbiddenError
   550  func ForbiddenErrorf(format string, params ...interface{}) error {
   551  	return forbidden(fmt.Sprintf(format, params...))
   552  }
   553  
   554  // NoServiceErrorf creates an instance of NoServiceError
   555  func NoServiceErrorf(format string, params ...interface{}) error {
   556  	return noService(fmt.Sprintf(format, params...))
   557  }
   558  
   559  // NotImplementedErrorf creates an instance of NotImplementedError
   560  func NotImplementedErrorf(format string, params ...interface{}) error {
   561  	return notImpl(fmt.Sprintf(format, params...))
   562  }
   563  
   564  // TimeoutErrorf creates an instance of TimeoutError
   565  func TimeoutErrorf(format string, params ...interface{}) error {
   566  	return timeout(fmt.Sprintf(format, params...))
   567  }
   568  
   569  // InternalErrorf creates an instance of InternalError
   570  func InternalErrorf(format string, params ...interface{}) error {
   571  	return internal(fmt.Sprintf(format, params...))
   572  }
   573  
   574  // InternalMaskableErrorf creates an instance of InternalError and MaskableError
   575  func InternalMaskableErrorf(format string, params ...interface{}) error {
   576  	return maskInternal(fmt.Sprintf(format, params...))
   577  }
   578  
   579  // RetryErrorf creates an instance of RetryError
   580  func RetryErrorf(format string, params ...interface{}) error {
   581  	return retry(fmt.Sprintf(format, params...))
   582  }
   583  
   584  /***********************
   585   * Internal Error Types
   586   ***********************/
   587  type badRequest string
   588  
   589  func (br badRequest) Error() string {
   590  	return string(br)
   591  }
   592  func (br badRequest) BadRequest() {}
   593  
   594  type notFound string
   595  
   596  func (nf notFound) Error() string {
   597  	return string(nf)
   598  }
   599  func (nf notFound) NotFound() {}
   600  
   601  type forbidden string
   602  
   603  func (frb forbidden) Error() string {
   604  	return string(frb)
   605  }
   606  func (frb forbidden) Forbidden() {}
   607  
   608  type noService string
   609  
   610  func (ns noService) Error() string {
   611  	return string(ns)
   612  }
   613  func (ns noService) NoService() {}
   614  
   615  type timeout string
   616  
   617  func (to timeout) Error() string {
   618  	return string(to)
   619  }
   620  func (to timeout) Timeout() {}
   621  
   622  type notImpl string
   623  
   624  func (ni notImpl) Error() string {
   625  	return string(ni)
   626  }
   627  func (ni notImpl) NotImplemented() {}
   628  
   629  type internal string
   630  
   631  func (nt internal) Error() string {
   632  	return string(nt)
   633  }
   634  func (nt internal) Internal() {}
   635  
   636  type maskInternal string
   637  
   638  func (mnt maskInternal) Error() string {
   639  	return string(mnt)
   640  }
   641  func (mnt maskInternal) Internal() {}
   642  func (mnt maskInternal) Maskable() {}
   643  
   644  type retry string
   645  
   646  func (r retry) Error() string {
   647  	return string(r)
   648  }
   649  func (r retry) Retry() {}