chore: Very very rough impl
This commit is contained in:
parent
bae72607bf
commit
f888bd220f
10 changed files with 319 additions and 0 deletions
91
cmd/cli.go
Normal file
91
cmd/cli.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/mr-karan/doggo/pkg/resolver"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
// Version and date of the build. This is injected at build-time.
|
||||
buildVersion = "unknown"
|
||||
buildDate = "unknown"
|
||||
)
|
||||
|
||||
// initLogger initializes logger
|
||||
func initLogger(verbose bool) *logrus.Logger {
|
||||
logger := logrus.New()
|
||||
logger.SetFormatter(&logrus.TextFormatter{
|
||||
FullTimestamp: true,
|
||||
})
|
||||
// Set logger level
|
||||
if verbose {
|
||||
logger.SetLevel(logrus.DebugLevel)
|
||||
logger.Debug("verbose logging enabled")
|
||||
} else {
|
||||
logger.SetLevel(logrus.InfoLevel)
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Intialize new CLI app
|
||||
app := cli.NewApp()
|
||||
app.Name = "doggo"
|
||||
app.Usage = "Command-line DNS Client"
|
||||
app.Version = buildVersion
|
||||
app.Author = "Karan Sharma @mrkaran"
|
||||
// Register command line args.
|
||||
app.Flags = []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "verbose",
|
||||
Usage: "Enable verbose logging",
|
||||
},
|
||||
}
|
||||
var (
|
||||
logger = initLogger(true)
|
||||
)
|
||||
// Initialize hub.
|
||||
hub := NewHub(logger, buildVersion)
|
||||
|
||||
app.Action = func(c *cli.Context) error {
|
||||
// parse arguments
|
||||
for _, arg := range c.Args() {
|
||||
if strings.HasPrefix(arg, "@") {
|
||||
hub.Nameservers = append(hub.Nameservers, arg)
|
||||
} else if isUpper(arg) {
|
||||
if parseQueryType(arg) {
|
||||
hub.QTypes = append(hub.QTypes, arg)
|
||||
} else if parseQueryClass(arg) {
|
||||
hub.QClass = append(hub.QClass, arg)
|
||||
}
|
||||
} else {
|
||||
hub.Domains = append(hub.Domains, arg)
|
||||
}
|
||||
}
|
||||
// load defaults
|
||||
if len(hub.QTypes) == 0 {
|
||||
hub.QTypes = append(hub.QTypes, "A")
|
||||
}
|
||||
if len(hub.Nameservers) == 0 {
|
||||
ns, err := resolver.GetDefaultNameserver()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
hub.Nameservers = append(hub.Nameservers, ns)
|
||||
}
|
||||
// resolve query
|
||||
hub.Resolve()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run the app.
|
||||
hub.Logger.Info("Starting doggo...")
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
logger.Errorf("Something terrbily went wrong: %s", err)
|
||||
}
|
||||
}
|
33
cmd/hub.go
Normal file
33
cmd/hub.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Hub represents the structure for all app wide functions and structs.
|
||||
type Hub struct {
|
||||
Logger *logrus.Logger
|
||||
Version string
|
||||
Domains []string
|
||||
QTypes []string
|
||||
QClass []string
|
||||
Nameservers []string
|
||||
}
|
||||
|
||||
// NewHub initializes an instance of Hub which holds app wide configuration.
|
||||
func NewHub(logger *logrus.Logger, buildVersion string) *Hub {
|
||||
hub := &Hub{
|
||||
Logger: logger,
|
||||
Version: buildVersion,
|
||||
}
|
||||
return hub
|
||||
}
|
||||
|
||||
// initApp acts like a middleware to load app managers with Hub before running any command.
|
||||
// Use this middleware to perform any action before the command is run.
|
||||
func (hub *Hub) initApp(fn cli.ActionFunc) cli.ActionFunc {
|
||||
return func(c *cli.Context) error {
|
||||
return fn(c)
|
||||
}
|
||||
}
|
32
cmd/resolve.go
Normal file
32
cmd/resolve.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// Resolve resolves the domain name
|
||||
func (hub *Hub) Resolve() {
|
||||
var messages = make([]dns.Msg, 0, len(hub.Domains))
|
||||
for _, d := range hub.Domains {
|
||||
msg := dns.Msg{}
|
||||
msg.Id = dns.Id()
|
||||
msg.RecursionDesired = true
|
||||
msg.Question = []dns.Question{(dns.Question{d, dns.TypeA, dns.ClassINET})}
|
||||
messages = append(messages, msg)
|
||||
}
|
||||
c := new(dns.Client)
|
||||
for _, msg := range messages {
|
||||
in, rtt, err := c.Exchange(&msg, "127.0.0.1:53")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, ans := range in.Answer {
|
||||
if t, ok := ans.(*dns.A); ok {
|
||||
fmt.Println(t.String())
|
||||
}
|
||||
}
|
||||
fmt.Println("rtt is", rtt, msg.Question)
|
||||
}
|
||||
}
|
35
cmd/utils.go
Normal file
35
cmd/utils.go
Normal file
|
@ -0,0 +1,35 @@
|
|||
package main
|
||||
|
||||
import "unicode"
|
||||
|
||||
var (
|
||||
QTYPES = []string{"A", "AAAA", "MX"}
|
||||
QCLASS = []string{"CN", "AAAA", "MX"}
|
||||
)
|
||||
|
||||
func isUpper(s string) bool {
|
||||
for _, r := range s {
|
||||
if !unicode.IsUpper(r) && unicode.IsLetter(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func parseQueryType(s string) bool {
|
||||
for _, b := range QTYPES {
|
||||
if b == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func parseQueryClass(s string) bool {
|
||||
for _, b := range QCLASS {
|
||||
if b == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue