coredns/plugin/dnstap/out/socket.go
Miek Gieben d8714e64e4 Remove the word middleware (#1067)
* Rename middleware to plugin

first pass; mostly used 'sed', few spots where I manually changed
text.

This still builds a coredns binary.

* fmt error

* Rename AddMiddleware to AddPlugin

* Readd AddMiddleware to remain backwards compat
2017-09-14 09:36:06 +01:00

86 lines
1.6 KiB
Go

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
}