Skip to content

Commit

Permalink
Finalized DOH responder
Browse files Browse the repository at this point in the history
  • Loading branch information
shadrick committed Jun 12, 2018
1 parent 1dd4b8a commit 75e61ca
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 15 deletions.
30 changes: 25 additions & 5 deletions responder/recursive_dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"log"
"math/rand"
Expand Down Expand Up @@ -1907,12 +1908,18 @@ func handleDNSMessage(loggy *logrus.Entry, provider, network string, rt *runtime
}

if qname == "" || qtype == 0 {
w.Write([]byte("Arg error"))
w.WriteHeader(400)
return
}
if _, e := prepareAnswer(newDNSQuery(qname, qtype), &netpackage.TCPAddr{IP: netpackage.ParseIP(r.RemoteAddr)}); e != nil {
w.Write([]byte("servfault"))
if ret, e := prepareAnswer(newDNSQuery(qname, qtype), &netpackage.TCPAddr{IP: netpackage.ParseIP(r.RemoteAddr)}); e != nil {
w.WriteHeader(500)
return
} else {
w.Write([]byte("success"))
if jsonRet, err := json.Marshal(JSONFromMsg(ret)); err != nil {
w.WriteHeader(503)
} else {
w.Write(jsonRet)
}
}
return
}
Expand Down Expand Up @@ -1961,7 +1968,20 @@ func ServeDNS(cfg runtime.RecursorConfig, rt *runtime.Runtime, v4 bool, net stri
Handler: mux,
}

restDNS.ListenAndServeTLS(d.CertFile, d.KeyFile)
defer rt.OnFinishedOrPanic(func() {
restDNS.Close()
lg.Infof("Stopped %s dns resolver on %s", net, addr)
rt.SlackWH.SendMessage("shutting down.", operator)
}, pchan)
defer func() {
if rcv := recover(); rcv != nil {
snd := &StackAddedPanic{debug.Stack(), rcv}
fmt.Printf("Panic in ListenAndServeTLS [%s]\n", snd)
pchan <- snd
}
}()

go restDNS.ListenAndServeTLS(d.CertFile, d.KeyFile)
return
}

Expand Down
48 changes: 48 additions & 0 deletions responder/recursive_dns_helpers.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,58 @@
package responder

import (
"strings"

"github.com/miekg/dns"
"github.com/tenta-browser/tenta-dns/runtime"
)

type JSONQuestion struct {
Name string
RRtype uint16 `json:"Type"`
}

type JSONRR struct {
*JSONQuestion
TTL uint32
Data string
}

type JSONResponse struct {
Status int
TC, RD, RA, AD, CD bool
Question []*JSONQuestion
Answer, Authority, Additional []*JSONRR `json:",omitempty"`
}

func JSONFromMsg(in *dns.Msg) *JSONResponse {
resp := &JSONResponse{Status: in.Rcode, TC: in.Truncated, RD: in.RecursionDesired, RA: in.RecursionAvailable, AD: in.AuthenticatedData, CD: in.CheckingDisabled,
Question: []*JSONQuestion{&JSONQuestion{Name: in.Question[0].Name, RRtype: in.Question[0].Qtype}}}

if in.Answer != nil {
resp.Answer = []*JSONRR{}
for _, ans := range in.Answer {
resp.Answer = append(resp.Answer, &JSONRR{&JSONQuestion{ans.Header().Name, ans.Header().Rrtype}, ans.Header().Ttl, strings.TrimLeft(ans.String(), ans.Header().String())})
}
}

if in.Ns != nil {
resp.Authority = []*JSONRR{}
for _, ans := range in.Ns {
resp.Authority = append(resp.Authority, &JSONRR{&JSONQuestion{ans.Header().Name, ans.Header().Rrtype}, ans.Header().Ttl, strings.TrimLeft(ans.String(), ans.Header().String())})
}
}
cleanExtra := cleanAdditionalSection(in.Extra)
if len(cleanExtra) != 0 {
resp.Additional = []*JSONRR{}
for _, ans := range cleanExtra {
resp.Additional = append(resp.Additional, &JSONRR{&JSONQuestion{ans.Header().Name, ans.Header().Rrtype}, ans.Header().Ttl, strings.TrimLeft(ans.String(), ans.Header().String())})
}
}

return resp
}

// Politely decline to answer ANY queries
func refuseAny(w dns.ResponseWriter, r *dns.Msg, rt *runtime.Runtime) {
rt.Stats.Tick("resolver", "refuse-any")
Expand Down
14 changes: 7 additions & 7 deletions responder/recursive_dns_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ const (
)

const (
NETWORK_UDP = "udp"
NETWORK_TCP = "tcp"
NETWORK_TLS = "tcp-tls"
NETWORK_UDP = "udp"
NETWORK_TCP = "tcp"
NETWORK_TLS = "tcp-tls"
NETWORK_HTTPS = "https"
)

const (
Expand Down Expand Up @@ -535,9 +536,10 @@ func doQueryRecursively(rrt *ResolverRuntime, _level int) (*dns.Msg, error) {
if qtype == dns.TypeDS {
currentToken = rrt.domain
}
} else if !isFinalQuestion && isBottomLevel(rrt, _level+1) { /// aka, the next one would be final
qtype = rrt.record
}
// else if !isFinalQuestion && isBottomLevel(rrt, _level+1) { /// aka, the next one would be final
// qtype = rrt.record
// }
LogInfo(rrt, "CurrentZone [%s], CurrentToken [%s], isFinal [%v]", currentZone, currentToken, isFinalQuestion)
cachedRR, extra := rrt.c.Retrieve(rrt.provider, currentToken, qtype, doWeReturnDNSSEC(rrt))
if r, e, p := handleExtras(rrt, cachedRR, extra); p {
Expand Down Expand Up @@ -595,10 +597,8 @@ func doQueryRecursively(rrt *ResolverRuntime, _level int) (*dns.Msg, error) {
return setupResult(rrt, dns.RcodeServerFailure, nil), fmt.Errorf("bogus DNSSEC response")
}
}

/// TODO: add record security check
cacheResponse(rrt, res, answerType)

if answerType != RESPONSE_NODATA && answerType != RESPONSE_NXDOMAIN &&
answerType != RESPONSE_EDNS_ALLERGY && answerType != RESPONSE_THROTTLE_SUSPECT {
rrt.currentZone = currentToken
Expand Down
7 changes: 4 additions & 3 deletions tenta-dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ package main
import (
"flag"
"fmt"
"github.com/tenta-browser/tenta-dns/director"
"github.com/tenta-browser/tenta-dns/log"
"github.com/tenta-browser/tenta-dns/runtime"
"os"
"os/signal"
"syscall"

"github.com/tenta-browser/tenta-dns/director"
"github.com/tenta-browser/tenta-dns/log"
"github.com/tenta-browser/tenta-dns/runtime"

"github.com/coreos/go-systemd/daemon"
"github.com/sirupsen/logrus"
)
Expand Down

0 comments on commit 75e61ca

Please sign in to comment.