Instead of allocating all possible IPs in advance, generate them as
needed.
A loop will cycle through all possible IPs in sequential order,
allocating them as needed and marking them as in use. Once the loop
exhausts all IPs, it will wrap back to the beginning. IPs that are
already in use will be skipped. When an IP is released, it will be
cleared and be available for allocation again.
Two decisions went into this design:
1) Minimize memory footprint by only allocating IPs that are actually
in use
2) Minimize reuse of released IP addresses to avoid sending traffic to
the wrong containers
As a side effect, the functions for IP/Mask<->int conversion have been
rewritten to never be able to fail in order to reduce the amount of
error returns.
Fixes gh-231
Current Go tip (+74e65f07a0c8) and likely Go 1.1 does not build docker since net.TCPAddr struct has an additional field now for IPv6:
type TCPAddr struct {
IP IP
Port int
Zone string // IPv6 scoped addressing zone
}
Initializing the struct with named fields resolves this problem.