Skip to content

Commit

Permalink
Merge pull request #7 from Cottand/multiple-rr
Browse files Browse the repository at this point in the history
remove dashboard, add test for multiple DNS records
  • Loading branch information
cottand authored Aug 25, 2023
2 parents 93f82bf + 9ca28d7 commit d32510d
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 55 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ jobs:
with:
go-version: 1.19

- name: Prepare Submodule
run: git submodule update --init

- name: Build
run: go build -v ./...

Expand Down
16 changes: 0 additions & 16 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package main

import (
"bufio"
"embed"
"io/fs"
"net"
"net/http"
"os"
Expand All @@ -15,9 +13,6 @@ import (
"gopkg.in/gin-contrib/cors.v1"
)

//go:embed dashboard/reaper
var dashboardAssets embed.FS

func isRunningInDockerContainer() bool {
// slightly modified from blog: https://paulbradley.org/indocker/
// docker creates a .dockerenv file at the root
Expand Down Expand Up @@ -58,17 +53,6 @@ func StartAPIServer(config *Config,

router.Use(cors.Default())

// Serves only if the user configuration enables the dashboard
if config.Dashboard {
router.GET("/", func(c *gin.Context) {
c.Redirect(http.StatusTemporaryRedirect, "/dashboard")
c.Abort()
})

dashboardAssets, _ := fs.Sub(dashboardAssets, "dashboard/reaper")
router.StaticFS("/dashboard", http.FS(dashboardAssets))
}

router.GET("/blockcache", func(c *gin.Context) {
special := make([]string, 0, len(blockCache.Special))
for k := range blockCache.Special {
Expand Down
4 changes: 0 additions & 4 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ type Config struct {
CustomDNSRecords []string
ToggleName string
ReactivationDelay uint
Dashboard bool
APIDebug bool
DoH string
UseDrbl int
Expand Down Expand Up @@ -81,9 +80,6 @@ logconfig = "file:grimd.log@2,stderr@2"
# apidebug enables the debug mode of the http api library
apidebug = false
# enable the web interface by default
dashboard = true
# address to bind to for the DNS server
bind = "0.0.0.0:53"
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
grimd:
image: ghcr.io/looterz/grimd:latest
image: ghcr.io/cottand/grimd:latest
ports:
- "53:53/udp"
- "53:53/tcp"
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/looterz/grimd
module github.com/cottand/grimd

require (
github.com/BurntSushi/toml v1.2.1
Expand Down
50 changes: 50 additions & 0 deletions grimd_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package main

import (
"github.com/BurntSushi/toml"
"testing"
"time"

"github.com/miekg/dns"
)
Expand All @@ -21,3 +23,51 @@ func BenchmarkResolver(b *testing.B) {
}
}
}

func TestMultipleARecords(t *testing.T) {
testDnsHost := "127.0.0.1:5300"
var config Config
_, err := toml.Decode(defaultConfig, &config)

config.CustomDNSRecords = []string{
"example.com. IN A 10.10.0.1 ",
"example.com. IN A 10.10.0.2 ",
}

quitActivation := make(chan bool)
actChannel := make(chan *ActivationHandler)

go startActivation(actChannel, quitActivation, config.ReactivationDelay)
grimdActivation = <-actChannel
close(actChannel)

server := &Server{
host: testDnsHost,
rTimeout: 5 * time.Second,
wTimeout: 5 * time.Second,
}
c := new(dns.Client)

// BlockCache contains all blocked domains
blockCache := &MemoryBlockCache{Backend: make(map[string]bool)}
// QuestionCache contains all queries to the dns server
questionCache := makeQuestionCache(config.QuestionCacheCap)

server.Run(&config, blockCache, questionCache)

time.Sleep(200 * time.Millisecond)
defer server.Stop()

m := new(dns.Msg)
m.SetQuestion(dns.Fqdn("example.com"), dns.TypeA)

reply, _, err := c.Exchange(m, testDnsHost)
if err != nil {
t.Error(err)
t.FailNow()
}

if l := len(reply.Answer); l != 2 {
t.Fatalf("Expected 2 returned records but had %v: %v", l, reply.Answer)
}
}
53 changes: 37 additions & 16 deletions records.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,49 @@ package main

import "github.com/miekg/dns"

type CustomDNSRecord struct {
handler *DNSHandler
answer dns.RR
func NewCustomDNSRecordsFromText(recordsText []string) []CustomDNSRecords {
customRecordsMap := make(map[string][]dns.RR)
for _, recordText := range recordsText {
answer, answerErr := dns.NewRR(recordText)
if answerErr != nil {
logger.Errorf("Cannot parse custom record: %s", answerErr)
}
name := answer.Header().Name
if len(name) > 0 {
if customRecordsMap[name] == nil {
customRecordsMap[name] = []dns.RR{}
}
customRecordsMap[name] = append(customRecordsMap[name], answer)
} else {
logger.Errorf("Cannot parse custom record (invalid name): '%s'", recordText)
}
}
return NewCustomDNSRecords(customRecordsMap)
}

func NewCustomDNSRecord(handler *DNSHandler, recordText string) (*CustomDNSRecord, error) {
answer, answerErr := dns.NewRR(recordText)
if answerErr != nil {
return nil, answerErr
func NewCustomDNSRecords(from map[string][]dns.RR) []CustomDNSRecords {
var records []CustomDNSRecords
for name, rrs := range from {
records = append(records, CustomDNSRecords{
name: name,
answer: rrs,
})
}
return records
}

return &CustomDNSRecord{
handler: handler,
answer: answer,
}, nil
type CustomDNSRecords struct {
name string
answer []dns.RR
}

func (c *CustomDNSRecord) serve(writer dns.ResponseWriter, req *dns.Msg) {
m := new(dns.Msg)
m.SetReply(req)
func (c *CustomDNSRecords) serve(server *DNSHandler) (handler func(dns.ResponseWriter, *dns.Msg)) {
return func(writer dns.ResponseWriter, req *dns.Msg) {
m := new(dns.Msg)
m.SetReply(req)

m.Answer = append(m.Answer, c.answer)
m.Answer = append(m.Answer, c.answer...)

c.handler.WriteReplyMsg(writer, m)
server.WriteReplyMsg(writer, m)
}
}
17 changes: 3 additions & 14 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,9 @@ func (s *Server) Run(config *Config,
udpHandler := dns.NewServeMux()
udpHandler.HandleFunc(".", s.handler.DoUDP)

for _, recordText := range config.CustomDNSRecords {
customRecord, customRecordErr := NewCustomDNSRecord(s.handler, recordText)
if customRecordErr == nil {
name := customRecord.answer.Header().Name

if len(name) > 0 {
tcpHandler.HandleFunc(name, customRecord.serve)
udpHandler.HandleFunc(name, customRecord.serve)
} else {
logger.Errorf("Cannot parse custom record: invalid dns")
}
} else {
logger.Errorf("Cannot parse custom record: %s", customRecordErr)
}
for _, record := range NewCustomDNSRecordsFromText(config.CustomDNSRecords) {
tcpHandler.HandleFunc(record.name, record.serve(s.handler))
udpHandler.HandleFunc(record.name, record.serve(s.handler))
}

s.tcpServer = &dns.Server{Addr: s.host,
Expand Down

0 comments on commit d32510d

Please sign in to comment.