basic stdin reader on loop to reuse connections

This commit is contained in:
2025-03-01 16:45:15 +00:00
parent f5fa15b701
commit a2fb149e7a

View File

@@ -1,7 +1,10 @@
package main package main
import ( import (
"bufio"
"log" "log"
"os"
"strings"
"github.com/afonsofrancof/sdns-perf/internal/protocols/do53" "github.com/afonsofrancof/sdns-perf/internal/protocols/do53"
"github.com/afonsofrancof/sdns-perf/internal/protocols/doh" "github.com/afonsofrancof/sdns-perf/internal/protocols/doh"
@@ -36,6 +39,10 @@ type Do53Cmd struct {
CommonFlags CommonFlags
} }
type Listen struct {
}
var cli struct { var cli struct {
Verbose bool `help:"Enable verbose logging" short:"v"` Verbose bool `help:"Enable verbose logging" short:"v"`
@@ -43,6 +50,7 @@ var cli struct {
DoT DoTCmd `cmd:"dot" help:"Query using DNS-over-TLS" name:"dot"` DoT DoTCmd `cmd:"dot" help:"Query using DNS-over-TLS" name:"dot"`
DoQ DoQCmd `cmd:"doq" help:"Query using DNS-over-QUIC" name:"doq"` DoQ DoQCmd `cmd:"doq" help:"Query using DNS-over-QUIC" name:"doq"`
Do53 Do53Cmd `cmd:"doq" help:"Query using plain DNS over UDP" name:"do53"` Do53 Do53Cmd `cmd:"doq" help:"Query using plain DNS over UDP" name:"do53"`
Listen Listen `cmd:"listen"`
} }
func (c *Do53Cmd) Run() error { func (c *Do53Cmd) Run() error {
@@ -50,6 +58,7 @@ func (c *Do53Cmd) Run() error {
if err != nil { if err != nil {
return err return err
} }
defer do53client.Close()
return do53client.Query(c.DomainName, c.QueryType, c.Server, c.DNSSEC) return do53client.Query(c.DomainName, c.QueryType, c.Server, c.DNSSEC)
} }
@@ -58,6 +67,7 @@ func (c *DoHCmd) Run() error {
if err != nil { if err != nil {
return err return err
} }
defer dohclient.Close()
return dohclient.Query(c.DomainName, c.QueryType, c.DNSSEC) return dohclient.Query(c.DomainName, c.QueryType, c.DNSSEC)
} }
@@ -66,6 +76,7 @@ func (c *DoTCmd) Run() error {
if err != nil { if err != nil {
return err return err
} }
defer dotclient.Close()
return dotclient.Query(c.DomainName, c.QueryType, c.Server, c.DNSSEC) return dotclient.Query(c.DomainName, c.QueryType, c.Server, c.DNSSEC)
} }
@@ -74,9 +85,172 @@ func (c *DoQCmd) Run() error {
if err != nil { if err != nil {
return err return err
} }
defer doqclient.Close()
return doqclient.Query(c.DomainName, c.QueryType, c.DNSSEC) return doqclient.Query(c.DomainName, c.QueryType, c.DNSSEC)
} }
func (l *Listen) Run() error {
// Maps to store clients for reuse
do53Clients := make(map[string]*do53.Do53Client)
dotClients := make(map[string]*dot.DoTClient)
doqClients := make(map[string]*doq.DoQClient)
dohClients := make(map[string]*doh.DoHClient) // Using server+path+proxy as key
scanner := bufio.NewScanner(os.Stdin)
log.Println("Listening for input. Format: protocol domain server [options]")
for scanner.Scan() {
line := scanner.Text()
fields := strings.Fields(line)
if len(fields) < 3 {
log.Printf("Invalid input: %s. Format should be 'protocol domain server [options]'", line)
continue
}
protocol := fields[0]
domain := fields[1]
server := fields[2]
// Default query type and DNSSEC setting
queryType := "A"
dnssec := false
switch protocol {
case "do53":
// Parse additional options
if len(fields) > 3 {
queryType = fields[3]
}
if len(fields) > 4 && fields[4] == "dnssec" {
dnssec = true
}
// Check if client exists, if not create it
client, exists := do53Clients[server]
if !exists {
var err error
client, err = do53.New(server)
if err != nil {
log.Printf("Error creating Do53 client: %v", err)
continue
}
do53Clients[server] = client
}
err := client.Query(domain, queryType, server, dnssec)
if err != nil {
log.Printf("Error querying with Do53: %v", err)
}
case "dot":
// Parse additional options
if len(fields) > 3 {
queryType = fields[3]
}
if len(fields) > 4 && fields[4] == "dnssec" {
dnssec = true
}
client, exists := dotClients[server]
if !exists {
var err error
client, err = dot.New(server)
if err != nil {
log.Printf("Error creating DoT client: %v", err)
continue
}
dotClients[server] = client
}
err := client.Query(domain, queryType, server, dnssec)
if err != nil {
log.Printf("Error querying with DoT: %v", err)
}
case "doq":
// Parse additional options
if len(fields) > 3 {
queryType = fields[3]
}
if len(fields) > 4 && fields[4] == "dnssec" {
dnssec = true
}
client, exists := doqClients[server]
if !exists {
var err error
client, err = doq.New(server)
if err != nil {
log.Printf("Error creating DoQ client: %v", err)
continue
}
doqClients[server] = client
}
err := client.Query(domain, queryType, dnssec)
if err != nil {
log.Printf("Error querying with DoQ: %v", err)
}
case "doh":
// DoH requires path parameter
if len(fields) < 4 {
log.Printf("DoH requires a path parameter")
continue
}
path := fields[3]
proxy := ""
// Parse additional options
if len(fields) > 4 {
queryType = fields[4]
}
if len(fields) > 5 {
if fields[5] == "dnssec" {
dnssec = true
} else {
proxy = fields[5]
}
}
if len(fields) > 6 && fields[6] == "dnssec" {
dnssec = true
}
// Create a composite key for DoH clients
key := server + ":" + path + ":" + proxy
client, exists := dohClients[key]
if !exists {
var err error
client, err = doh.New(server, path, proxy)
if err != nil {
log.Printf("Error creating DoH client: %v", err)
continue
}
dohClients[key] = client
}
err := client.Query(domain, queryType, dnssec)
if err != nil {
log.Printf("Error querying with DoH: %v", err)
}
default:
log.Printf("Unknown protocol: %s", protocol)
}
}
if err := scanner.Err(); err != nil {
return err
}
return nil
}
func main() { func main() {
ctx := kong.Parse(&cli, ctx := kong.Parse(&cli,
kong.Name("dns-go"), kong.Name("dns-go"),