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() {}