aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cache/cache.go56
-rw-r--r--cache/cache_test.go30
-rw-r--r--dns/proxy.go12
-rw-r--r--http/http.go24
-rw-r--r--http/http_test.go4
5 files changed, 53 insertions, 73 deletions
diff --git a/cache/cache.go b/cache/cache.go
index 47db598..d168098 100644
--- a/cache/cache.go
+++ b/cache/cache.go
@@ -51,13 +51,37 @@ func (m *maintainer) run(cache *Cache) {
// Value represents a value stored in the cache.
type Value struct {
- Question string
- Qtype uint16
- Answers []string
CreatedAt time.Time
msg *dns.Msg
}
+// Rcode returns the response code of this cached value.
+func (v *Value) Rcode() int { return v.msg.Rcode }
+
+// Question returns the question of this cached value.
+func (v *Value) Question() string { return v.msg.Question[0].Name }
+
+// Qtype returns the DNS request type of this cached value.
+func (v *Value) Qtype() uint16 { return v.msg.Question[0].Qtype }
+
+// Answers returns the DNS responses of this cached value.
+func (v *Value) Answers() []string {
+ var answers []string
+ for _, answer := range v.msg.Answer {
+ switch v := answer.(type) {
+ case *dns.A:
+ answers = append(answers, v.A.String())
+ case *dns.AAAA:
+ answers = append(answers, v.AAAA.String())
+ case *dns.MX:
+ answers = append(answers, v.Mx)
+ case *dns.PTR:
+ answers = append(answers, v.Ptr)
+ }
+ }
+ return answers
+}
+
// TTL returns the TTL of this cache value.
func (v *Value) TTL() time.Duration { return minTTL(v.msg) }
@@ -147,35 +171,11 @@ func (c *Cache) Set(k uint32, msg *dns.Msg) {
delete(c.values, c.keys[0])
c.keys = c.keys[1:]
}
- c.values[k] = &Value{
- Question: question(msg),
- Answers: answers(msg),
- Qtype: qtype(msg),
- CreatedAt: now,
- msg: msg,
- }
+ c.values[k] = &Value{CreatedAt: now, msg: msg}
c.keys = append(c.keys, k)
c.mu.Unlock()
}
-func qtype(msg *dns.Msg) uint16 { return msg.Question[0].Qtype }
-
-func question(msg *dns.Msg) string { return msg.Question[0].Name }
-
-func answers(msg *dns.Msg) []string {
- var answers []string
- for _, answer := range msg.Answer {
- switch v := answer.(type) {
- case *dns.A:
- answers = append(answers, v.A.String())
- case *dns.AAAA:
- answers = append(answers, v.AAAA.String())
- case *dns.MX:
- answers = append(answers, v.Mx)
- }
- }
- return answers
-}
func (c *Cache) deleteExpired() {
c.mu.Lock()
for k, v := range c.values {
diff --git a/cache/cache_test.go b/cache/cache_test.go
index 71e5e58..9c13e66 100644
--- a/cache/cache_test.go
+++ b/cache/cache_test.go
@@ -92,30 +92,12 @@ func TestCache(t *testing.T) {
ok bool
value *Value
}{
- {msg, createdAt, createdAt, true, &Value{
- CreatedAt: createdAt,
- Question: "foo.",
- Qtype: 1,
- Answers: []string{"192.0.2.1", "192.0.2.2"},
- msg: msg},
- }, // Not expired when query time == create time
- {msg, createdAt, createdAt.Add(30 * time.Second), true, &Value{
- CreatedAt: createdAt,
- Question: "foo.",
- Qtype: 1,
- Answers: []string{"192.0.2.1", "192.0.2.2"},
- msg: msg},
- }, // Not expired when below TTL
- {msg, createdAt, createdAt.Add(60 * time.Second), true, &Value{
- CreatedAt: createdAt,
- Question: "foo.",
- Qtype: 1,
- Answers: []string{"192.0.2.1", "192.0.2.2"},
- msg: msg},
- }, //, Not expired until TTL exceeds
- {msg, createdAt, createdAt.Add(61 * time.Second), false, nil}, // Expired
- {msgWithZeroTTL, createdAt, createdAt, false, nil}, // 0 TTL is not cached
- {msgFailure, createdAt, createdAt, false, nil}, // Non-cacheable rcode
+ {msg, createdAt, createdAt, true, &Value{CreatedAt: createdAt, msg: msg}}, // Not expired when query time == create time
+ {msg, createdAt, createdAt.Add(30 * time.Second), true, &Value{CreatedAt: createdAt, msg: msg}}, // Not expired when below TTL
+ {msg, createdAt, createdAt.Add(60 * time.Second), true, &Value{CreatedAt: createdAt, msg: msg}}, //, Not expired until TTL exceeds
+ {msg, createdAt, createdAt.Add(61 * time.Second), false, nil}, // Expired
+ {msgWithZeroTTL, createdAt, createdAt, false, nil}, // 0 TTL is not cached
+ {msgFailure, createdAt, createdAt, false, nil}, // Non-cacheable rcode
}
for i, tt := range tests {
c.now = func() time.Time { return tt.createdAt }
diff --git a/dns/proxy.go b/dns/proxy.go
index a159b26..9553be3 100644
--- a/dns/proxy.go
+++ b/dns/proxy.go
@@ -14,8 +14,6 @@ const (
TypeA = dns.TypeA
// TypeAAAA represents the resource record type AAAA, an IPv6 address.
TypeAAAA = dns.TypeAAAA
- // TypeMX represents the resource record type MX, a mail exchange address.
- TypeMX = dns.TypeMX
// LogDiscard disables logging of DNS requests
LogDiscard = iota
// LogAll logs all DNS requests
@@ -24,6 +22,14 @@ const (
LogHijacked
)
+var (
+ // TypeToString contains a mapping of DNS request type to string.
+ TypeToString = dns.TypeToString
+
+ // RcodeToString contains a mapping of Mapping DNS return code to string.
+ RcodeToString = dns.RcodeToString
+)
+
// Request represents a simplified DNS request.
type Request struct {
Type uint16
@@ -149,6 +155,8 @@ func answers(msg *dns.Msg) []string {
answers = append(answers, v.AAAA.String())
case *dns.MX:
answers = append(answers, v.Mx)
+ case *dns.PTR:
+ answers = append(answers, v.Ptr)
}
}
return answers
diff --git a/http/http.go b/http/http.go
index 98ca90d..c2c6c5c 100644
--- a/http/http.go
+++ b/http/http.go
@@ -26,7 +26,8 @@ type entry struct {
RemoteAddr net.IP `json:"remote_addr,omitempty"`
Qtype string `json:"type"`
Question string `json:"question"`
- Answers []string `json:"answers"`
+ Answers []string `json:"answers,omitempty"`
+ Rcode string `json:"rcode,omitempty"`
}
type httpError struct {
@@ -99,26 +100,15 @@ func (s *Server) cacheHandler(w http.ResponseWriter, r *http.Request) (interface
entries = append(entries, entry{
Time: v.CreatedAt.UTC().Format(time.RFC3339),
TTL: int64(v.TTL().Truncate(time.Second).Seconds()),
- Qtype: qtype(v.Qtype),
- Question: v.Question,
- Answers: v.Answers,
+ Qtype: dns.TypeToString[v.Qtype()],
+ Question: v.Question(),
+ Answers: v.Answers(),
+ Rcode: dns.RcodeToString[v.Rcode()],
})
}
return entries, nil
}
-func qtype(qtype uint16) string {
- switch qtype {
- case dns.TypeA:
- return "A"
- case dns.TypeAAAA:
- return "AAAA"
- case dns.TypeMX:
- return "MX"
- }
- return ""
-}
-
func (s *Server) logHandler(w http.ResponseWriter, r *http.Request) (interface{}, *httpError) {
logEntries, err := s.logger.Get(100)
if err != nil {
@@ -132,7 +122,7 @@ func (s *Server) logHandler(w http.ResponseWriter, r *http.Request) (interface{}
entries = append(entries, entry{
Time: le.Time.UTC().Format(time.RFC3339),
RemoteAddr: le.RemoteAddr,
- Qtype: qtype(le.Qtype),
+ Qtype: dns.TypeToString[le.Qtype],
Question: le.Question,
Answers: le.Answers,
})
diff --git a/http/http_test.go b/http/http_test.go
index fc100aa..c98577b 100644
--- a/http/http_test.go
+++ b/http/http_test.go
@@ -61,8 +61,8 @@ func TestRequests(t *testing.T) {
srv.cache.Set(1, newA("1.example.com.", 60, net.IPv4(192, 0, 2, 200)))
srv.cache.Set(2, newA("2.example.com.", 30, net.IPv4(192, 0, 2, 201)))
- var cacheResponse = "[{\"time\":\"RFC3339\",\"ttl\":30,\"type\":\"A\",\"question\":\"2.example.com.\",\"answers\":[\"192.0.2.201\"]}," +
- "{\"time\":\"RFC3339\",\"ttl\":60,\"type\":\"A\",\"question\":\"1.example.com.\",\"answers\":[\"192.0.2.200\"]}]"
+ var cacheResponse = "[{\"time\":\"RFC3339\",\"ttl\":30,\"type\":\"A\",\"question\":\"2.example.com.\",\"answers\":[\"192.0.2.201\"],\"rcode\":\"NOERROR\"}," +
+ "{\"time\":\"RFC3339\",\"ttl\":60,\"type\":\"A\",\"question\":\"1.example.com.\",\"answers\":[\"192.0.2.200\"],\"rcode\":\"NOERROR\"}]"
var logResponse = "[{\"time\":\"RFC3339\",\"remote_addr\":\"127.0.0.254\",\"type\":\"AAAA\",\"question\":\"example.com.\",\"answers\":[\"2001:db8::1\"]}," +
"{\"time\":\"RFC3339\",\"remote_addr\":\"127.0.0.42\",\"type\":\"A\",\"question\":\"example.com.\",\"answers\":[\"192.0.2.101\",\"192.0.2.100\"]}]"