network.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. package docker
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "log"
  8. "net"
  9. "os/exec"
  10. "strconv"
  11. "strings"
  12. )
  13. const (
  14. networkBridgeIface = "lxcbr0"
  15. portRangeStart = 49153
  16. portRangeEnd = 65535
  17. )
  18. // Calculates the first and last IP addresses in an IPNet
  19. func networkRange(network *net.IPNet) (net.IP, net.IP) {
  20. netIP := network.IP.To4()
  21. firstIP := netIP.Mask(network.Mask)
  22. lastIP := net.IPv4(0, 0, 0, 0).To4()
  23. for i := 0; i < len(lastIP); i++ {
  24. lastIP[i] = netIP[i] | ^network.Mask[i]
  25. }
  26. return firstIP, lastIP
  27. }
  28. // Converts a 4 bytes IP into a 32 bit integer
  29. func ipToInt(ip net.IP) (int32, error) {
  30. buf := bytes.NewBuffer(ip.To4())
  31. var n int32
  32. if err := binary.Read(buf, binary.BigEndian, &n); err != nil {
  33. return 0, err
  34. }
  35. return n, nil
  36. }
  37. // Converts 32 bit integer into a 4 bytes IP address
  38. func intToIp(n int32) (net.IP, error) {
  39. var buf bytes.Buffer
  40. if err := binary.Write(&buf, binary.BigEndian, &n); err != nil {
  41. return net.IP{}, err
  42. }
  43. ip := net.IPv4(0, 0, 0, 0).To4()
  44. for i := 0; i < net.IPv4len; i++ {
  45. ip[i] = buf.Bytes()[i]
  46. }
  47. return ip, nil
  48. }
  49. // Given a netmask, calculates the number of available hosts
  50. func networkSize(mask net.IPMask) (int32, error) {
  51. m := net.IPv4Mask(0, 0, 0, 0)
  52. for i := 0; i < net.IPv4len; i++ {
  53. m[i] = ^mask[i]
  54. }
  55. buf := bytes.NewBuffer(m)
  56. var n int32
  57. if err := binary.Read(buf, binary.BigEndian, &n); err != nil {
  58. return 0, err
  59. }
  60. return n + 1, nil
  61. }
  62. // Wrapper around the iptables command
  63. func iptables(args ...string) error {
  64. if err := exec.Command("/sbin/iptables", args...).Run(); err != nil {
  65. return fmt.Errorf("iptables failed: iptables %v", strings.Join(args, " "))
  66. }
  67. return nil
  68. }
  69. // Return the IPv4 address of a network interface
  70. func getIfaceAddr(name string) (net.Addr, error) {
  71. iface, err := net.InterfaceByName(name)
  72. if err != nil {
  73. return nil, err
  74. }
  75. addrs, err := iface.Addrs()
  76. if err != nil {
  77. return nil, err
  78. }
  79. var addrs4 []net.Addr
  80. for _, addr := range addrs {
  81. ip := (addr.(*net.IPNet)).IP
  82. if ip4 := ip.To4(); len(ip4) == net.IPv4len {
  83. addrs4 = append(addrs4, addr)
  84. }
  85. }
  86. switch {
  87. case len(addrs4) == 0:
  88. return nil, fmt.Errorf("Interface %v has no IP addresses", name)
  89. case len(addrs4) > 1:
  90. return nil, fmt.Errorf("Interface %v has more than 1 IPv4 address", name)
  91. }
  92. return addrs4[0], nil
  93. }
  94. // Port mapper takes care of mapping external ports to containers by setting
  95. // up iptables rules.
  96. // It keeps track of all mappings and is able to unmap at will
  97. type PortMapper struct {
  98. mapping map[int]net.TCPAddr
  99. }
  100. func (mapper *PortMapper) cleanup() error {
  101. // Ignore errors - This could mean the chains were never set up
  102. iptables("-t", "nat", "-D", "PREROUTING", "-j", "DOCKER")
  103. iptables("-t", "nat", "-F", "DOCKER")
  104. iptables("-t", "nat", "-X", "DOCKER")
  105. mapper.mapping = make(map[int]net.TCPAddr)
  106. return nil
  107. }
  108. func (mapper *PortMapper) setup() error {
  109. if err := iptables("-t", "nat", "-N", "DOCKER"); err != nil {
  110. return errors.New("Unable to setup port networking: Failed to create DOCKER chain")
  111. }
  112. if err := iptables("-t", "nat", "-A", "PREROUTING", "-j", "DOCKER"); err != nil {
  113. return errors.New("Unable to setup port networking: Failed to inject docker in PREROUTING chain")
  114. }
  115. return nil
  116. }
  117. func (mapper *PortMapper) iptablesForward(rule string, port int, dest net.TCPAddr) error {
  118. return iptables("-t", "nat", rule, "DOCKER", "-p", "tcp", "--dport", strconv.Itoa(port),
  119. "-j", "DNAT", "--to-destination", net.JoinHostPort(dest.IP.String(), strconv.Itoa(dest.Port)))
  120. }
  121. func (mapper *PortMapper) Map(port int, dest net.TCPAddr) error {
  122. if err := mapper.iptablesForward("-A", port, dest); err != nil {
  123. return err
  124. }
  125. mapper.mapping[port] = dest
  126. return nil
  127. }
  128. func (mapper *PortMapper) Unmap(port int) error {
  129. dest, ok := mapper.mapping[port]
  130. if !ok {
  131. return errors.New("Port is not mapped")
  132. }
  133. if err := mapper.iptablesForward("-D", port, dest); err != nil {
  134. return err
  135. }
  136. delete(mapper.mapping, port)
  137. return nil
  138. }
  139. func newPortMapper() (*PortMapper, error) {
  140. mapper := &PortMapper{}
  141. if err := mapper.cleanup(); err != nil {
  142. return nil, err
  143. }
  144. if err := mapper.setup(); err != nil {
  145. return nil, err
  146. }
  147. return mapper, nil
  148. }
  149. // Port allocator: Atomatically allocate and release networking ports
  150. type PortAllocator struct {
  151. ports chan (int)
  152. }
  153. func (alloc *PortAllocator) populate(start, end int) {
  154. alloc.ports = make(chan int, end-start)
  155. for port := start; port < end; port++ {
  156. alloc.ports <- port
  157. }
  158. }
  159. func (alloc *PortAllocator) Acquire() (int, error) {
  160. select {
  161. case port := <-alloc.ports:
  162. return port, nil
  163. default:
  164. return -1, errors.New("No more ports available")
  165. }
  166. return -1, nil
  167. }
  168. func (alloc *PortAllocator) Release(port int) error {
  169. select {
  170. case alloc.ports <- port:
  171. return nil
  172. default:
  173. return errors.New("Too many ports have been released")
  174. }
  175. return nil
  176. }
  177. func newPortAllocator(start, end int) (*PortAllocator, error) {
  178. allocator := &PortAllocator{}
  179. allocator.populate(start, end)
  180. return allocator, nil
  181. }
  182. // IP allocator: Atomatically allocate and release networking ports
  183. type IPAllocator struct {
  184. network *net.IPNet
  185. queue chan (net.IP)
  186. }
  187. func (alloc *IPAllocator) populate() error {
  188. firstIP, _ := networkRange(alloc.network)
  189. size, err := networkSize(alloc.network.Mask)
  190. if err != nil {
  191. return err
  192. }
  193. // The queue size should be the network size - 3
  194. // -1 for the network address, -1 for the broadcast address and
  195. // -1 for the gateway address
  196. alloc.queue = make(chan net.IP, size-3)
  197. for i := int32(1); i < size-1; i++ {
  198. ipNum, err := ipToInt(firstIP)
  199. if err != nil {
  200. return err
  201. }
  202. ip, err := intToIp(ipNum + int32(i))
  203. if err != nil {
  204. return err
  205. }
  206. // Discard the network IP (that's the host IP address)
  207. if ip.Equal(alloc.network.IP) {
  208. continue
  209. }
  210. alloc.queue <- ip
  211. }
  212. return nil
  213. }
  214. func (alloc *IPAllocator) Acquire() (net.IP, error) {
  215. select {
  216. case ip := <-alloc.queue:
  217. return ip, nil
  218. default:
  219. return net.IP{}, errors.New("No more IP addresses available")
  220. }
  221. return net.IP{}, nil
  222. }
  223. func (alloc *IPAllocator) Release(ip net.IP) error {
  224. select {
  225. case alloc.queue <- ip:
  226. return nil
  227. default:
  228. return errors.New("Too many IP addresses have been released")
  229. }
  230. return nil
  231. }
  232. func newIPAllocator(network *net.IPNet) (*IPAllocator, error) {
  233. alloc := &IPAllocator{
  234. network: network,
  235. }
  236. if err := alloc.populate(); err != nil {
  237. return nil, err
  238. }
  239. return alloc, nil
  240. }
  241. // Network interface represents the networking stack of a container
  242. type NetworkInterface struct {
  243. IPNet net.IPNet
  244. Gateway net.IP
  245. manager *NetworkManager
  246. extPorts []int
  247. }
  248. // Allocate an external TCP port and map it to the interface
  249. func (iface *NetworkInterface) AllocatePort(port int) (int, error) {
  250. extPort, err := iface.manager.portAllocator.Acquire()
  251. if err != nil {
  252. return -1, err
  253. }
  254. if err := iface.manager.portMapper.Map(extPort, net.TCPAddr{iface.IPNet.IP, port}); err != nil {
  255. iface.manager.portAllocator.Release(extPort)
  256. return -1, err
  257. }
  258. iface.extPorts = append(iface.extPorts, extPort)
  259. return extPort, nil
  260. }
  261. // Release: Network cleanup - release all resources
  262. func (iface *NetworkInterface) Release() error {
  263. for _, port := range iface.extPorts {
  264. if err := iface.manager.portMapper.Unmap(port); err != nil {
  265. log.Printf("Unable to unmap port %v: %v", port, err)
  266. }
  267. if err := iface.manager.portAllocator.Release(port); err != nil {
  268. log.Printf("Unable to release port %v: %v", port, err)
  269. }
  270. }
  271. return iface.manager.ipAllocator.Release(iface.IPNet.IP)
  272. }
  273. // Network Manager manages a set of network interfaces
  274. // Only *one* manager per host machine should be used
  275. type NetworkManager struct {
  276. bridgeIface string
  277. bridgeNetwork *net.IPNet
  278. ipAllocator *IPAllocator
  279. portAllocator *PortAllocator
  280. portMapper *PortMapper
  281. }
  282. // Allocate a network interface
  283. func (manager *NetworkManager) Allocate() (*NetworkInterface, error) {
  284. ip, err := manager.ipAllocator.Acquire()
  285. if err != nil {
  286. return nil, err
  287. }
  288. iface := &NetworkInterface{
  289. IPNet: net.IPNet{ip, manager.bridgeNetwork.Mask},
  290. Gateway: manager.bridgeNetwork.IP,
  291. manager: manager,
  292. }
  293. return iface, nil
  294. }
  295. func newNetworkManager(bridgeIface string) (*NetworkManager, error) {
  296. addr, err := getIfaceAddr(bridgeIface)
  297. if err != nil {
  298. return nil, err
  299. }
  300. network := addr.(*net.IPNet)
  301. ipAllocator, err := newIPAllocator(network)
  302. if err != nil {
  303. return nil, err
  304. }
  305. portAllocator, err := newPortAllocator(portRangeStart, portRangeEnd)
  306. if err != nil {
  307. return nil, err
  308. }
  309. portMapper, err := newPortMapper()
  310. manager := &NetworkManager{
  311. bridgeIface: bridgeIface,
  312. bridgeNetwork: network,
  313. ipAllocator: ipAllocator,
  314. portAllocator: portAllocator,
  315. portMapper: portMapper,
  316. }
  317. return manager, nil
  318. }