1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*!
* \file
*
* \brief A DNS traffic probe data structure.
*
* \addtogroup probe
* @{
*/
#pragma once
#include <stdint.h>
#include "libknot/consts.h"
#include "libknot/packet/pkt.h"
/*! EDE absence indication. */
#define KNOT_PROBE_DATA_EDE_NONE 0xFFFF
/*! Data transport protocol types. */
typedef enum {
KNOT_PROBE_PROTO_UDP = 0,
KNOT_PROBE_PROTO_TCP,
KNOT_PROBE_PROTO_QUIC,
KNOT_PROBE_PROTO_TLS,
KNOT_PROBE_PROTO_HTTPS,
} knot_probe_proto_t;
/*! DNS message header in wire format (network byte order!). */
typedef struct {
uint16_t id;
uint8_t byte3; /*!< QR, OPCODE, AA, TC, RD. */
uint8_t byte4; /*!< RA, Z, AD, CD, RCODE. */
uint16_t questions;
uint16_t answers;
uint16_t authorities;
uint16_t additionals;
} knot_probe_data_wire_hdr_t;
/*! Probe data unit. */
typedef struct {
uint8_t ip; /*!< IP protocol: 4 or 6. */
uint8_t proto; /*!< Transport protocol \ref knot_probe_proto_t. */
struct {
uint8_t addr[16]; /*!< Query destination address. */
uint16_t port; /*!< Query destination port. */
} local;
struct {
uint8_t addr[16]; /*!< Query source address. */
uint16_t port; /*!< Query source port. */
} remote;
struct {
knot_probe_data_wire_hdr_t hdr; /*!< DNS reply header. */
uint16_t size; /*!< DNS reply size (0 if no reply). */
uint16_t rcode; /*!< Final RCODE (header + EDNS + TSIG). */
uint16_t ede; /*!< EDE code if present. */
} reply;
uint32_t tcp_rtt; /*!< Average TCP RTT in microseconds. */
struct {
uint32_t options; /*!< EDNS options bit map (e.g. NSID ~ 1 << 3). */
uint16_t payload; /*!< EDNS payload size. */
uint8_t version; /*!< EDNS version. */
uint8_t present : 1; /*!< EDNS presence indication. */
uint8_t flag_do : 1; /*!< DO flag indication. */
uint8_t reserved : 6; /*!< Unused. */
} query_edns;
struct {
knot_probe_data_wire_hdr_t hdr; /*!< DNS query header. */
uint16_t size; /*!< DNS query size. */
uint16_t qclass; /*!< QCLASS. */
uint16_t qtype; /*!< QTYPE. */
uint8_t qname_len; /*!< QNAME length. */
uint8_t qname[KNOT_DNAME_MAXLEN]; /*!< QNAME. */
} query;
} knot_probe_data_t;
/*!
* \brief Initializes a probe data unit.
*
* \note 'reply.ede' and 'tcp.rtt' are zeroed only and require further setting.
*
* \param data Output probe data unit.
* \param proto Transport protocol \ref knot_probe_proto_t.
* \param local_addr Query destination address (optional).
* \param remote_addr Query source address.
* \param query Query packet.
* \param reply Reply packet (optional).
* \param rcode Extended rcode (combination of RCODE, EDNS, TSIG).
*
* \retval KNOT_EOK Success.
* \return KNOT_E* If error.
*/
int knot_probe_data_set(knot_probe_data_t *data, knot_probe_proto_t proto,
const struct sockaddr_storage *local_addr,
const struct sockaddr_storage *remote_addr,
const knot_pkt_t *query, const knot_pkt_t *reply,
uint16_t rcode);
/*!
* \brief Gets averate TCP RRT for a given socket descriptor.
*
* \note Implemented on Linux only!
*
* \param sockfd Socket descriptor of a TCP connection.
*
* \return Average TCP RTT in microseconds.
*/
uint32_t knot_probe_tcp_rtt(int sockfd);
/*! @} */
|