aboutsummaryrefslogtreecommitdiff
path: root/middleware/dnstap
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/dnstap')
-rw-r--r--middleware/dnstap/README.md61
-rw-r--r--middleware/dnstap/handler.go79
-rw-r--r--middleware/dnstap/handler_test.go65
-rw-r--r--middleware/dnstap/msg/msg.go168
-rw-r--r--middleware/dnstap/msg/msg_test.go42
-rw-r--r--middleware/dnstap/msg/wrapper.go26
-rw-r--r--middleware/dnstap/out/socket.go86
-rw-r--r--middleware/dnstap/out/socket_test.go94
-rw-r--r--middleware/dnstap/out/tcp.go59
-rw-r--r--middleware/dnstap/out/tcp_test.go66
-rw-r--r--middleware/dnstap/setup.go98
-rw-r--r--middleware/dnstap/setup_test.go34
-rw-r--r--middleware/dnstap/taprw/writer.go73
-rw-r--r--middleware/dnstap/taprw/writer_test.go82
-rw-r--r--middleware/dnstap/test/helpers.go80
15 files changed, 0 insertions, 1113 deletions
diff --git a/middleware/dnstap/README.md b/middleware/dnstap/README.md
deleted file mode 100644
index d91c9422c..000000000
--- a/middleware/dnstap/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# dnstap
-
-*dnstap* enables logging to dnstap, a flexible, structured binary log format for DNS software: http://dnstap.info.
-
-There is a buffer, expect at least 13 requests before the server sends its dnstap messages to the socket.
-
-## Syntax
-
-~~~ txt
-dnstap SOCKET [full]
-~~~
-
-* **SOCKET** is the socket path supplied to the dnstap command line tool.
-* `full` to include the wire-format DNS message.
-
-## Examples
-
-Log information about client requests and responses to */tmp/dnstap.sock*.
-
-~~~ txt
-dnstap /tmp/dnstap.sock
-~~~
-
-Log information including the wire-format DNS message about client requests and responses to */tmp/dnstap.sock*.
-
-~~~ txt
-dnstap unix:///tmp/dnstap.sock full
-~~~
-
-Log to a remote endpoint.
-
-~~~ txt
-dnstap tcp://127.0.0.1:6000 full
-~~~
-
-## Dnstap command line tool
-
-~~~ sh
-go get github.com/dnstap/golang-dnstap
-cd $GOPATH/src/github.com/dnstap/golang-dnstap/dnstap
-go build
-./dnstap
-~~~
-
-The following command listens on the given socket and decodes messages to stdout.
-
-~~~ sh
-dnstap -u /tmp/dnstap.sock
-~~~
-
-The following command listens on the given socket and saves message payloads to a binary dnstap-format log file.
-
-~~~ sh
-dnstap -u /tmp/dnstap.sock -w /tmp/test.dnstap
-~~~
-
-Listen for dnstap messages on port 6000.
-
-~~~ sh
-dnstap -l 127.0.0.1:6000
-~~~
diff --git a/middleware/dnstap/handler.go b/middleware/dnstap/handler.go
deleted file mode 100644
index eb2924be5..000000000
--- a/middleware/dnstap/handler.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package dnstap
-
-import (
- "fmt"
- "io"
-
- "github.com/coredns/coredns/middleware"
- "github.com/coredns/coredns/middleware/dnstap/msg"
- "github.com/coredns/coredns/middleware/dnstap/taprw"
-
- tap "github.com/dnstap/golang-dnstap"
- "github.com/miekg/dns"
- "golang.org/x/net/context"
-)
-
-// Dnstap is the dnstap handler.
-type Dnstap struct {
- Next middleware.Handler
- Out io.Writer
- Pack bool
-}
-
-type (
- // Tapper is implemented by the Context passed by the dnstap handler.
- Tapper interface {
- TapMessage(*tap.Message) error
- TapBuilder() msg.Builder
- }
- tapContext struct {
- context.Context
- Dnstap
- }
-)
-
-// TapperFromContext will return a Tapper if the dnstap middleware is enabled.
-func TapperFromContext(ctx context.Context) (t Tapper) {
- t, _ = ctx.(Tapper)
- return
-}
-
-func tapMessageTo(w io.Writer, m *tap.Message) error {
- frame, err := msg.Marshal(m)
- if err != nil {
- return fmt.Errorf("marshal: %s", err)
- }
- _, err = w.Write(frame)
- return err
-}
-
-// TapMessage implements Tapper.
-func (h Dnstap) TapMessage(m *tap.Message) error {
- return tapMessageTo(h.Out, m)
-}
-
-// TapBuilder implements Tapper.
-func (h Dnstap) TapBuilder() msg.Builder {
- return msg.Builder{Full: h.Pack}
-}
-
-// ServeDNS logs the client query and response to dnstap and passes the dnstap Context.
-func (h Dnstap) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
- rw := &taprw.ResponseWriter{ResponseWriter: w, Tapper: &h, Query: r}
- rw.QueryEpoch()
-
- code, err := middleware.NextOrFailure(h.Name(), h.Next, tapContext{ctx, h}, rw, r)
- if err != nil {
- // ignore dnstap errors
- return code, err
- }
-
- if err := rw.DnstapError(); err != nil {
- return code, middleware.Error("dnstap", err)
- }
-
- return code, nil
-}
-
-// Name returns dnstap.
-func (h Dnstap) Name() string { return "dnstap" }
diff --git a/middleware/dnstap/handler_test.go b/middleware/dnstap/handler_test.go
deleted file mode 100644
index dfdde582d..000000000
--- a/middleware/dnstap/handler_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package dnstap
-
-import (
- "errors"
- "fmt"
- "testing"
-
- "github.com/coredns/coredns/middleware/dnstap/test"
- mwtest "github.com/coredns/coredns/middleware/test"
-
- tap "github.com/dnstap/golang-dnstap"
- "github.com/golang/protobuf/proto"
- "github.com/miekg/dns"
- "golang.org/x/net/context"
-)
-
-func testCase(t *testing.T, tapq, tapr *tap.Message, q, r *dns.Msg) {
- w := writer{}
- w.queue = append(w.queue, tapq, tapr)
- h := Dnstap{
- Next: mwtest.HandlerFunc(func(_ context.Context,
- w dns.ResponseWriter, _ *dns.Msg) (int, error) {
-
- return 0, w.WriteMsg(r)
- }),
- Out: &w,
- Pack: false,
- }
- _, err := h.ServeDNS(context.TODO(), &mwtest.ResponseWriter{}, q)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-type writer struct {
- queue []*tap.Message
-}
-
-func (w *writer) Write(b []byte) (int, error) {
- e := tap.Dnstap{}
- if err := proto.Unmarshal(b, &e); err != nil {
- return 0, err
- }
- if len(w.queue) == 0 {
- return 0, errors.New("message not expected")
- }
- if !test.MsgEqual(w.queue[0], e.Message) {
- return 0, fmt.Errorf("want: %v, have: %v", w.queue[0], e.Message)
- }
- w.queue = w.queue[1:]
- return len(b), nil
-}
-
-func TestDnstap(t *testing.T) {
- q := mwtest.Case{Qname: "example.org", Qtype: dns.TypeA}.Msg()
- r := mwtest.Case{
- Qname: "example.org.", Qtype: dns.TypeA,
- Answer: []dns.RR{
- mwtest.A("example.org. 3600 IN A 10.0.0.1"),
- },
- }.Msg()
- tapq := test.TestingData().ToClientQuery()
- tapr := test.TestingData().ToClientResponse()
- testCase(t, tapq, tapr, q, r)
-}
diff --git a/middleware/dnstap/msg/msg.go b/middleware/dnstap/msg/msg.go
deleted file mode 100644
index 0e2cd5d40..000000000
--- a/middleware/dnstap/msg/msg.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// Package msg helps to build a dnstap Message.
-package msg
-
-import (
- "errors"
- "net"
- "strconv"
- "time"
-
- tap "github.com/dnstap/golang-dnstap"
- "github.com/miekg/dns"
-)
-
-// Builder helps to build Data by being aware of the dnstap middleware configuration.
-type Builder struct {
- Full bool
- Data
-}
-
-// AddrMsg parses the info of net.Addr and dns.Msg.
-func (b *Builder) AddrMsg(a net.Addr, m *dns.Msg) (err error) {
- err = b.RemoteAddr(a)
- if err != nil {
- return
- }
- return b.Msg(m)
-}
-
-// Msg parses the info of dns.Msg.
-func (b *Builder) Msg(m *dns.Msg) (err error) {
- if b.Full {
- err = b.Pack(m)
- }
- return
-}
-
-// Data helps to build a dnstap Message.
-// It can be transformed into the actual Message using this package.
-type Data struct {
- Packed []byte
- SocketProto tap.SocketProtocol
- SocketFam tap.SocketFamily
- Address []byte
- Port uint32
- TimeSec uint64
-}
-
-// HostPort decodes into Data any string returned by dnsutil.ParseHostPortOrFile.
-func (d *Data) HostPort(addr string) error {
- ip, port, err := net.SplitHostPort(addr)
- if err != nil {
- return err
- }
- p, err := strconv.ParseUint(port, 10, 32)
- if err != nil {
- return err
- }
- d.Port = uint32(p)
-
- if ip := net.ParseIP(ip); ip != nil {
- d.Address = []byte(ip)
- if ip := ip.To4(); ip != nil {
- d.SocketFam = tap.SocketFamily_INET
- } else {
- d.SocketFam = tap.SocketFamily_INET6
- }
- return nil
- }
- return errors.New("not an ip address")
-}
-
-// RemoteAddr parses the information about the remote address into Data.
-func (d *Data) RemoteAddr(remote net.Addr) error {
- switch addr := remote.(type) {
- case *net.TCPAddr:
- d.Address = addr.IP
- d.Port = uint32(addr.Port)
- d.SocketProto = tap.SocketProtocol_TCP
- case *net.UDPAddr:
- d.Address = addr.IP
- d.Port = uint32(addr.Port)
- d.SocketProto = tap.SocketProtocol_UDP
- default:
- return errors.New("unknown remote address type")
- }
-
- if a := net.IP(d.Address); a.To4() != nil {
- d.SocketFam = tap.SocketFamily_INET
- } else {
- d.SocketFam = tap.SocketFamily_INET6
- }
-
- return nil
-}
-
-// Pack encodes the DNS message into Data.
-func (d *Data) Pack(m *dns.Msg) error {
- packed, err := m.Pack()
- if err != nil {
- return err
- }
- d.Packed = packed
- return nil
-}
-
-// Epoch returns the epoch time in seconds.
-func Epoch() uint64 {
- return uint64(time.Now().Unix())
-}
-
-// Epoch sets the dnstap message epoch.
-func (d *Data) Epoch() {
- d.TimeSec = Epoch()
-}
-
-// ToClientResponse transforms Data into a client response message.
-func (d *Data) ToClientResponse() *tap.Message {
- t := tap.Message_CLIENT_RESPONSE
- return &tap.Message{
- Type: &t,
- SocketFamily: &d.SocketFam,
- SocketProtocol: &d.SocketProto,
- ResponseTimeSec: &d.TimeSec,
- ResponseMessage: d.Packed,
- QueryAddress: d.Address,
- QueryPort: &d.Port,
- }
-}
-
-// ToClientQuery transforms Data into a client query message.
-func (d *Data) ToClientQuery() *tap.Message {
- t := tap.Message_CLIENT_QUERY
- return &tap.Message{
- Type: &t,
- SocketFamily: &d.SocketFam,
- SocketProtocol: &d.SocketProto,
- QueryTimeSec: &d.TimeSec,
- QueryMessage: d.Packed,
- QueryAddress: d.Address,
- QueryPort: &d.Port,
- }
-}
-
-// ToOutsideQuery transforms the data into a forwarder or resolver query message.
-func (d *Data) ToOutsideQuery(t tap.Message_Type) *tap.Message {
- return &tap.Message{
- Type: &t,
- SocketFamily: &d.SocketFam,
- SocketProtocol: &d.SocketProto,
- QueryTimeSec: &d.TimeSec,
- QueryMessage: d.Packed,
- ResponseAddress: d.Address,
- ResponsePort: &d.Port,
- }
-}
-
-// ToOutsideResponse transforms the data into a forwarder or resolver response message.
-func (d *Data) ToOutsideResponse(t tap.Message_Type) *tap.Message {
- return &tap.Message{
- Type: &t,
- SocketFamily: &d.SocketFam,
- SocketProtocol: &d.SocketProto,
- ResponseTimeSec: &d.TimeSec,
- ResponseMessage: d.Packed,
- ResponseAddress: d.Address,
- ResponsePort: &d.Port,
- }
-}
diff --git a/middleware/dnstap/msg/msg_test.go b/middleware/dnstap/msg/msg_test.go
deleted file mode 100644
index 2f80a90cd..000000000
--- a/middleware/dnstap/msg/msg_test.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package msg
-
-import (
- "net"
- "reflect"
- "testing"
-
- "github.com/coredns/coredns/middleware/test"
- "github.com/coredns/coredns/request"
-
- tap "github.com/dnstap/golang-dnstap"
- "github.com/miekg/dns"
-)
-
-func testRequest(t *testing.T, expected Data, r request.Request) {
- d := Data{}
- if err := d.RemoteAddr(r.W.RemoteAddr()); err != nil {
- t.Fail()
- return
- }
- if d.SocketProto != expected.SocketProto ||
- d.SocketFam != expected.SocketFam ||
- !reflect.DeepEqual(d.Address, expected.Address) ||
- d.Port != expected.Port {
- t.Fatalf("expected: %v, have: %v", expected, d)
- return
- }
-}
-func TestRequest(t *testing.T) {
- testRequest(t, Data{
- SocketProto: tap.SocketProtocol_UDP,
- SocketFam: tap.SocketFamily_INET,
- Address: net.ParseIP("10.240.0.1"),
- Port: 40212,
- }, testingRequest())
-}
-func testingRequest() request.Request {
- m := new(dns.Msg)
- m.SetQuestion("example.com.", dns.TypeA)
- m.SetEdns0(4097, true)
- return request.Request{W: &test.ResponseWriter{}, Req: m}
-}
diff --git a/middleware/dnstap/msg/wrapper.go b/middleware/dnstap/msg/wrapper.go
deleted file mode 100644
index a74c604d8..000000000
--- a/middleware/dnstap/msg/wrapper.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package msg
-
-import (
- "fmt"
-
- lib "github.com/dnstap/golang-dnstap"
- "github.com/golang/protobuf/proto"
-)
-
-func wrap(m *lib.Message) *lib.Dnstap {
- t := lib.Dnstap_MESSAGE
- return &lib.Dnstap{
- Type: &t,
- Message: m,
- }
-}
-
-// Marshal encodes the message to a binary dnstap payload.
-func Marshal(m *lib.Message) (data []byte, err error) {
- data, err = proto.Marshal(wrap(m))
- if err != nil {
- err = fmt.Errorf("proto: %s", err)
- return
- }
- return
-}
diff --git a/middleware/dnstap/out/socket.go b/middleware/dnstap/out/socket.go
deleted file mode 100644
index 520dcf1d8..000000000
--- a/middleware/dnstap/out/socket.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package out
-
-import (
- "fmt"
- "net"
-
- fs "github.com/farsightsec/golang-framestream"
-)
-
-// Socket is a Frame Streams encoder over a UNIX socket.
-type Socket struct {
- path string
- enc *fs.Encoder
- conn net.Conn
- err error
-}
-
-func openSocket(s *Socket) error {
- conn, err := net.Dial("unix", s.path)
- if err != nil {
- return err
- }
- s.conn = conn
-
- enc, err := fs.NewEncoder(conn, &fs.EncoderOptions{
- ContentType: []byte("protobuf:dnstap.Dnstap"),
- Bidirectional: true,
- })
- if err != nil {
- return err
- }
- s.enc = enc
-
- s.err = nil
- return nil
-}
-
-// NewSocket will always return a new Socket.
-// err if nothing is listening to it, it will attempt to reconnect on the next Write.
-func NewSocket(path string) (s *Socket, err error) {
- s = &Socket{path: path}
- if err = openSocket(s); err != nil {
- err = fmt.Errorf("open socket: %s", err)
- s.err = err
- return
- }
- return
-}
-
-// Write a single Frame Streams frame.
-func (s *Socket) Write(frame []byte) (int, error) {
- if s.err != nil {
- // is the dnstap tool listening?
- if err := openSocket(s); err != nil {
- return 0, fmt.Errorf("open socket: %s", err)
- }
- }
- n, err := s.enc.Write(frame)
- if err != nil {
- // the dnstap command line tool is down
- s.conn.Close()
- s.err = err
- return 0, err
- }
- return n, nil
-
-}
-
-// Close the socket and flush the remaining frames.
-func (s *Socket) Close() error {
- if s.err != nil {
- // nothing to close
- return nil
- }
-
- defer s.conn.Close()
-
- if err := s.enc.Flush(); err != nil {
- return fmt.Errorf("flush: %s", err)
- }
- if err := s.enc.Close(); err != nil {
- return err
- }
-
- return nil
-}
diff --git a/middleware/dnstap/out/socket_test.go b/middleware/dnstap/out/socket_test.go
deleted file mode 100644
index 050a38d36..000000000
--- a/middleware/dnstap/out/socket_test.go
+++ /dev/null
@@ -1,94 +0,0 @@
-package out
-
-import (
- "net"
- "testing"
-
- fs "github.com/farsightsec/golang-framestream"
-)
-
-func acceptOne(t *testing.T, l net.Listener) {
- server, err := l.Accept()
- if err != nil {
- t.Fatalf("server accept: %s", err)
- return
- }
-
- dec, err := fs.NewDecoder(server, &fs.DecoderOptions{
- ContentType: []byte("protobuf:dnstap.Dnstap"),
- Bidirectional: true,
- })
- if err != nil {
- t.Fatalf("server decoder: %s", err)
- return
- }
-
- if _, err := dec.Decode(); err != nil {
- t.Errorf("server decode: %s", err)
- }
-
- if err := server.Close(); err != nil {
- t.Error(err)
- }
-}
-func sendOne(socket *Socket) error {
- if _, err := socket.Write([]byte("frame")); err != nil {
- return err
- }
- if err := socket.enc.Flush(); err != nil {
- // Would happen during Write in real life.
- socket.conn.Close()
- socket.err = err
- return err
- }
- return nil
-}
-func TestSocket(t *testing.T) {
- socket, err := NewSocket("dnstap.sock")
- if err == nil {
- t.Fatal("new socket: not listening but no error")
- return
- }
-
- if err := sendOne(socket); err == nil {
- t.Fatal("not listening but no error")
- return
- }
-
- l, err := net.Listen("unix", "dnstap.sock")
- if err != nil {
- t.Fatal(err)
- return
- }
-
- wait := make(chan bool)
- go func() {
- acceptOne(t, l)
- wait <- true
- }()
-
- if err := sendOne(socket); err != nil {
- t.Fatalf("send one: %s", err)
- return
- }
-
- <-wait
- if err := sendOne(socket); err == nil {
- panic("must fail")
- }
-
- go func() {
- acceptOne(t, l)
- wait <- true
- }()
-
- if err := sendOne(socket); err != nil {
- t.Fatalf("send one: %s", err)
- return
- }
-
- <-wait
- if err := l.Close(); err != nil {
- t.Error(err)
- }
-}
diff --git a/middleware/dnstap/out/tcp.go b/middleware/dnstap/out/tcp.go
deleted file mode 100644
index 8d2c25270..000000000
--- a/middleware/dnstap/out/tcp.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package out
-
-import (
- "net"
- "time"
-
- fs "github.com/farsightsec/golang-framestream"
-)
-
-// TCP is a Frame Streams encoder over TCP.
-type TCP struct {
- address string
- frames [][]byte
-}
-
-// NewTCP returns a TCP writer.
-func NewTCP(address string) *TCP {
- s := &TCP{address: address}
- s.frames = make([][]byte, 0, 13) // 13 messages buffer
- return s
-}
-
-// Write a single Frame Streams frame.
-func (s *TCP) Write(frame []byte) (n int, err error) {
- s.frames = append(s.frames, frame)
- if len(s.frames) == cap(s.frames) {
- return len(frame), s.Flush()
- }
- return len(frame), nil
-}
-
-// Flush the remaining frames.
-func (s *TCP) Flush() error {
- defer func() {
- s.frames = s.frames[0:]
- }()
- c, err := net.DialTimeout("tcp", s.address, time.Second)
- if err != nil {
- return err
- }
- enc, err := fs.NewEncoder(c, &fs.EncoderOptions{
- ContentType: []byte("protobuf:dnstap.Dnstap"),
- Bidirectional: true,
- })
- if err != nil {
- return err
- }
- for _, frame := range s.frames {
- if _, err = enc.Write(frame); err != nil {
- return err
- }
- }
- return enc.Flush()
-}
-
-// Close is an alias to Flush to satisfy io.WriteCloser similarly to type Socket.
-func (s *TCP) Close() error {
- return s.Flush()
-}
diff --git a/middleware/dnstap/out/tcp_test.go b/middleware/dnstap/out/tcp_test.go
deleted file mode 100644
index 113603cd4..000000000
--- a/middleware/dnstap/out/tcp_test.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package out
-
-import (
- "net"
- "testing"
-)
-
-func sendOneTCP(tcp *TCP) error {
- if _, err := tcp.Write([]byte("frame")); err != nil {
- return err
- }
- if err := tcp.Flush(); err != nil {
- return err
- }
- return nil
-}
-func TestTCP(t *testing.T) {
- tcp := NewTCP("localhost:14000")
-
- if err := sendOneTCP(tcp); err == nil {
- t.Fatal("Not listening but no error.")
- return
- }
-
- l, err := net.Listen("tcp", "localhost:14000")
- if err != nil {
- t.Fatal(err)
- return
- }
-
- wait := make(chan bool)
- go func() {
- acceptOne(t, l)
- wait <- true
- }()
-
- if err := sendOneTCP(tcp); err != nil {
- t.Fatalf("send one: %s", err)
- return
- }
-
- <-wait
-
- // TODO: When the server isn't responding according to the framestream protocol
- // the thread is blocked.
- /*
- if err := sendOneTCP(tcp); err == nil {
- panic("must fail")
- }
- */
-
- go func() {
- acceptOne(t, l)
- wait <- true
- }()
-
- if err := sendOneTCP(tcp); err != nil {
- t.Fatalf("send one: %s", err)
- return
- }
-
- <-wait
- if err := l.Close(); err != nil {
- t.Error(err)
- }
-}
diff --git a/middleware/dnstap/setup.go b/middleware/dnstap/setup.go
deleted file mode 100644
index 63a3eb099..000000000
--- a/middleware/dnstap/setup.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package dnstap
-
-import (
- "fmt"
- "io"
- "log"
- "strings"
-
- "github.com/coredns/coredns/core/dnsserver"
- "github.com/coredns/coredns/middleware"
- "github.com/coredns/coredns/middleware/dnstap/out"
- "github.com/coredns/coredns/middleware/pkg/dnsutil"
-
- "github.com/mholt/caddy"
- "github.com/mholt/caddy/caddyfile"
-)
-
-func init() {
- caddy.RegisterPlugin("dnstap", caddy.Plugin{
- ServerType: "dns",
- Action: wrapSetup,
- })
-}
-
-func wrapSetup(c *caddy.Controller) error {
- if err := setup(c); err != nil {
- return middleware.Error("dnstap", err)
- }
- return nil
-}
-
-type config struct {
- target string
- socket bool
- full bool
-}
-
-func parseConfig(d *caddyfile.Dispenser) (c config, err error) {
- d.Next() // directive name
-
- if !d.Args(&c.target) {
- return c, d.ArgErr()
- }
-
- if strings.HasPrefix(c.target, "tcp://") {
- // remote IP endpoint
- servers, err := dnsutil.ParseHostPortOrFile(c.target[6:])
- if err != nil {
- return c, d.ArgErr()
- }
- c.target = servers[0]
- } else {
- // default to UNIX socket
- if strings.HasPrefix(c.target, "unix://") {
- c.target = c.target[7:]
- }
- c.socket = true
- }
-
- c.full = d.NextArg() && d.Val() == "full"
-
- return
-}
-
-func setup(c *caddy.Controller) error {
- conf, err := parseConfig(&c.Dispenser)
- if err != nil {
- return err
- }
-
- dnstap := Dnstap{Pack: conf.full}
-
- var o io.WriteCloser
- if conf.socket {
- o, err = out.NewSocket(conf.target)
- if err != nil {
- log.Printf("[WARN] Can't connect to %s at the moment: %s", conf.target, err)
- }
- } else {
- o = out.NewTCP(conf.target)
- }
- dnstap.Out = o
-
- c.OnShutdown(func() error {
- if err := o.Close(); err != nil {
- return fmt.Errorf("output: %s", err)
- }
- return nil
- })
-
- dnsserver.GetConfig(c).AddMiddleware(
- func(next middleware.Handler) middleware.Handler {
- dnstap.Next = next
- return dnstap
- })
-
- return nil
-}
diff --git a/middleware/dnstap/setup_test.go b/middleware/dnstap/setup_test.go
deleted file mode 100644
index fc1dc98e0..000000000
--- a/middleware/dnstap/setup_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package dnstap
-
-import (
- "github.com/mholt/caddy"
- "testing"
-)
-
-func TestConfig(t *testing.T) {
- tests := []struct {
- file string
- path string
- full bool
- socket bool
- fail bool
- }{
- {"dnstap dnstap.sock full", "dnstap.sock", true, true, false},
- {"dnstap unix://dnstap.sock", "dnstap.sock", false, true, false},
- {"dnstap tcp://127.0.0.1:6000", "127.0.0.1:6000", false, false, false},
- {"dnstap", "fail", false, true, true},
- }
- for _, c := range tests {
- cad := caddy.NewTestController("dns", c.file)
- conf, err := parseConfig(&cad.Dispenser)
- if c.fail {
- if err == nil {
- t.Errorf("%s: %s", c.file, err)
- }
- } else if err != nil || conf.target != c.path ||
- conf.full != c.full || conf.socket != c.socket {
-
- t.Errorf("expected: %+v\nhave: %+v\nerror: %s\n", c, conf, err)
- }
- }
-}
diff --git a/middleware/dnstap/taprw/writer.go b/middleware/dnstap/taprw/writer.go
deleted file mode 100644
index 99572afd9..000000000
--- a/middleware/dnstap/taprw/writer.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Package taprw takes a query and intercepts the response.
-// It will log both after the response is written.
-package taprw
-
-import (
- "fmt"
-
- "github.com/coredns/coredns/middleware/dnstap/msg"
-
- tap "github.com/dnstap/golang-dnstap"
- "github.com/miekg/dns"
-)
-
-// Tapper is what ResponseWriter needs to log to dnstap.
-type Tapper interface {
- TapMessage(m *tap.Message) error
- TapBuilder() msg.Builder
-}
-
-// ResponseWriter captures the client response and logs the query to dnstap.
-// Single request use.
-type ResponseWriter struct {
- queryEpoch uint64
- Query *dns.Msg
- dns.ResponseWriter
- Tapper
- err error
-}
-
-// DnstapError check if a dnstap error occurred during Write and returns it.
-func (w ResponseWriter) DnstapError() error {
- return w.err
-}
-
-// QueryEpoch sets the query epoch as reported by dnstap.
-func (w *ResponseWriter) QueryEpoch() {
- w.queryEpoch = msg.Epoch()
-}
-
-// WriteMsg writes back the response to the client and THEN works on logging the request
-// and response to dnstap.
-// Dnstap errors are to be checked by DnstapError.
-func (w *ResponseWriter) WriteMsg(resp *dns.Msg) (writeErr error) {
- writeErr = w.ResponseWriter.WriteMsg(resp)
- writeEpoch := msg.Epoch()
-
- b := w.TapBuilder()
- b.TimeSec = w.queryEpoch
- if err := func() (err error) {
- err = b.AddrMsg(w.ResponseWriter.RemoteAddr(), w.Query)
- if err != nil {
- return
- }
- return w.TapMessage(b.ToClientQuery())
- }(); err != nil {
- w.err = fmt.Errorf("client query: %s", err)
- // don't forget to call DnstapError later
- }
-
- if writeErr == nil {
- if err := func() (err error) {
- b.TimeSec = writeEpoch
- if err = b.Msg(resp); err != nil {
- return
- }
- return w.TapMessage(b.ToClientResponse())
- }(); err != nil {
- w.err = fmt.Errorf("client response: %s", err)
- }
- }
-
- return
-}
diff --git a/middleware/dnstap/taprw/writer_test.go b/middleware/dnstap/taprw/writer_test.go
deleted file mode 100644
index 426f1f580..000000000
--- a/middleware/dnstap/taprw/writer_test.go
+++ /dev/null
@@ -1,82 +0,0 @@
-package taprw
-
-import (
- "errors"
- "testing"
-
- "github.com/coredns/coredns/middleware/dnstap/msg"
- "github.com/coredns/coredns/middleware/dnstap/test"
- mwtest "github.com/coredns/coredns/middleware/test"
-
- tap "github.com/dnstap/golang-dnstap"
- "github.com/miekg/dns"
-)
-
-type TapFailer struct {
-}
-
-func (TapFailer) TapMessage(*tap.Message) error {
- return errors.New("failed")
-}
-func (TapFailer) TapBuilder() msg.Builder {
- return msg.Builder{Full: true}
-}
-
-func TestDnstapError(t *testing.T) {
- rw := ResponseWriter{
- Query: new(dns.Msg),
- ResponseWriter: &mwtest.ResponseWriter{},
- Tapper: TapFailer{},
- }
- if err := rw.WriteMsg(new(dns.Msg)); err != nil {
- t.Errorf("dnstap error during Write: %s", err)
- }
- if rw.DnstapError() == nil {
- t.Fatal("no dnstap error")
- }
-}
-
-func testingMsg() (m *dns.Msg) {
- m = new(dns.Msg)
- m.SetQuestion("example.com.", dns.TypeA)
- m.SetEdns0(4097, true)
- return
-}
-
-func TestClientQueryResponse(t *testing.T) {
- trapper := test.TrapTapper{Full: true}
- m := testingMsg()
- rw := ResponseWriter{
- Query: m,
- Tapper: &trapper,
- ResponseWriter: &mwtest.ResponseWriter{},
- }
- d := test.TestingData()
-
- // will the wire-format msg be reported?
- bin, err := m.Pack()
- if err != nil {
- t.Fatal(err)
- return
- }
- d.Packed = bin
-
- if err := rw.WriteMsg(m); err != nil {
- t.Fatal(err)
- return
- }
- if l := len(trapper.Trap); l != 2 {
- t.Fatalf("%d msg trapped", l)
- return
- }
- want := d.ToClientQuery()
- have := trapper.Trap[0]
- if !test.MsgEqual(want, have) {
- t.Fatalf("query: want: %v\nhave: %v", want, have)
- }
- want = d.ToClientResponse()
- have = trapper.Trap[1]
- if !test.MsgEqual(want, have) {
- t.Fatalf("response: want: %v\nhave: %v", want, have)
- }
-}
diff --git a/middleware/dnstap/test/helpers.go b/middleware/dnstap/test/helpers.go
deleted file mode 100644
index 46ba327ab..000000000
--- a/middleware/dnstap/test/helpers.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package test
-
-import (
- "net"
- "reflect"
-
- "github.com/coredns/coredns/middleware/dnstap/msg"
-
- tap "github.com/dnstap/golang-dnstap"
- "golang.org/x/net/context"
-)
-
-// Context is a message trap.
-type Context struct {
- context.Context
- TrapTapper
-}
-
-// TestingData returns the Data matching coredns/test.ResponseWriter.
-func TestingData() (d *msg.Data) {
- d = &msg.Data{
- SocketFam: tap.SocketFamily_INET,
- SocketProto: tap.SocketProtocol_UDP,
- Address: net.ParseIP("10.240.0.1"),
- Port: 40212,
- }
- return
-}
-
-type comp struct {
- Type *tap.Message_Type
- SF *tap.SocketFamily
- SP *tap.SocketProtocol
- QA []byte
- RA []byte
- QP *uint32
- RP *uint32
- QTSec bool
- RTSec bool
- RM []byte
- QM []byte
-}
-
-func toComp(m *tap.Message) comp {
- return comp{
- Type: m.Type,
- SF: m.SocketFamily,
- SP: m.SocketProtocol,
- QA: m.QueryAddress,
- RA: m.ResponseAddress,
- QP: m.QueryPort,
- RP: m.ResponsePort,
- QTSec: m.QueryTimeSec != nil,
- RTSec: m.ResponseTimeSec != nil,
- RM: m.ResponseMessage,
- QM: m.QueryMessage,
- }
-}
-
-// MsgEqual compares two dnstap messages ignoring timestamps.
-func MsgEqual(a, b *tap.Message) bool {
- return reflect.DeepEqual(toComp(a), toComp(b))
-}
-
-// TrapTapper traps messages.
-type TrapTapper struct {
- Trap []*tap.Message
- Full bool
-}
-
-// TapMessage adds the message to the trap.
-func (t *TrapTapper) TapMessage(m *tap.Message) error {
- t.Trap = append(t.Trap, m)
- return nil
-}
-
-// TapBuilder returns a test msg.Builder.
-func (t *TrapTapper) TapBuilder() msg.Builder {
- return msg.Builder{Full: t.Full}
-}