func main() { // glog will log to tmp files by default. override so all entries // can flow into journald (if running under systemd) flag.Set("logtostderr", "true") // now parse command line args flag.Parse() if opts.help { fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]...\n", os.Args[0]) flag.PrintDefaults() os.Exit(0) } if opts.version { fmt.Fprintln(os.Stderr, Version) os.Exit(0) } iface, tep := lookupIface() if iface == nil || tep == nil { return } log.Infof("Using %s to tunnel", tep) sm := makeSubnetManager() udp.Run(sm, iface, tep, opts.port, opts.ipMasq, func(sn ip.IP4Net, mtu int) { writeSubnet(sn, mtu) daemon.SdNotify("READY=1") }) }
func (sm *SubnetManager) allocateSubnet() (ip.IP4Net, error) { log.Infof("Picking subnet in range %s ... %s", sm.config.SubnetMin, sm.config.SubnetMax) var bag []ip.IP4 sn := ip.IP4Net{IP: sm.config.SubnetMin, PrefixLen: sm.config.SubnetLen} OuterLoop: for ; sn.IP <= sm.config.SubnetMax && len(bag) < 100; sn = sn.Next() { for _, l := range sm.leases { if sn.Overlaps(l.Network) { continue OuterLoop } } bag = append(bag, sn.IP) } if len(bag) == 0 { return ip.IP4Net{}, errors.New("out of subnets") } else { i := randInt(0, len(bag)) return ip.IP4Net{IP: bag[i], PrefixLen: sm.config.SubnetLen}, nil } }