diff --git a/config/config.go b/config/config.go index f56288d..e13a46e 100644 --- a/config/config.go +++ b/config/config.go @@ -1,18 +1,38 @@ package config type Configuration struct { + DNS DNSConfiguration + HTTP HTTPConfiguration +} + +type DNSConfiguration struct { Port uint16 Host string Domains []string } +type HTTPConfiguration struct { + Port uint16 + Host string + Socket string + SocketFileMode uint32 +} + var ( Config Configuration defaultConfig = Configuration{ - Port: 5353, - Host: "0.0.0.0", - Domains: []string{}, + DNS: DNSConfiguration{ + Port: 5353, + Host: "0.0.0.0", + Domains: []string{}, + }, + HTTP: HTTPConfiguration{ + Port: 8080, + Host: "127.0.0.1", + Socket: "", + SocketFileMode: 0644, + }, } ) diff --git a/dns/dns.go b/dns/dns.go index edc0d37..53b6398 100644 --- a/dns/dns.go +++ b/dns/dns.go @@ -1,6 +1,7 @@ package dns import ( + "errors" "fmt" "log" "strconv" @@ -11,11 +12,11 @@ import ( ) type domain struct { - root string - mutv4 sync.RWMutex - mutv6 sync.RWMutex - ipv4 map[string]string - ipv6 map[string]string + Root string + Mutv4 sync.RWMutex + Mutv6 sync.RWMutex + Ipv4 map[string]string + Ipv6 map[string]string } var domains = []*domain{} @@ -25,9 +26,9 @@ func parseQuery(m *dns.Msg, currentDomain *domain) { switch q.Qtype { case dns.TypeA: log.Printf("Query for A record of %s\n", q.Name) - currentDomain.mutv4.RLock() - ip := currentDomain.ipv4[q.Name] - currentDomain.mutv4.RUnlock() + currentDomain.Mutv4.RLock() + ip := currentDomain.Ipv4[q.Name] + currentDomain.Mutv4.RUnlock() if ip != "" { rr, err := dns.NewRR(fmt.Sprintf("%s A %s", q.Name, ip)) if err == nil { @@ -36,9 +37,9 @@ func parseQuery(m *dns.Msg, currentDomain *domain) { } case dns.TypeAAAA: log.Printf("Query for AAAA record of %s\n", q.Name) - currentDomain.mutv6.RLock() - ip := currentDomain.ipv6[q.Name] - currentDomain.mutv6.RUnlock() + currentDomain.Mutv6.RLock() + ip := currentDomain.Ipv6[q.Name] + currentDomain.Mutv6.RUnlock() if ip != "" { rr, err := dns.NewRR(fmt.Sprintf("%s AAAA %s", q.Name, ip)) if err == nil { @@ -64,10 +65,13 @@ func handleDnsRequest(currentDomain *domain) func(w dns.ResponseWriter, r *dns.M } } -func Load() { - for _, currentDomain := range config.Config.Domains { +func Init() { + for _, currentDomain := range config.Config.DNS.Domains { + log.Printf("Added domain root: %s\n", currentDomain) domains = append(domains, &domain{ - root: currentDomain, + Root: currentDomain, + Ipv4: make(map[string]string), + Ipv6: make(map[string]string), }) } } @@ -75,12 +79,12 @@ func Load() { func Run() (*dns.Server, error) { // attach request handler func for _, currentDomain := range domains { - dns.HandleFunc(currentDomain.root, handleDnsRequest(currentDomain)) + dns.HandleFunc(currentDomain.Root, handleDnsRequest(currentDomain)) } // start server - server := &dns.Server{Addr: ":" + strconv.Itoa(int(config.Config.Port)), Net: "udp"} - log.Printf("Starting DNS at %d\n", config.Config.Port) + server := &dns.Server{Addr: ":" + strconv.Itoa(int(config.Config.DNS.Port)), Net: "udp"} + log.Printf("Starting DNS at %d\n", config.Config.DNS.Port) err := server.ListenAndServe() if err != nil { server.Shutdown() @@ -90,24 +94,34 @@ func Run() (*dns.Server, error) { return server, nil } -func UpdateIpv6(domain string, ipv6 string) { +func UpdateIpv6(domain string, ipv6 string) error { for _, currentDomain := range domains { - if dns.IsSubDomain(currentDomain.root, domain) { - currentDomain.mutv6.Lock() - currentDomain.ipv6[domain] = ipv6 - currentDomain.mutv6.Unlock() - break + if dns.IsSubDomain(currentDomain.Root, domain) { + log.Printf("Updating domain %s AAAA %s\n", domain, ipv6) + currentDomain.Mutv6.Lock() + currentDomain.Ipv6[domain] = ipv6 + currentDomain.Mutv6.Unlock() + return nil } } + + return errors.New("no root found") } -func UpdateIpv4(domain string, ipv4 string) { +func UpdateIpv4(domain string, ipv4 string) (err error) { for _, currentDomain := range domains { - if dns.IsSubDomain(currentDomain.root, domain) { - currentDomain.mutv4.Lock() - currentDomain.ipv4[domain] = ipv4 - currentDomain.mutv4.Unlock() - break + if dns.IsSubDomain(currentDomain.Root, domain) { + log.Printf("Updating domain %s A %s\n", domain, ipv4) + currentDomain.Mutv4.Lock() + currentDomain.Ipv4[domain] = ipv4 + currentDomain.Mutv4.Unlock() + return nil } } + + return errors.New("no root found") +} + +func Get() []*domain { + return domains } diff --git a/go.mod b/go.mod index 19240ad..eee31e5 100644 --- a/go.mod +++ b/go.mod @@ -2,12 +2,20 @@ module github.com/MarekWojt/gertdns go 1.17 -require github.com/miekg/dns v1.1.43 +require ( + github.com/fasthttp/router v1.4.4 + github.com/gookit/color v1.4.2 + github.com/miekg/dns v1.1.43 + github.com/pelletier/go-toml/v2 v2.0.0-beta.3 + github.com/valyala/fasthttp v1.31.0 +) require ( - github.com/gookit/color v1.4.2 // indirect - github.com/pelletier/go-toml/v2 v2.0.0-beta.3 // indirect + github.com/andybalholm/brotli v1.0.2 // indirect + github.com/klauspost/compress v1.13.4 // indirect + github.com/savsgio/gotils v0.0.0-20210921075833-21a6215cb0e4 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect - golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect + golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 // indirect ) diff --git a/go.sum b/go.sum index 2198bbe..7f9388a 100644 --- a/go.sum +++ b/go.sum @@ -1,28 +1,51 @@ +github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fasthttp/router v1.4.4 h1:Z025tHFTjDp6T6QMBjloyGL6KV5wtakW365K/7KiE1c= +github.com/fasthttp/router v1.4.4/go.mod h1:TiyF2kc+mogKcTxqkhUbiXpwklouv5dN58A0ZUo8J6s= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gookit/color v1.4.2 h1:tXy44JFSFkKnELV6WaMo/lLfu/meqITX3iAV52do7lk= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= +github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s= +github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/pelletier/go-toml/v2 v2.0.0-beta.3 h1:PNCTU4naEJ8mKal97P3A2qDU74QRQGlv4FXiL1XDqi4= github.com/pelletier/go-toml/v2 v2.0.0-beta.3/go.mod h1:aNseLYu/uKskg0zpr/kbr2z8yGuWtotWf/0BpGIAL2Y= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/savsgio/gotils v0.0.0-20210921075833-21a6215cb0e4 h1:ocK/D6lCgLji37Z2so4xhMl46se1ntReQQCUIU4BWI8= +github.com/savsgio/gotils v0.0.0-20210921075833-21a6215cb0e4/go.mod h1:oejLrk1Y/5zOF+c/aHtXqn3TFlzzbAgPWg8zBiAHDas= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 h1:t0lM6y/M5IiUZyvbBTcngso8SZEZICH7is9B6g/obVU= github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.31.0 h1:lrauRLII19afgCs2fnWRJ4M5IkV0lo2FqA61uGkNBfE= +github.com/valyala/fasthttp v1.31.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 h1:cEhElsAv9LUt9ZUUocxzWe05oFLVd+AA2nstydTeI8g= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 h1:KzbpndAYEM+4oHRp9JmB2ewj0NHHxO3Z0g7Gus2O1kk= golang.org/x/sys v0.0.0-20211015200801-69063c4bb744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index a9685dc..0432d2a 100644 --- a/main.go +++ b/main.go @@ -6,12 +6,19 @@ import ( "github.com/MarekWojt/gertdns/config" "github.com/MarekWojt/gertdns/dns" + "github.com/MarekWojt/gertdns/web" + rootDns "github.com/miekg/dns" ) var ( configFile = flag.String("configFile", "conf.toml", "Path to configuration file") ) +type dnsResult struct { + server *rootDns.Server + err error +} + func main() { flag.Parse() @@ -20,10 +27,43 @@ func main() { log.Fatalf("Failed to load configuration: %s\n ", err.Error()) } - dns.Load() - server, err := dns.Run() - if err != nil { - log.Fatalf("Failed to start DNS server: %s\n ", err.Error()) - } - defer server.Shutdown() + dns.Init() + web.Init() + + webChan := make(chan error) + dnsChan := make(chan dnsResult) + go func() { + server, err := dns.Run() + if err != nil { + log.Fatalf("Failed to start DNS server: %s\n ", err.Error()) + } + + dnsChan <- dnsResult{ + server: server, + err: err, + } + }() + + go func() { + err := web.RunSocket() + if err != nil { + log.Fatalf("Failed to start HTTP socket: %s\n ", err.Error()) + } + + webChan <- err + }() + + go func() { + err := web.RunHTTP() + if err != nil { + log.Fatalf("Failed to start HTTP server: %s\n ", err.Error()) + } + + webChan <- err + }() + + currentDnsResult := <-dnsChan + defer currentDnsResult.server.Shutdown() + <-webChan + <-webChan } diff --git a/web/web.go b/web/web.go index efb3895..8687fa5 100644 --- a/web/web.go +++ b/web/web.go @@ -1 +1,165 @@ package web + +import ( + "flag" + "fmt" + "io/fs" + "log" + + "github.com/MarekWojt/gertdns/auth" + "github.com/MarekWojt/gertdns/config" + "github.com/MarekWojt/gertdns/dns" + "github.com/fasthttp/router" + "github.com/valyala/fasthttp" +) + +var enableDebugMode *bool = flag.Bool("enable-debug-mode", false, "Enables debug mode, will output a list of ") + +func index(ctx *fasthttp.RequestCtx) { + if !*enableDebugMode { + ctx.WriteString("Working") + } else { + domains := dns.Get() + ctx.SetContentType("text/html") + ctx.WriteString("
| Type | Domain | IP | Root domain |
|---|---|---|---|
| A | %s | %s | %s |
| AAAA | %s | %s | %s |