89 lines
1.9 KiB
Go
89 lines
1.9 KiB
Go
// Package msg helps to build a dnstap Message.
|
|
package msg
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/coredns/coredns/request"
|
|
|
|
tap "github.com/dnstap/golang-dnstap"
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
// Data helps to build a dnstap Message.
|
|
// It can be transformed into the actual Message using this package.
|
|
type Data struct {
|
|
Type tap.Message_Type
|
|
Packed []byte
|
|
SocketProto tap.SocketProtocol
|
|
SocketFam tap.SocketFamily
|
|
Address []byte
|
|
Port uint32
|
|
TimeSec uint64
|
|
}
|
|
|
|
func (d *Data) FromRequest(r request.Request) error {
|
|
switch addr := r.W.RemoteAddr().(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
|
|
}
|
|
|
|
func (d *Data) Pack(m *dns.Msg) error {
|
|
packed, err := m.Pack()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
d.Packed = packed
|
|
return nil
|
|
}
|
|
|
|
func (d *Data) Epoch() {
|
|
d.TimeSec = uint64(time.Now().Unix())
|
|
}
|
|
|
|
// Transform the data into a client response message.
|
|
func (d *Data) ToClientResponse() *tap.Message {
|
|
d.Type = tap.Message_CLIENT_RESPONSE
|
|
return &tap.Message{
|
|
Type: &d.Type,
|
|
SocketFamily: &d.SocketFam,
|
|
SocketProtocol: &d.SocketProto,
|
|
ResponseTimeSec: &d.TimeSec,
|
|
ResponseMessage: d.Packed,
|
|
QueryAddress: d.Address,
|
|
QueryPort: &d.Port,
|
|
}
|
|
}
|
|
|
|
// Transform the data into a client query message.
|
|
func (d *Data) ToClientQuery() *tap.Message {
|
|
d.Type = tap.Message_CLIENT_QUERY
|
|
return &tap.Message{
|
|
Type: &d.Type,
|
|
SocketFamily: &d.SocketFam,
|
|
SocketProtocol: &d.SocketProto,
|
|
QueryTimeSec: &d.TimeSec,
|
|
QueryMessage: d.Packed,
|
|
QueryAddress: d.Address,
|
|
QueryPort: &d.Port,
|
|
}
|
|
}
|