listen_addr.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package cluster // import "github.com/docker/docker/daemon/cluster"
  2. import (
  3. "fmt"
  4. "net"
  5. "strings"
  6. )
  7. const (
  8. errNoSuchInterface configError = "no such interface"
  9. errNoIP configError = "could not find the system's IP address"
  10. errMustSpecifyListenAddr configError = "must specify a listening address because the address to advertise is not recognized as a system address, and a system's IP address to use could not be uniquely identified"
  11. errBadNetworkIdentifier configError = "must specify a valid IP address or interface name"
  12. errBadListenAddr configError = "listen address must be an IP address or network interface (with optional port number)"
  13. errBadAdvertiseAddr configError = "advertise address must be a non-zero IP address or network interface (with optional port number)"
  14. errBadDataPathAddr configError = "data path address must be a non-zero IP address or network interface (without a port number)"
  15. errBadDefaultAdvertiseAddr configError = "default advertise address must be a non-zero IP address or network interface (without a port number)"
  16. )
  17. func resolveListenAddr(specifiedAddr string) (string, string, error) {
  18. specifiedHost, specifiedPort, err := net.SplitHostPort(specifiedAddr)
  19. if err != nil {
  20. return "", "", configError("could not parse listen address " + specifiedAddr)
  21. }
  22. // Does the host component match any of the interface names on the
  23. // system? If so, use the address from that interface.
  24. specifiedIP, err := resolveInputIPAddr(specifiedHost, true)
  25. if err != nil {
  26. if err == errBadNetworkIdentifier {
  27. err = errBadListenAddr
  28. }
  29. return "", "", err
  30. }
  31. return specifiedIP.String(), specifiedPort, nil
  32. }
  33. func (c *Cluster) resolveAdvertiseAddr(advertiseAddr, listenAddrPort string) (string, string, error) {
  34. // Approach:
  35. // - If an advertise address is specified, use that. Resolve the
  36. // interface's address if an interface was specified in
  37. // advertiseAddr. Fill in the port from listenAddrPort if necessary.
  38. // - If DefaultAdvertiseAddr is not empty, use that with the port from
  39. // listenAddrPort. Resolve the interface's address from
  40. // if an interface name was specified in DefaultAdvertiseAddr.
  41. // - Otherwise, try to autodetect the system's address. Use the port in
  42. // listenAddrPort with this address if autodetection succeeds.
  43. if advertiseAddr != "" {
  44. advertiseHost, advertisePort, err := net.SplitHostPort(advertiseAddr)
  45. if err != nil {
  46. // Not a host:port specification
  47. advertiseHost = advertiseAddr
  48. advertisePort = listenAddrPort
  49. }
  50. // Does the host component match any of the interface names on the
  51. // system? If so, use the address from that interface.
  52. advertiseIP, err := resolveInputIPAddr(advertiseHost, false)
  53. if err != nil {
  54. if err == errBadNetworkIdentifier {
  55. err = errBadAdvertiseAddr
  56. }
  57. return "", "", err
  58. }
  59. return advertiseIP.String(), advertisePort, nil
  60. }
  61. if c.config.DefaultAdvertiseAddr != "" {
  62. // Does the default advertise address component match any of the
  63. // interface names on the system? If so, use the address from
  64. // that interface.
  65. defaultAdvertiseIP, err := resolveInputIPAddr(c.config.DefaultAdvertiseAddr, false)
  66. if err != nil {
  67. if err == errBadNetworkIdentifier {
  68. err = errBadDefaultAdvertiseAddr
  69. }
  70. return "", "", err
  71. }
  72. return defaultAdvertiseIP.String(), listenAddrPort, nil
  73. }
  74. systemAddr, err := c.resolveSystemAddr()
  75. if err != nil {
  76. return "", "", err
  77. }
  78. return systemAddr.String(), listenAddrPort, nil
  79. }
  80. // validateDefaultAddrPool validates default address pool
  81. // it also strips white space from the string before validation
  82. func validateDefaultAddrPool(defaultAddrPool []string, size uint32) error {
  83. if defaultAddrPool == nil {
  84. // defaultAddrPool is not defined
  85. return nil
  86. }
  87. // if size is not set, then we use default value 24
  88. if size == 0 {
  89. size = 24
  90. }
  91. // We allow max value as 29. We can have 8 IP addresses for max value 29
  92. // If we allow 30, then we will get only 4 IP addresses. But with latest
  93. // libnetwork LB scale implementation, we use total of 4 IP addresses for internal use.
  94. // Hence keeping 29 as max value, we will have 8 IP addresses. This will be
  95. // smallest subnet that can be used in overlay network.
  96. if size > 29 {
  97. return fmt.Errorf("subnet size is out of range: %d", size)
  98. }
  99. for i := range defaultAddrPool {
  100. // trim leading and trailing white spaces
  101. defaultAddrPool[i] = strings.TrimSpace(defaultAddrPool[i])
  102. _, b, err := net.ParseCIDR(defaultAddrPool[i])
  103. if err != nil {
  104. return fmt.Errorf("invalid base pool %s: %v", defaultAddrPool[i], err)
  105. }
  106. ones, _ := b.Mask.Size()
  107. if size < uint32(ones) {
  108. return fmt.Errorf("invalid CIDR: %q. Subnet size is too small for pool: %d", defaultAddrPool[i], size)
  109. }
  110. }
  111. return nil
  112. }
  113. // getDataPathPort validates vxlan udp port (data path port) number.
  114. // if no port is set, the default (4789) is returned
  115. // valid port numbers are between 1024 and 49151
  116. func getDataPathPort(portNum uint32) (uint32, error) {
  117. // if the value comes as 0 by any reason we set it to default value 4789
  118. if portNum == 0 {
  119. portNum = 4789
  120. return portNum, nil
  121. }
  122. // IANA procedures for each range in detail
  123. // The Well Known Ports, aka the System Ports, from 0-1023
  124. // The Registered Ports, aka the User Ports, from 1024-49151
  125. // The Dynamic Ports, aka the Private Ports, from 49152-65535
  126. // So we can allow range between 1024 to 49151
  127. if portNum < 1024 || portNum > 49151 {
  128. return 0, fmt.Errorf("Datapath port number is not in valid range (1024-49151) : %d", portNum)
  129. }
  130. return portNum, nil
  131. }
  132. func resolveDataPathAddr(dataPathAddr string) (string, error) {
  133. if dataPathAddr == "" {
  134. // dataPathAddr is not defined
  135. return "", nil
  136. }
  137. // If a data path flag is specified try to resolve the IP address.
  138. dataPathIP, err := resolveInputIPAddr(dataPathAddr, false)
  139. if err != nil {
  140. if err == errBadNetworkIdentifier {
  141. err = errBadDataPathAddr
  142. }
  143. return "", err
  144. }
  145. return dataPathIP.String(), nil
  146. }
  147. func resolveInterfaceAddr(specifiedInterface string) (net.IP, error) {
  148. // Use a specific interface's IP address.
  149. intf, err := net.InterfaceByName(specifiedInterface)
  150. if err != nil {
  151. return nil, errNoSuchInterface
  152. }
  153. addrs, err := intf.Addrs()
  154. if err != nil {
  155. return nil, err
  156. }
  157. var interfaceAddr4, interfaceAddr6 net.IP
  158. for _, addr := range addrs {
  159. ipAddr, ok := addr.(*net.IPNet)
  160. if ok {
  161. if ipAddr.IP.To4() != nil {
  162. // IPv4
  163. if interfaceAddr4 != nil {
  164. return nil, configError(fmt.Sprintf("interface %s has more than one IPv4 address (%s and %s)", specifiedInterface, interfaceAddr4, ipAddr.IP))
  165. }
  166. interfaceAddr4 = ipAddr.IP
  167. } else {
  168. // IPv6
  169. if interfaceAddr6 != nil {
  170. return nil, configError(fmt.Sprintf("interface %s has more than one IPv6 address (%s and %s)", specifiedInterface, interfaceAddr6, ipAddr.IP))
  171. }
  172. interfaceAddr6 = ipAddr.IP
  173. }
  174. }
  175. }
  176. if interfaceAddr4 == nil && interfaceAddr6 == nil {
  177. return nil, configError(fmt.Sprintf("interface %s has no usable IPv4 or IPv6 address", specifiedInterface))
  178. }
  179. // In the case that there's exactly one IPv4 address
  180. // and exactly one IPv6 address, favor IPv4 over IPv6.
  181. if interfaceAddr4 != nil {
  182. return interfaceAddr4, nil
  183. }
  184. return interfaceAddr6, nil
  185. }
  186. // resolveInputIPAddr tries to resolve the IP address from the string passed as input
  187. // - tries to match the string as an interface name, if so returns the IP address associated with it
  188. // - on failure of previous step tries to parse the string as an IP address itself
  189. // if succeeds returns the IP address
  190. func resolveInputIPAddr(input string, isUnspecifiedValid bool) (net.IP, error) {
  191. // Try to see if it is an interface name
  192. interfaceAddr, err := resolveInterfaceAddr(input)
  193. if err == nil {
  194. return interfaceAddr, nil
  195. }
  196. // String matched interface but there is a potential ambiguity to be resolved
  197. if err != errNoSuchInterface {
  198. return nil, err
  199. }
  200. // String is not an interface check if it is a valid IP
  201. if ip := net.ParseIP(input); ip != nil && (isUnspecifiedValid || !ip.IsUnspecified()) {
  202. return ip, nil
  203. }
  204. // Not valid IP found
  205. return nil, errBadNetworkIdentifier
  206. }
  207. func (c *Cluster) resolveSystemAddrViaSubnetCheck() (net.IP, error) {
  208. // Use the system's only IP address, or fail if there are
  209. // multiple addresses to choose from. Skip interfaces which
  210. // are managed by docker via subnet check.
  211. interfaces, err := net.Interfaces()
  212. if err != nil {
  213. return nil, err
  214. }
  215. var systemAddr net.IP
  216. var systemInterface string
  217. // List Docker-managed subnets
  218. v4Subnets, v6Subnets := c.config.NetworkSubnetsProvider.Subnets()
  219. ifaceLoop:
  220. for _, intf := range interfaces {
  221. // Skip inactive interfaces and loopback interfaces
  222. if (intf.Flags&net.FlagUp == 0) || (intf.Flags&net.FlagLoopback) != 0 {
  223. continue
  224. }
  225. addrs, err := intf.Addrs()
  226. if err != nil {
  227. continue
  228. }
  229. var interfaceAddr4, interfaceAddr6 net.IP
  230. for _, addr := range addrs {
  231. ipAddr, ok := addr.(*net.IPNet)
  232. // Skip loopback and link-local addresses
  233. if !ok || !ipAddr.IP.IsGlobalUnicast() {
  234. continue
  235. }
  236. if ipAddr.IP.To4() != nil {
  237. // IPv4
  238. // Ignore addresses in subnets that are managed by Docker.
  239. for _, subnet := range v4Subnets {
  240. if subnet.Contains(ipAddr.IP) {
  241. continue ifaceLoop
  242. }
  243. }
  244. if interfaceAddr4 != nil {
  245. return nil, errMultipleIPs(intf.Name, intf.Name, interfaceAddr4, ipAddr.IP)
  246. }
  247. interfaceAddr4 = ipAddr.IP
  248. } else {
  249. // IPv6
  250. // Ignore addresses in subnets that are managed by Docker.
  251. for _, subnet := range v6Subnets {
  252. if subnet.Contains(ipAddr.IP) {
  253. continue ifaceLoop
  254. }
  255. }
  256. if interfaceAddr6 != nil {
  257. return nil, errMultipleIPs(intf.Name, intf.Name, interfaceAddr6, ipAddr.IP)
  258. }
  259. interfaceAddr6 = ipAddr.IP
  260. }
  261. }
  262. // In the case that this interface has exactly one IPv4 address
  263. // and exactly one IPv6 address, favor IPv4 over IPv6.
  264. if interfaceAddr4 != nil {
  265. if systemAddr != nil {
  266. return nil, errMultipleIPs(systemInterface, intf.Name, systemAddr, interfaceAddr4)
  267. }
  268. systemAddr = interfaceAddr4
  269. systemInterface = intf.Name
  270. } else if interfaceAddr6 != nil {
  271. if systemAddr != nil {
  272. return nil, errMultipleIPs(systemInterface, intf.Name, systemAddr, interfaceAddr6)
  273. }
  274. systemAddr = interfaceAddr6
  275. systemInterface = intf.Name
  276. }
  277. }
  278. if systemAddr == nil {
  279. return nil, errNoIP
  280. }
  281. return systemAddr, nil
  282. }
  283. func listSystemIPs() []net.IP {
  284. interfaces, err := net.Interfaces()
  285. if err != nil {
  286. return nil
  287. }
  288. var systemAddrs []net.IP
  289. for _, intf := range interfaces {
  290. addrs, err := intf.Addrs()
  291. if err != nil {
  292. continue
  293. }
  294. for _, addr := range addrs {
  295. ipAddr, ok := addr.(*net.IPNet)
  296. if ok {
  297. systemAddrs = append(systemAddrs, ipAddr.IP)
  298. }
  299. }
  300. }
  301. return systemAddrs
  302. }
  303. func errMultipleIPs(interfaceA, interfaceB string, addrA, addrB net.IP) error {
  304. if interfaceA == interfaceB {
  305. return configError(fmt.Sprintf("could not choose an IP address to advertise since this system has multiple addresses on interface %s (%s and %s)", interfaceA, addrA, addrB))
  306. }
  307. return configError(fmt.Sprintf("could not choose an IP address to advertise since this system has multiple addresses on different interfaces (%s on %s and %s on %s)", addrA, interfaceA, addrB, interfaceB))
  308. }