github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/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 "strings" 9 10 "github.com/ishidawataru/sctp" 11 ) 12 13 // constants for the IP address type 14 // Deprecated: use the consts defined in github.com/docker/docker/libnetwork/resolvconf 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 // PortBinding represents a port binding between the container and the host 72 type PortBinding struct { 73 Proto Protocol 74 IP net.IP 75 Port uint16 76 HostIP net.IP 77 HostPort uint16 78 HostPortEnd uint16 79 } 80 81 // HostAddr returns the host side transport address 82 func (p PortBinding) HostAddr() (net.Addr, error) { 83 switch p.Proto { 84 case UDP: 85 return &net.UDPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil 86 case TCP: 87 return &net.TCPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil 88 case SCTP: 89 return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.HostIP}}, Port: int(p.HostPort)}, nil 90 default: 91 return nil, ErrInvalidProtocolBinding(p.Proto.String()) 92 } 93 } 94 95 // ContainerAddr returns the container side transport address 96 func (p PortBinding) ContainerAddr() (net.Addr, error) { 97 switch p.Proto { 98 case UDP: 99 return &net.UDPAddr{IP: p.IP, Port: int(p.Port)}, nil 100 case TCP: 101 return &net.TCPAddr{IP: p.IP, Port: int(p.Port)}, nil 102 case SCTP: 103 return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.IP}}, Port: int(p.Port)}, nil 104 default: 105 return nil, ErrInvalidProtocolBinding(p.Proto.String()) 106 } 107 } 108 109 // GetCopy returns a copy of this PortBinding structure instance 110 func (p *PortBinding) GetCopy() PortBinding { 111 return PortBinding{ 112 Proto: p.Proto, 113 IP: GetIPCopy(p.IP), 114 Port: p.Port, 115 HostIP: GetIPCopy(p.HostIP), 116 HostPort: p.HostPort, 117 HostPortEnd: p.HostPortEnd, 118 } 119 } 120 121 // String returns the PortBinding structure in string form 122 func (p *PortBinding) String() string { 123 ret := fmt.Sprintf("%s/", p.Proto) 124 if p.IP != nil { 125 ret += p.IP.String() 126 } 127 ret = fmt.Sprintf("%s:%d/", ret, p.Port) 128 if p.HostIP != nil { 129 ret += p.HostIP.String() 130 } 131 ret = fmt.Sprintf("%s:%d", ret, p.HostPort) 132 return ret 133 } 134 135 // Equal checks if this instance of PortBinding is equal to the passed one 136 func (p *PortBinding) Equal(o *PortBinding) bool { 137 if p == o { 138 return true 139 } 140 141 if o == nil { 142 return false 143 } 144 145 if p.Proto != o.Proto || p.Port != o.Port || 146 p.HostPort != o.HostPort || p.HostPortEnd != o.HostPortEnd { 147 return false 148 } 149 150 if p.IP != nil { 151 if !p.IP.Equal(o.IP) { 152 return false 153 } 154 } else { 155 if o.IP != nil { 156 return false 157 } 158 } 159 160 if p.HostIP != nil { 161 if !p.HostIP.Equal(o.HostIP) { 162 return false 163 } 164 } else { 165 if o.HostIP != nil { 166 return false 167 } 168 } 169 170 return true 171 } 172 173 // ErrInvalidProtocolBinding is returned when the port binding protocol is not valid. 174 type ErrInvalidProtocolBinding string 175 176 func (ipb ErrInvalidProtocolBinding) Error() string { 177 return fmt.Sprintf("invalid transport protocol: %s", string(ipb)) 178 } 179 180 const ( 181 // ICMP is for the ICMP ip protocol 182 ICMP = 1 183 // TCP is for the TCP ip protocol 184 TCP = 6 185 // UDP is for the UDP ip protocol 186 UDP = 17 187 // SCTP is for the SCTP ip protocol 188 SCTP = 132 189 ) 190 191 // Protocol represents an IP protocol number 192 type Protocol uint8 193 194 func (p Protocol) String() string { 195 switch p { 196 case ICMP: 197 return "icmp" 198 case TCP: 199 return "tcp" 200 case UDP: 201 return "udp" 202 case SCTP: 203 return "sctp" 204 default: 205 return fmt.Sprintf("%d", p) 206 } 207 } 208 209 // ParseProtocol returns the respective Protocol type for the passed string 210 func ParseProtocol(s string) Protocol { 211 switch strings.ToLower(s) { 212 case "icmp": 213 return ICMP 214 case "udp": 215 return UDP 216 case "tcp": 217 return TCP 218 case "sctp": 219 return SCTP 220 default: 221 return 0 222 } 223 } 224 225 // GetMacCopy returns a copy of the passed MAC address 226 func GetMacCopy(from net.HardwareAddr) net.HardwareAddr { 227 if from == nil { 228 return nil 229 } 230 to := make(net.HardwareAddr, len(from)) 231 copy(to, from) 232 return to 233 } 234 235 // GetIPCopy returns a copy of the passed IP address 236 func GetIPCopy(from net.IP) net.IP { 237 if from == nil { 238 return nil 239 } 240 to := make(net.IP, len(from)) 241 copy(to, from) 242 return to 243 } 244 245 // GetIPNetCopy returns a copy of the passed IP Network 246 func GetIPNetCopy(from *net.IPNet) *net.IPNet { 247 if from == nil { 248 return nil 249 } 250 bm := make(net.IPMask, len(from.Mask)) 251 copy(bm, from.Mask) 252 return &net.IPNet{IP: GetIPCopy(from.IP), Mask: bm} 253 } 254 255 // GetIPNetCanonical returns the canonical form for the passed network 256 func GetIPNetCanonical(nw *net.IPNet) *net.IPNet { 257 if nw == nil { 258 return nil 259 } 260 c := GetIPNetCopy(nw) 261 c.IP = c.IP.Mask(nw.Mask) 262 return c 263 } 264 265 // CompareIPNet returns equal if the two IP Networks are equal 266 func CompareIPNet(a, b *net.IPNet) bool { 267 if a == b { 268 return true 269 } 270 if a == nil || b == nil { 271 return false 272 } 273 return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask) 274 } 275 276 // GetMinimalIP returns the address in its shortest form 277 // If ip contains an IPv4-mapped IPv6 address, the 4-octet form of the IPv4 address will be returned. 278 // Otherwise ip is returned unchanged. 279 func GetMinimalIP(ip net.IP) net.IP { 280 if ip != nil && ip.To4() != nil { 281 return ip.To4() 282 } 283 return ip 284 } 285 286 // IsIPNetValid returns true if the ipnet is a valid network/mask 287 // combination. Otherwise returns false. 288 func IsIPNetValid(nw *net.IPNet) bool { 289 return nw.String() != "0.0.0.0/0" 290 } 291 292 var v4inV6MaskPrefix = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} 293 294 // compareIPMask checks if the passed ip and mask are semantically compatible. 295 // It returns the byte indexes for the address and mask so that caller can 296 // do bitwise operations without modifying address representation. 297 func compareIPMask(ip net.IP, mask net.IPMask) (is int, ms int, err error) { 298 // Find the effective starting of address and mask 299 if len(ip) == net.IPv6len && ip.To4() != nil { 300 is = 12 301 } 302 if len(ip[is:]) == net.IPv4len && len(mask) == net.IPv6len && bytes.Equal(mask[:12], v4inV6MaskPrefix) { 303 ms = 12 304 } 305 // Check if address and mask are semantically compatible 306 if len(ip[is:]) != len(mask[ms:]) { 307 err = fmt.Errorf("ip and mask are not compatible: (%#v, %#v)", ip, mask) 308 } 309 return 310 } 311 312 // GetHostPartIP returns the host portion of the ip address identified by the mask. 313 // IP address representation is not modified. If address and mask are not compatible 314 // an error is returned. 315 func GetHostPartIP(ip net.IP, mask net.IPMask) (net.IP, error) { 316 // Find the effective starting of address and mask 317 is, ms, err := compareIPMask(ip, mask) 318 if err != nil { 319 return nil, fmt.Errorf("cannot compute host portion ip address because %s", err) 320 } 321 322 // Compute host portion 323 out := GetIPCopy(ip) 324 for i := 0; i < len(mask[ms:]); i++ { 325 out[is+i] &= ^mask[ms+i] 326 } 327 328 return out, nil 329 } 330 331 // GetBroadcastIP returns the broadcast ip address for the passed network (ip and mask). 332 // IP address representation is not modified. If address and mask are not compatible 333 // an error is returned. 334 func GetBroadcastIP(ip net.IP, mask net.IPMask) (net.IP, error) { 335 // Find the effective starting of address and mask 336 is, ms, err := compareIPMask(ip, mask) 337 if err != nil { 338 return nil, fmt.Errorf("cannot compute broadcast ip address because %s", err) 339 } 340 341 // Compute broadcast address 342 out := GetIPCopy(ip) 343 for i := 0; i < len(mask[ms:]); i++ { 344 out[is+i] |= ^mask[ms+i] 345 } 346 347 return out, nil 348 } 349 350 // ParseCIDR returns the *net.IPNet represented by the passed CIDR notation 351 func ParseCIDR(cidr string) (n *net.IPNet, e error) { 352 var i net.IP 353 if i, n, e = net.ParseCIDR(cidr); e == nil { 354 n.IP = i 355 } 356 return 357 } 358 359 const ( 360 // NEXTHOP indicates a StaticRoute with an IP next hop. 361 NEXTHOP = iota 362 363 // CONNECTED indicates a StaticRoute with an interface for directly connected peers. 364 CONNECTED 365 ) 366 367 // StaticRoute is a statically-provisioned IP route. 368 type StaticRoute struct { 369 Destination *net.IPNet 370 371 RouteType int // NEXT_HOP or CONNECTED 372 373 // NextHop will be resolved by the kernel (i.e. as a loose hop). 374 NextHop net.IP 375 } 376 377 // GetCopy returns a copy of this StaticRoute structure 378 func (r *StaticRoute) GetCopy() *StaticRoute { 379 d := GetIPNetCopy(r.Destination) 380 nh := GetIPCopy(r.NextHop) 381 return &StaticRoute{Destination: d, 382 RouteType: r.RouteType, 383 NextHop: nh, 384 } 385 } 386 387 // InterfaceStatistics represents the interface's statistics 388 type InterfaceStatistics struct { 389 RxBytes uint64 390 RxPackets uint64 391 RxErrors uint64 392 RxDropped uint64 393 TxBytes uint64 394 TxPackets uint64 395 TxErrors uint64 396 TxDropped uint64 397 } 398 399 func (is *InterfaceStatistics) String() string { 400 return fmt.Sprintf("\nRxBytes: %d, RxPackets: %d, RxErrors: %d, RxDropped: %d, TxBytes: %d, TxPackets: %d, TxErrors: %d, TxDropped: %d", 401 is.RxBytes, is.RxPackets, is.RxErrors, is.RxDropped, is.TxBytes, is.TxPackets, is.TxErrors, is.TxDropped) 402 } 403 404 /****************************** 405 * Well-known Error Interfaces 406 ******************************/ 407 408 // MaskableError is an interface for errors which can be ignored by caller 409 type MaskableError interface { 410 // Maskable makes implementer into MaskableError type 411 Maskable() 412 } 413 414 // RetryError is an interface for errors which might get resolved through retry 415 type RetryError interface { 416 // Retry makes implementer into RetryError type 417 Retry() 418 } 419 420 // BadRequestError is an interface for errors originated by a bad request 421 type BadRequestError interface { 422 // BadRequest makes implementer into BadRequestError type 423 BadRequest() 424 } 425 426 // NotFoundError is an interface for errors raised because a needed resource is not available 427 type NotFoundError interface { 428 // NotFound makes implementer into NotFoundError type 429 NotFound() 430 } 431 432 // ForbiddenError is an interface for errors which denote a valid request that cannot be honored 433 type ForbiddenError interface { 434 // Forbidden makes implementer into ForbiddenError type 435 Forbidden() 436 } 437 438 // NoServiceError is an interface for errors returned when the required service is not available 439 type NoServiceError interface { 440 // NoService makes implementer into NoServiceError type 441 NoService() 442 } 443 444 // TimeoutError is an interface for errors raised because of timeout 445 type TimeoutError interface { 446 // Timeout makes implementer into TimeoutError type 447 Timeout() 448 } 449 450 // NotImplementedError is an interface for errors raised because of requested functionality is not yet implemented 451 type NotImplementedError interface { 452 // NotImplemented makes implementer into NotImplementedError type 453 NotImplemented() 454 } 455 456 // InternalError is an interface for errors raised because of an internal error 457 type InternalError interface { 458 // Internal makes implementer into InternalError type 459 Internal() 460 } 461 462 /****************************** 463 * Well-known Error Formatters 464 ******************************/ 465 466 // BadRequestErrorf creates an instance of BadRequestError 467 func BadRequestErrorf(format string, params ...interface{}) error { 468 return badRequest(fmt.Sprintf(format, params...)) 469 } 470 471 // NotFoundErrorf creates an instance of NotFoundError 472 func NotFoundErrorf(format string, params ...interface{}) error { 473 return notFound(fmt.Sprintf(format, params...)) 474 } 475 476 // ForbiddenErrorf creates an instance of ForbiddenError 477 func ForbiddenErrorf(format string, params ...interface{}) error { 478 return forbidden(fmt.Sprintf(format, params...)) 479 } 480 481 // NoServiceErrorf creates an instance of NoServiceError 482 func NoServiceErrorf(format string, params ...interface{}) error { 483 return noService(fmt.Sprintf(format, params...)) 484 } 485 486 // NotImplementedErrorf creates an instance of NotImplementedError 487 func NotImplementedErrorf(format string, params ...interface{}) error { 488 return notImpl(fmt.Sprintf(format, params...)) 489 } 490 491 // TimeoutErrorf creates an instance of TimeoutError 492 func TimeoutErrorf(format string, params ...interface{}) error { 493 return timeout(fmt.Sprintf(format, params...)) 494 } 495 496 // InternalErrorf creates an instance of InternalError 497 func InternalErrorf(format string, params ...interface{}) error { 498 return internal(fmt.Sprintf(format, params...)) 499 } 500 501 // InternalMaskableErrorf creates an instance of InternalError and MaskableError 502 func InternalMaskableErrorf(format string, params ...interface{}) error { 503 return maskInternal(fmt.Sprintf(format, params...)) 504 } 505 506 // RetryErrorf creates an instance of RetryError 507 func RetryErrorf(format string, params ...interface{}) error { 508 return retry(fmt.Sprintf(format, params...)) 509 } 510 511 /*********************** 512 * Internal Error Types 513 ***********************/ 514 type badRequest string 515 516 func (br badRequest) Error() string { 517 return string(br) 518 } 519 func (br badRequest) BadRequest() {} 520 521 type notFound string 522 523 func (nf notFound) Error() string { 524 return string(nf) 525 } 526 func (nf notFound) NotFound() {} 527 528 type forbidden string 529 530 func (frb forbidden) Error() string { 531 return string(frb) 532 } 533 func (frb forbidden) Forbidden() {} 534 535 type noService string 536 537 func (ns noService) Error() string { 538 return string(ns) 539 } 540 func (ns noService) NoService() {} 541 542 type timeout string 543 544 func (to timeout) Error() string { 545 return string(to) 546 } 547 func (to timeout) Timeout() {} 548 549 type notImpl string 550 551 func (ni notImpl) Error() string { 552 return string(ni) 553 } 554 func (ni notImpl) NotImplemented() {} 555 556 type internal string 557 558 func (nt internal) Error() string { 559 return string(nt) 560 } 561 func (nt internal) Internal() {} 562 563 type maskInternal string 564 565 func (mnt maskInternal) Error() string { 566 return string(mnt) 567 } 568 func (mnt maskInternal) Internal() {} 569 func (mnt maskInternal) Maskable() {} 570 571 type retry string 572 573 func (r retry) Error() string { 574 return string(r) 575 } 576 func (r retry) Retry() {}