2017-07-24 23:12:50 +02:00
package msg
import (
2020-10-12 19:10:35 +02:00
"fmt"
2017-07-24 23:12:50 +02:00
"net"
2018-03-01 03:19:01 +01:00
"time"
2017-07-24 23:12:50 +02:00
tap "github.com/dnstap/golang-dnstap"
)
2020-10-12 19:10:35 +02:00
var (
protoUDP = tap . SocketProtocol_UDP
protoTCP = tap . SocketProtocol_TCP
familyINET = tap . SocketFamily_INET
familyINET6 = tap . SocketFamily_INET6
)
2017-07-24 23:12:50 +02:00
2026-06-25 17:49:32 -05:00
// socketFamilyAndAddress maps an IP to the dnstap SocketFamily and the address
// bytes to store for it. IPv4, including IPv4-mapped IPv6, is returned as a
// 4-octet INET address; anything else as a 16-octet INET6 address, matching
// https://github.com/dnstap/dnstap.pb/blob/main/dnstap.proto.
func socketFamilyAndAddress ( ip net . IP ) ( * tap . SocketFamily , [ ] byte ) {
if ip4 := ip . To4 ( ) ; ip4 != nil {
return & familyINET , ip4
}
return & familyINET6 , ip
}
// TODO: SetQueryAddress and SetResponseAddress each set the message-level SocketFamily (and SocketProtocol) from their own address. A dnstap Message describes a single socket whose two endpoints share one family, but calling both setters with addresses of different families leaves SocketFamily reflecting only the last call and inconsistent with the other stored address. Evaluate replacing the two setters with a single SetAddresses(t, query, response) that derives SocketFamily/SocketProtocol once for the whole socket and rejects a family mismatch.
2020-10-12 19:10:35 +02:00
// SetQueryAddress adds the query address to the message. This also sets the SocketFamily and SocketProtocol.
func SetQueryAddress ( t * tap . Message , addr net . Addr ) error {
switch a := addr . ( type ) {
case * net . TCPAddr :
t . SocketProtocol = & protoTCP
2017-09-01 12:41:41 +02:00
2026-01-01 13:50:29 +05:30
p := uint32 ( a . Port ) // #nosec G115 -- Port is inherently bounded (1-65535)
2020-10-12 19:10:35 +02:00
t . QueryPort = & p
2017-09-01 12:41:41 +02:00
2026-06-25 17:49:32 -05:00
t . SocketFamily , t . QueryAddress = socketFamilyAndAddress ( a . IP )
2020-10-12 19:10:35 +02:00
return nil
2017-07-24 23:12:50 +02:00
case * net . UDPAddr :
2020-10-12 19:10:35 +02:00
t . SocketProtocol = & protoUDP
2026-01-01 13:50:29 +05:30
p := uint32 ( a . Port ) // #nosec G115 -- Port is inherently bounded (1-65535)
2020-10-12 19:10:35 +02:00
t . QueryPort = & p
2017-07-24 23:12:50 +02:00
2026-06-25 17:49:32 -05:00
t . SocketFamily , t . QueryAddress = socketFamilyAndAddress ( a . IP )
2020-10-12 19:10:35 +02:00
return nil
default :
return fmt . Errorf ( "unknown address type: %T" , a )
2017-07-24 23:12:50 +02:00
}
2018-03-01 03:19:01 +01:00
}
2017-07-24 23:12:50 +02:00
2020-10-12 19:10:35 +02:00
// SetResponseAddress the response address to the message. This also sets the SocketFamily and SocketProtocol.
func SetResponseAddress ( t * tap . Message , addr net . Addr ) error {
switch a := addr . ( type ) {
case * net . TCPAddr :
t . SocketProtocol = & protoTCP
2018-03-01 03:19:01 +01:00
2026-01-01 13:50:29 +05:30
p := uint32 ( a . Port ) // #nosec G115 -- Port is inherently bounded (1-65535)
2020-10-12 19:10:35 +02:00
t . ResponsePort = & p
2017-07-24 23:12:50 +02:00
2026-06-25 17:49:32 -05:00
t . SocketFamily , t . ResponseAddress = socketFamilyAndAddress ( a . IP )
2020-10-12 19:10:35 +02:00
return nil
case * net . UDPAddr :
t . SocketProtocol = & protoUDP
2018-03-01 03:19:01 +01:00
2026-01-01 13:50:29 +05:30
p := uint32 ( a . Port ) // #nosec G115 -- Port is inherently bounded (1-65535)
2020-10-12 19:10:35 +02:00
t . ResponsePort = & p
2017-07-24 23:12:50 +02:00
2026-06-25 17:49:32 -05:00
t . SocketFamily , t . ResponseAddress = socketFamilyAndAddress ( a . IP )
2020-10-12 19:10:35 +02:00
return nil
default :
return fmt . Errorf ( "unknown address type: %T" , a )
}
2017-07-24 23:12:50 +02:00
}
2020-10-12 19:10:35 +02:00
// SetQueryTime sets the time of the query in t.
func SetQueryTime ( t * tap . Message , ti time . Time ) {
2026-01-01 13:50:29 +05:30
qts := uint64 ( ti . Unix ( ) ) // #nosec G115 -- Unix time fits in uint64
qtn := uint32 ( ti . Nanosecond ( ) ) // #nosec G115 -- Nanoseconds (0-999999999) fit in uint32
2020-10-12 19:10:35 +02:00
t . QueryTimeSec = & qts
t . QueryTimeNsec = & qtn
2017-07-24 23:12:50 +02:00
}
2017-09-01 12:41:41 +02:00
2020-10-12 19:10:35 +02:00
// SetResponseTime sets the time of the response in t.
func SetResponseTime ( t * tap . Message , ti time . Time ) {
2026-01-01 13:50:29 +05:30
rts := uint64 ( ti . Unix ( ) ) // #nosec G115 -- Unix time fits in uint64
rtn := uint32 ( ti . Nanosecond ( ) ) // #nosec G115 -- Nanoseconds (0-999999999) fit in uint32
2020-10-12 19:10:35 +02:00
t . ResponseTimeSec = & rts
t . ResponseTimeNsec = & rtn
2017-09-01 12:41:41 +02:00
}
2020-10-12 19:10:35 +02:00
// SetType sets the type in t.
func SetType ( t * tap . Message , typ tap . Message_Type ) { t . Type = & typ }