From 40b9c4eb99e4730e3e6523c5b8bf3f913d584ea3 Mon Sep 17 00:00:00 2001 From: Zach Date: Sat, 1 Sep 2018 22:11:57 -0400 Subject: [PATCH] Make registry generic and split query and registry functions --- server.go | 4 +- whois/query.go | 107 +++---------------------------------------- whois/registry.go | 112 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 103 deletions(-) create mode 100644 whois/registry.go diff --git a/server.go b/server.go index 5421720..724943f 100644 --- a/server.go +++ b/server.go @@ -13,7 +13,7 @@ import ( "syscall" "time" - "github.com/Mic92/whois42d/whois" + "github.com/zgiles/whois42d/whois" ) type Server struct { @@ -25,7 +25,7 @@ type Server struct { } func New(dataPath string) *Server { - registry := whois.Registry{dataPath} + registry := whois.New(dataPath, "This is the dn42 whois query service.", "dn42", "DN42") return &Server{registry, time.Now(), false, 0, sync.WaitGroup{}} } diff --git a/whois/query.go b/whois/query.go index 3a783b3..855c00a 100644 --- a/whois/query.go +++ b/whois/query.go @@ -2,63 +2,17 @@ package whois import ( "bufio" - "bytes" "flag" "fmt" - "io/ioutil" "net" "os" "path" - "regexp" - "sort" "strings" ) -type Registry struct { - DataPath string -} - -type Type struct { - Name string - Pattern *regexp.Regexp - Kind int -} - -type Object map[int]interface{} - -const ( - UPPER = iota - LOWER - ROUTE - ROUTE6 -) - -type Query struct { - Objects []Object - Flags *Flags -} - -var whoisTypes = []Type{ - {"aut-num", regexp.MustCompile(`^AS([0123456789]+)$`), UPPER}, - {"dns", regexp.MustCompile(`.dn42$`), LOWER}, - {"person", regexp.MustCompile(`-DN42$`), UPPER}, - {"mntner", regexp.MustCompile(`-MNT$`), UPPER}, - {"schema", regexp.MustCompile(`-SCHEMA$`), UPPER}, - {"organisation", regexp.MustCompile(`ORG-`), UPPER}, - {"tinc-keyset", regexp.MustCompile(`^SET-.+-TINC$`), UPPER}, - {"tinc-key", regexp.MustCompile(`-TINC$`), UPPER}, - {"as-set", regexp.MustCompile(`^AS`), UPPER}, - {"route-set", regexp.MustCompile(`^RS-`), UPPER}, - {"inetnum", nil, ROUTE}, - {"inet6num", nil, ROUTE6}, - {"route", nil, ROUTE}, - {"route6", nil, ROUTE6}, - {"as-block", regexp.MustCompile(`\d+_\d+`), UPPER}, -} - func (r *Registry) handleObject(conn *net.TCPConn, object Object, flags *Flags) bool { found := false - for _, t := range whoisTypes { + for _, t := range r.whoisTypes { if len(flags.Types) > 0 && !flags.Types[t.Name] { continue } @@ -79,7 +33,7 @@ func (r *Registry) handleObject(conn *net.TCPConn, object Object, flags *Flags) } func (r *Registry) HandleQuery(conn *net.TCPConn) { - fmt.Fprint(conn, "% This is the dn42 whois query service.\n\n") + fmt.Fprint(conn, "% " + r.Header + "\n\n") query := parseQuery(conn) if query == nil { @@ -88,7 +42,7 @@ func (r *Registry) HandleQuery(conn *net.TCPConn) { flags := query.Flags if flags.ServerInfo != "" { - printServerInfo(conn, strings.TrimSpace(flags.ServerInfo)) + r.printServerInfo(conn, strings.TrimSpace(flags.ServerInfo)) return } found := false @@ -104,55 +58,6 @@ func (r *Registry) HandleQuery(conn *net.TCPConn) { fmt.Fprint(conn, "\n") } -func readCidrs(path string) ([]net.IPNet, error) { - files, err := ioutil.ReadDir(path) - if err != nil { - return nil, err - } - cidrs := []net.IPNet{} - for _, f := range files { - name := strings.Replace(f.Name(), "_", "/", -1) - _, cidr, err := net.ParseCIDR(name) - if err != nil { - fmt.Fprintf(os.Stderr, "skip invalid net '%s'", f.Name()) - continue - } - i := sort.Search(len(cidrs), func(i int) bool { - c := cidrs[i] - return bytes.Compare(c.Mask, cidr.Mask) >= 0 - }) - - if i < len(cidrs) { - cidrs = append(cidrs[:i], append([]net.IPNet{*cidr}, cidrs[i:]...)...) - } else { - cidrs = append(cidrs, *cidr) - } - } - - return cidrs, nil -} - -func parseObject(arg string) Object { - obj := path.Base(arg) - object := Object{ - UPPER: strings.ToUpper(obj), - LOWER: strings.ToLower(obj), - } - - ip := net.ParseIP(obj) - if ip == nil { - ip, _, _ = net.ParseCIDR(arg) - } - if ip != nil { - if ip.To4() == nil { - object[ROUTE6] = ip - } else { - object[ROUTE] = ip.To4() - } - } - return object -} - func parseQuery(conn *net.TCPConn) *Query { r := bufio.NewReader(conn) req, e := r.ReadString('\n') @@ -180,14 +85,14 @@ func parseQuery(conn *net.TCPConn) *Query { return &query } -func printServerInfo(conn *net.TCPConn, what string) { +func (r *Registry) printServerInfo(conn *net.TCPConn, what string) { switch what { case "version": fmt.Fprintf(conn, "%% whois42d v%d\n", VERSION) case "sources": - fmt.Fprintf(conn, "DN42:3:N:0-0\n") + fmt.Fprintf(conn, r.RegistryTopLevel+":3:N:0-0\n") case "types": - for _, t := range whoisTypes { + for _, t := range r.whoisTypes { fmt.Fprintf(conn, "%s\n", t.Name) } default: diff --git a/whois/registry.go b/whois/registry.go new file mode 100644 index 0000000..be2cb0f --- /dev/null +++ b/whois/registry.go @@ -0,0 +1,112 @@ +package whois + +import ( + "bytes" + "fmt" + "io/ioutil" + "net" + "os" + "path" + "regexp" + "sort" + "strings" +) + +type Registry struct { + DataPath string + Header string + DNSTopLevel string + RegistryTopLevel string + whoisTypes []Type +} + +type Type struct { + Name string + Pattern *regexp.Regexp + Kind int +} + +type Object map[int]interface{} + +const ( + UPPER = iota + LOWER + ROUTE + ROUTE6 +) + +type Query struct { + Objects []Object + Flags *Flags +} + +func New(DataPath string, Header string, DNSTopLevel string, RegistryTopLevel string) Registry { + r := Registry{DataPath: DataPath, Header: Header, DNSTopLevel: DNSTopLevel, RegistryTopLevel: RegistryTopLevel} + r.whoisTypes = []Type{ + {"aut-num", regexp.MustCompile(`^AS([0123456789]+)$`), UPPER}, + {"dns", regexp.MustCompile(`.` + r.DNSTopLevel + `$`), LOWER}, + {"person", regexp.MustCompile(`-` + r.RegistryTopLevel + `$`), UPPER}, + {"mntner", regexp.MustCompile(`-MNT$`), UPPER}, + {"schema", regexp.MustCompile(`-SCHEMA$`), UPPER}, + {"organisation", regexp.MustCompile(`ORG-`), UPPER}, + {"tinc-keyset", regexp.MustCompile(`^SET-.+-TINC$`), UPPER}, + {"tinc-key", regexp.MustCompile(`-TINC$`), UPPER}, + {"as-set", regexp.MustCompile(`^AS`), UPPER}, + {"route-set", regexp.MustCompile(`^RS-`), UPPER}, + {"inetnum", nil, ROUTE}, + {"inet6num", nil, ROUTE6}, + {"route", nil, ROUTE}, + {"route6", nil, ROUTE6}, + {"as-block", regexp.MustCompile(`\d+_\d+`), UPPER}, + } + return r +} + +func readCidrs(path string) ([]net.IPNet, error) { + files, err := ioutil.ReadDir(path) + if err != nil { + return nil, err + } + cidrs := []net.IPNet{} + for _, f := range files { + name := strings.Replace(f.Name(), "_", "/", -1) + _, cidr, err := net.ParseCIDR(name) + if err != nil { + fmt.Fprintf(os.Stderr, "skip invalid net '%s'", f.Name()) + continue + } + i := sort.Search(len(cidrs), func(i int) bool { + c := cidrs[i] + return bytes.Compare(c.Mask, cidr.Mask) >= 0 + }) + + if i < len(cidrs) { + cidrs = append(cidrs[:i], append([]net.IPNet{*cidr}, cidrs[i:]...)...) + } else { + cidrs = append(cidrs, *cidr) + } + } + + return cidrs, nil +} + +func parseObject(arg string) Object { + obj := path.Base(arg) + object := Object{ + UPPER: strings.ToUpper(obj), + LOWER: strings.ToLower(obj), + } + + ip := net.ParseIP(obj) + if ip == nil { + ip, _, _ = net.ParseCIDR(arg) + } + if ip != nil { + if ip.To4() == nil { + object[ROUTE6] = ip + } else { + object[ROUTE] = ip.To4() + } + } + return object +}