package main import ( "flag" "fmt" "net" "os" "os/signal" "strings" "syscall" "github.com/gologme/log" "github.com/zhoreeq/meshname/pkg/meshname" ) func parseNetworks(networksconf string) (map[string]*net.IPNet, error) { networks := make(map[string]*net.IPNet) for _, item := range strings.Split(networksconf, ",") { if tokens := strings.SplitN(item, "=", 2); len(tokens) == 2 { if _, validSubnet, err := net.ParseCIDR(tokens[1]); err == nil { networks[tokens[0]] = validSubnet } else { return nil, err } } } return networks, nil } func loadConfig(s *meshname.MeshnameServer, confPath string) error { dnsRecords, err := meshname.ParseConfigFile(confPath) if err == nil { s.ConfigureDNSRecords(dnsRecords) } return err } var ( genconf, subdomain, useconffile, listenAddr, networksconf string getName, getIP string debug, noMeshIP, allowRemote bool ) func init() { flag.StringVar(&genconf, "genconf", "", "generate a new config for IP address") flag.StringVar(&subdomain, "subdomain", "meshname.", "subdomain used to generate config") flag.StringVar(&useconffile, "useconffile", "", "run daemon with a config file") flag.StringVar(&listenAddr, "listenaddr", "[::1]:53535", "address to listen on") flag.StringVar(&networksconf, "networks", "ygg=200::/7,cjd=fc00::/8,meshname=::/0,vapordns=::/0", "TLD=subnet list separated by comma") flag.BoolVar(&noMeshIP, "nomeship", false, "disable .meship resolver") flag.StringVar(&getName, "getname", "", "convert IPv6 address to a name") flag.StringVar(&getIP, "getip", "", "convert a name to IPv6 address") flag.BoolVar(&allowRemote, "allowremote", false, "allow remote queries from any IP address") flag.BoolVar(&debug, "debug", false, "enable debug logging") } func main() { flag.Parse() logger := log.New(os.Stdout, "", log.Flags()) logger.EnableLevel("error") logger.EnableLevel("warn") logger.EnableLevel("info") if debug { logger.EnableLevel("debug") } if getName != "" { ip := net.ParseIP(getName) if ip == nil { logger.Fatal("Invalid IP address") } subDomain := meshname.DomainFromIP(&ip) fmt.Println(subDomain) return } else if getIP != "" { ip, err := meshname.IPFromDomain(&getIP) if err != nil { logger.Fatal(err) } fmt.Println(ip) return } else if genconf != "" { if conf, err := meshname.GenConf(genconf, subdomain); err == nil { fmt.Println(conf) } else { logger.Errorln(err) } return } networks, err := parseNetworks(networksconf) if err != nil { logger.Fatalln(err) } s := meshname.New(logger, listenAddr, networks, !noMeshIP, allowRemote) if useconffile != "" { if err := loadConfig(s, useconffile); err != nil { logger.Fatalln(err) } } if err := s.Start(); err != nil { logger.Fatal(err) } logger.Infoln("Listening on:", listenAddr) c := make(chan os.Signal, 1) r := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) signal.Notify(r, os.Interrupt, syscall.SIGHUP) defer s.Stop() for { select { case <-c: return case <-r: if useconffile != "" { if err := loadConfig(s, useconffile); err != nil { logger.Errorln(err) } } } } }