diff options
Diffstat (limited to 'plugin/dnstap/msg/msg.go')
-rw-r--r-- | plugin/dnstap/msg/msg.go | 194 |
1 files changed, 95 insertions, 99 deletions
diff --git a/plugin/dnstap/msg/msg.go b/plugin/dnstap/msg/msg.go index 95442301e..44c88d3e5 100644 --- a/plugin/dnstap/msg/msg.go +++ b/plugin/dnstap/msg/msg.go @@ -1,157 +1,153 @@ -// 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 plugin configuration. +// Builder helps to build a Dnstap message. 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 + Address net.IP Port uint32 TimeSec uint64 + + err error } -// 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) +// New returns a new Builder +func New() *Builder { + return &Builder{} +} - 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 +// Addr adds the remote address to the message. +func (b *Builder) Addr(remote net.Addr) *Builder { + if b.err != nil { + return b } - 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 + b.Address = addr.IP + b.Port = uint32(addr.Port) + b.SocketProto = tap.SocketProtocol_TCP case *net.UDPAddr: - d.Address = addr.IP - d.Port = uint32(addr.Port) - d.SocketProto = tap.SocketProtocol_UDP + b.Address = addr.IP + b.Port = uint32(addr.Port) + b.SocketProto = tap.SocketProtocol_UDP default: - return errors.New("unknown remote address type") + b.err = errors.New("unknown remote address type") + return b } - if a := net.IP(d.Address); a.To4() != nil { - d.SocketFam = tap.SocketFamily_INET + if b.Address.To4() != nil { + b.SocketFam = tap.SocketFamily_INET } else { - d.SocketFam = tap.SocketFamily_INET6 + b.SocketFam = tap.SocketFamily_INET6 } + return b +} - return nil +// Msg adds the raw DNS message to the dnstap message. +func (b *Builder) Msg(m *dns.Msg) *Builder { + if b.err != nil { + return b + } + + b.Packed, b.err = m.Pack() + return b } -// Pack encodes the DNS message into Data. -func (d *Data) Pack(m *dns.Msg) error { - packed, err := m.Pack() +// HostPort adds the remote address as encoded by dnsutil.ParseHostPortOrFile to the message. +func (b *Builder) HostPort(addr string) *Builder { + ip, port, err := net.SplitHostPort(addr) if err != nil { - return err + b.err = err + return b + } + p, err := strconv.ParseUint(port, 10, 32) + if err != nil { + b.err = err + return b + } + b.Port = uint32(p) + + if ip := net.ParseIP(ip); ip != nil { + b.Address = []byte(ip) + if ip := ip.To4(); ip != nil { + b.SocketFam = tap.SocketFamily_INET + } else { + b.SocketFam = tap.SocketFamily_INET6 + } + return b } - d.Packed = packed - return nil + b.err = errors.New("not an ip address") + return b +} + +// Time adds the timestamp to the message. +func (b *Builder) Time(ts time.Time) *Builder { + b.TimeSec = uint64(ts.Unix()) + return b } // ToClientResponse transforms Data into a client response message. -func (d *Data) ToClientResponse() *tap.Message { +func (b *Builder) ToClientResponse() (*tap.Message, error) { 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, - } + SocketFamily: &b.SocketFam, + SocketProtocol: &b.SocketProto, + ResponseTimeSec: &b.TimeSec, + ResponseMessage: b.Packed, + QueryAddress: b.Address, + QueryPort: &b.Port, + }, b.err } // ToClientQuery transforms Data into a client query message. -func (d *Data) ToClientQuery() *tap.Message { +func (b *Builder) ToClientQuery() (*tap.Message, error) { 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, - } + SocketFamily: &b.SocketFam, + SocketProtocol: &b.SocketProto, + QueryTimeSec: &b.TimeSec, + QueryMessage: b.Packed, + QueryAddress: b.Address, + QueryPort: &b.Port, + }, b.err } // ToOutsideQuery transforms the data into a forwarder or resolver query message. -func (d *Data) ToOutsideQuery(t tap.Message_Type) *tap.Message { +func (b *Builder) ToOutsideQuery(t tap.Message_Type) (*tap.Message, error) { return &tap.Message{ Type: &t, - SocketFamily: &d.SocketFam, - SocketProtocol: &d.SocketProto, - QueryTimeSec: &d.TimeSec, - QueryMessage: d.Packed, - ResponseAddress: d.Address, - ResponsePort: &d.Port, - } + SocketFamily: &b.SocketFam, + SocketProtocol: &b.SocketProto, + QueryTimeSec: &b.TimeSec, + QueryMessage: b.Packed, + ResponseAddress: b.Address, + ResponsePort: &b.Port, + }, b.err } // ToOutsideResponse transforms the data into a forwarder or resolver response message. -func (d *Data) ToOutsideResponse(t tap.Message_Type) *tap.Message { +func (b *Builder) ToOutsideResponse(t tap.Message_Type) (*tap.Message, error) { return &tap.Message{ Type: &t, - SocketFamily: &d.SocketFam, - SocketProtocol: &d.SocketProto, - ResponseTimeSec: &d.TimeSec, - ResponseMessage: d.Packed, - ResponseAddress: d.Address, - ResponsePort: &d.Port, - } + SocketFamily: &b.SocketFam, + SocketProtocol: &b.SocketProto, + ResponseTimeSec: &b.TimeSec, + ResponseMessage: b.Packed, + ResponseAddress: b.Address, + ResponsePort: &b.Port, + }, b.err } |