types.go 15 KB

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