diff options
Diffstat (limited to 'plugin/dnstap/msg/msg.go')
-rw-r--r-- | plugin/dnstap/msg/msg.go | 200 |
1 files changed, 69 insertions, 131 deletions
diff --git a/plugin/dnstap/msg/msg.go b/plugin/dnstap/msg/msg.go index d96fc6c9a..f9d84c45a 100644 --- a/plugin/dnstap/msg/msg.go +++ b/plugin/dnstap/msg/msg.go @@ -1,159 +1,97 @@ package msg import ( - "errors" + "fmt" "net" - "strconv" "time" tap "github.com/dnstap/golang-dnstap" - "github.com/miekg/dns" ) -// Builder helps to build a Dnstap message. -type Builder struct { - Packed []byte - SocketProto tap.SocketProtocol - SocketFam tap.SocketFamily - Address net.IP - Port uint32 - TimeSec uint64 - TimeNsec uint32 - - err error -} +var ( + protoUDP = tap.SocketProtocol_UDP + protoTCP = tap.SocketProtocol_TCP + familyINET = tap.SocketFamily_INET + familyINET6 = tap.SocketFamily_INET6 +) -// New returns a new Builder -func New() *Builder { - return &Builder{} -} +// SetQueryAddress adds the query address to the message. This also sets the SocketFamily and SocketProtocol. +func SetQueryAddress(t *tap.Message, addr net.Addr) error { + t.SocketFamily = &familyINET + switch a := addr.(type) { + case *net.TCPAddr: + t.SocketProtocol = &protoTCP + t.QueryAddress = a.IP -// Addr adds the remote address to the message. -func (b *Builder) Addr(remote net.Addr) *Builder { - if b.err != nil { - return b - } + p := uint32(a.Port) + t.QueryPort = &p - switch addr := remote.(type) { - case *net.TCPAddr: - b.Address = addr.IP - b.Port = uint32(addr.Port) - b.SocketProto = tap.SocketProtocol_TCP + if a.IP.To4() == nil { + t.SocketFamily = &familyINET6 + } + return nil case *net.UDPAddr: - b.Address = addr.IP - b.Port = uint32(addr.Port) - b.SocketProto = tap.SocketProtocol_UDP - default: - b.err = errors.New("unknown remote address type") - return b - } + t.SocketProtocol = &protoUDP + t.QueryAddress = a.IP + + p := uint32(a.Port) + t.QueryPort = &p - if b.Address.To4() != nil { - b.SocketFam = tap.SocketFamily_INET - } else { - b.SocketFam = tap.SocketFamily_INET6 + if a.IP.To4() == nil { + t.SocketFamily = &familyINET6 + } + return nil + default: + return fmt.Errorf("unknown address type: %T", a) } - return b } -// Msg adds the raw DNS message to the dnstap message. -func (b *Builder) Msg(m *dns.Msg) *Builder { - if b.err != nil { - return b - } +// SetResponseAddress the response address to the message. This also sets the SocketFamily and SocketProtocol. +func SetResponseAddress(t *tap.Message, addr net.Addr) error { + t.SocketFamily = &familyINET + switch a := addr.(type) { + case *net.TCPAddr: + t.SocketProtocol = &protoTCP + t.ResponseAddress = a.IP - b.Packed, b.err = m.Pack() - return b -} + p := uint32(a.Port) + t.ResponsePort = &p -// 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 { - 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 + if a.IP.To4() == nil { + t.SocketFamily = &familyINET6 } - return b - } - b.err = errors.New("not an ip address") - return b -} + return nil + case *net.UDPAddr: + t.SocketProtocol = &protoUDP + t.ResponseAddress = a.IP -// Time adds the timestamp to the message. -func (b *Builder) Time(ts time.Time) *Builder { - b.TimeSec = uint64(ts.Unix()) - b.TimeNsec = uint32(ts.Nanosecond()) - return b -} + p := uint32(a.Port) + t.ResponsePort = &p -// ToClientResponse transforms Data into a client response message. -func (b *Builder) ToClientResponse() (*tap.Message, error) { - t := tap.Message_CLIENT_RESPONSE - return &tap.Message{ - Type: &t, - SocketFamily: &b.SocketFam, - SocketProtocol: &b.SocketProto, - ResponseTimeSec: &b.TimeSec, - ResponseTimeNsec: &b.TimeNsec, - ResponseMessage: b.Packed, - QueryAddress: b.Address, - QueryPort: &b.Port, - }, b.err + if a.IP.To4() == nil { + t.SocketFamily = &familyINET6 + } + return nil + default: + return fmt.Errorf("unknown address type: %T", a) + } } -// ToClientQuery transforms Data into a client query message. -func (b *Builder) ToClientQuery() (*tap.Message, error) { - t := tap.Message_CLIENT_QUERY - return &tap.Message{ - Type: &t, - SocketFamily: &b.SocketFam, - SocketProtocol: &b.SocketProto, - QueryTimeSec: &b.TimeSec, - QueryTimeNsec: &b.TimeNsec, - QueryMessage: b.Packed, - QueryAddress: b.Address, - QueryPort: &b.Port, - }, b.err +// SetQueryTime sets the time of the query in t. +func SetQueryTime(t *tap.Message, ti time.Time) { + qts := uint64(ti.Unix()) + qtn := uint32(ti.Nanosecond()) + t.QueryTimeSec = &qts + t.QueryTimeNsec = &qtn } -// ToOutsideQuery transforms the data into a forwarder or resolver query message. -func (b *Builder) ToOutsideQuery(t tap.Message_Type) (*tap.Message, error) { - return &tap.Message{ - Type: &t, - SocketFamily: &b.SocketFam, - SocketProtocol: &b.SocketProto, - QueryTimeSec: &b.TimeSec, - QueryTimeNsec: &b.TimeNsec, - QueryMessage: b.Packed, - ResponseAddress: b.Address, - ResponsePort: &b.Port, - }, b.err +// SetResponseTime sets the time of the response in t. +func SetResponseTime(t *tap.Message, ti time.Time) { + rts := uint64(ti.Unix()) + rtn := uint32(ti.Nanosecond()) + t.ResponseTimeSec = &rts + t.ResponseTimeNsec = &rtn } -// ToOutsideResponse transforms the data into a forwarder or resolver response message. -func (b *Builder) ToOutsideResponse(t tap.Message_Type) (*tap.Message, error) { - return &tap.Message{ - Type: &t, - SocketFamily: &b.SocketFam, - SocketProtocol: &b.SocketProto, - ResponseTimeSec: &b.TimeSec, - ResponseTimeNsec: &b.TimeNsec, - ResponseMessage: b.Packed, - ResponseAddress: b.Address, - ResponsePort: &b.Port, - }, b.err -} +// SetType sets the type in t. +func SetType(t *tap.Message, typ tap.Message_Type) { t.Type = &typ } |