types.go 15 KB

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