-
Notifications
You must be signed in to change notification settings - Fork 8
/
tcpinfo.proto
312 lines (265 loc) · 9.03 KB
/
tcpinfo.proto
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
// Protobufs corresponding to messages in linux/include/uapi/linux/inet_diag.h
//
// Up to date as of net-next v4.16 3fb78e8be9d9428fbc4c016f8b031b01a6fdd63d
// These protos should ONLY contain raw data collected through netlink library.
// Meta-data, such as experiment name or collection time, and any data from
// sources other than netlink should be handles OUTSIDE these protos.
syntax = "proto3";
option go_package = "nl-proto";
/*
This is a work in progress.
Generally, this reflects the kernel's struct tcp_info. However, we have
some flexibility to simplify some bits, largely from protobuf's has_xxx
functionality. For example, some of the OPT_XXX flags in the options field
can be elided in this protobuf, because their values are reflected in
other fields, such as wscale fields.
We should consider collecting any or all of the extensions identified in
inet_diag.h Extensions:
enum {
INET_DIAG_NONE,
INET_DIAG_MEMINFO, // Done (subset of skmeminfo)
INET_DIAG_INFO, // Done
INET_DIAG_VEGASINFO, // Done
INET_DIAG_CONG, // Done - string field in top level message.
INET_DIAG_TOS,
INET_DIAG_TCLASS,
INET_DIAG_SKMEMINFO, // Done
INET_DIAG_SHUTDOWN,
INET_DIAG_DCTCPINFO, // Done
INET_DIAG_PROTOCOL, // Done - string in top level message.
INET_DIAG_SKV6ONLY,
INET_DIAG_LOCALS,
INET_DIAG_PEERS,
INET_DIAG_PAD,
INET_DIAG_MARK, // NEW - should we include this???
INET_DIAG_BBRINFO, // NEW Done.
__INET_DIAG_MAX,
};
*/
message EndPoint {
uint32 port = 1;
bytes ip = 2; // 4 or 16 bytes for ipv4 or ipv6 address.
}
// Using slightly different structure than inete_diag_sockid. Oddly,
// inet_diag.h does not specify the connection family in the sockid struct, but
// instead in the inet_diag_msg. However, in proto land, we can additionally
// infer the family from the number of bytes in EndPoint.ip.
message InetSocketIDProto {
EndPoint source = 1;
EndPoint destination = 2;
uint32 interface = 5;
// Using fixed64, as this is more efficient for hashes, keys, cookies.
fixed64 cookie = 6;
}
//extend google.protobuf.EnumValueOptions {
// string name = 54321;
//}
// https://datatracker.ietf.org/doc/draft-ietf-tcpm-rfc793bis/
// and uapi/linux/tcp.h
enum TCPState { // from tcp_states.h
INVALID = 0; // [(name)="Invalid"];
ESTABLISHED = 1; // [(name)="Established"];
SYN_SENT = 2; //[(name)="SynSent"];
SYN_RECV = 3; //[(name)="SynRecv"];
FIN_WAIT1 = 4; //[(name)="FinWait1"];
FIN_WAIT2 = 5; //[(name)="FinWait2"];
TIME_WAIT = 6; //[(name)="TimeWait"];
CLOSE = 7; //[(name)="Close"];
CLOSE_WAIT = 8; //[(name)="CloseWait"];
LAST_ACK = 9; //[(name)="LastAck"];
LISTEN = 10; //[(name)="Listen"];
CLOSING = 11; //[(name)="Closing"];
}
// For contents of struct inet_diag_msg.
message InetDiagMsgProto {
enum AddressFamily {
// NOTE: these are equivalent to AF_... in socket.h, but cannot have the
// same names since those are macros and will cause collisions.
// There are many other families, but for now we only care about these.
UNSPEC = 0;
INET = 2;
INET6 = 10;
}
// These are 8 bit unsigned.
AddressFamily family = 1;
// Assuming for now this is the same as the TCPF_... states in struct tcp_info.
// So use the same enumeration.
// TODO - is this the same TCPF state?
TCPState state = 2;
uint32 timer = 3;
uint32 retrans = 4;
InetSocketIDProto sock_id = 5;
uint32 expires = 6;
uint32 rqueue = 7;
uint32 wqueue = 8;
uint32 uid = 9;
uint32 inode = 10;
}
// Proto representation for struct tcpvegas_info, in inet_diag.h
message TCPVegasInfoProto {
// Note that tcpv_enabled is represented by the has_xxx in the parent.
uint32 rttcnt = 1;
uint32 rtt = 2;
uint32 minrtt = 3;
}
// Proto representation for struct tcp_dctcp_info, in inet_diag.h
message DCTCPInfoProto {
// Note that dctcp_enabled is represented by the has_xxx in the parent.
uint32 ce_state = 1;
uint32 alpha = 2;
uint32 ab_ecn = 3;
uint32 ab_tot = 4;
}
// Proto representation for INET_DIAG_SKMEMINFO messages.
// Haven't found a corresponding linux struct, but the message is described
// in https://manpages.debian.org/stretch/manpages/sock_diag.7.en.html
message SocketMemInfoProto {
uint32 rmem_alloc = 1;
uint32 rcvbuf = 2;
uint32 wmem_alloc = 3;
uint32 sndbuf = 4;
uint32 fwd_alloc = 5;
uint32 wmem_queued = 6;
uint32 optmem = 7;
uint32 backlog = 8;
uint32 drops = 9;
}
// Proto representation for struct inet_diag_meminfo.
message MemInfoProto {
uint32 rmem = 1;
uint32 wmem = 2;
uint32 fmem = 3;
uint32 tmem = 4;
}
// Proto representation for struct tcp_bbr_info.
message BBRInfoProto {
uint64 bw = 1; // Combines bbr_bw_lo and bbr_bw_hi
uint32 min_rtt = 2; // min-filtered RTT in uSec
uint32 pacing_gain = 3; // pacing gain shifted left 8 bits
uint32 cwnd_gain = 4; // cwnd gain shifted left 8 bits.
}
// This proto is intended to precisely represent the raw data from struct tcp_info.
// It corresponds to the linux struct defined in include/uapi/linux/tcpinfo.h
message TCPInfoProto {
TCPState state = 1; // TCPF_... state, e.g. ESTABLISHED, FIN_WAIT1, CLOSING, ...
enum CAState {
TCPF_UNUSED = 0;
TCPF_CA_Open = 1;
TCPF_CA_Disorder = 2;
TCPF_CA_CWR = 4;
TCPF_CA_Recovery = 8;
TCPF_CA_Loss = 16;
}
// bitwise OR of CAState enums.
uint32 ca_state = 2; // Maybe make this bools?
uint32 retransmits = 3;
uint32 probes = 4;
uint32 backoff = 5;
// #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
enum Options {
OPT_UNUSED = 0;
OPT_TIMESTAMPS = 1;
OPT_SACK = 2;
OPT_WSCALE = 4;
OPT_ECN = 8;
OPT_ECN_SEEN = 16;
OPT_SYN_DATA = 32;
}
uint32 options = 6;
// Here are the 6 OPTs broken out as bools.
bool ts_opt = 601;
bool sack_opt = 602;
// wscale_opt determines whether snd_wscale and rcv_wscale are populated.
// So this is actually redundant with has_snd_wscale and has_rcv_wscale.
bool wscale_opt = 603;
bool ecn_opt = 604;
bool ecnseen_opt = 605;
bool fastopen_opt = 606;
// These are 4 bit fields.
uint32 snd_wscale = 7;
uint32 rcv_wscale = 8;
// This field was recently added as an eighth u8 immediately following
// tcpi_xxx_wscale bit fields, so inserting it here.
bool delivery_rate_app_limited = 801;
uint32 rto = 9;
uint32 ato = 10;
uint32 snd_mss = 11;
uint32 rcv_mss = 12;
uint32 unacked = 13;
uint32 sacked = 14;
uint32 lost = 15;
uint32 retrans = 16;
uint32 fackets = 17;
/* Times. */
uint32 last_data_sent = 18; // msec ?
uint32 last_ack_sent = 19; // msec ? /* Not remembered, sorry. */
uint32 last_data_recv = 20; // msec ?
uint32 last_ack_recv = 21; // msec ?
/* Metrics. */
uint32 pmtu = 22;
uint32 rcv_ssthresh = 23;
uint32 rtt = 24; // msec
uint32 rttvar = 25;
uint32 snd_ssthresh = 26;
uint32 snd_cwnd = 27;
uint32 advmss = 28;
uint32 reordering = 29;
uint32 rcv_rtt = 30;
uint32 rcv_space = 31;
uint32 total_retrans = 32;
// In tcp.h, these four are 64 bit unsigned. However, the pacing rates
// are often max-1. Since protobufs use varints, we make these signed for
// compact encoding.
int64 pacing_rate = 33;
int64 max_pacing_rate = 34;
uint64 bytes_acked = 35; /* RFC4898 */
uint64 bytes_received = 36; /* RFC4898 */
uint32 segs_out = 37; /* RFC4898 tcpEStatsPerfSegsOut */
uint32 segs_in = 38; /* RFC4898 tcpEStatsPerfSegsIn */
uint32 notsent_bytes = 39;
uint32 min_rtt = 40;
uint32 data_segs_in = 41; /* RFC4898 tcpEStatsDataSegsIn */
uint32 data_segs_out = 42; /* RFC4898 tcpEStatsDataSegsOut */
uint64 delivery_rate = 43;
uint64 busy_time = 44;
uint64 rwnd_limited = 45;
uint64 sndbuf_limited = 46;
}
enum Protocol {
IPPROTO_UNUSED = 0;
IPPROTO_TCP = 6;
IPPROTO_UDP = 17;
IPPROTO_DCCP = 33;
}
// Parent containing all info gathered through netlink library.
message TCPDiagnosticsProto {
// Info from struct inet_diag_msg, including socket_id;
InetDiagMsgProto inet_diag_msg = 1;
// From INET_DIAG_PROTOCOL message.
Protocol diag_protocol = 2;
// From INET_DIAG_CONG message.
string congestion_algorithm = 3;
// The following three are mutually exclusive, as they provide
// data from different congestion control strategies.
oneof cc_info {
// Data obtained from struct tcpvegas_info.
TCPVegasInfoProto vegas = 4;
// Data obtained from struct tcp_dctcp_info.
DCTCPInfoProto dctcp = 5;
// Data obtained from struct tcp_bbr_info.
BBRInfoProto bbr_info = 6;
}
// Data obtained from INET_DIAG_SKMEMINFO.
SocketMemInfoProto socket_mem = 7;
// Data obtained from INET_DIAG_MEMINFO.
MemInfoProto mem_info = 8;
// Data obtained from struct tcp_info.
TCPInfoProto tcp_info = 9;
// If there is shutdown info, this is the mask value.
// Check has_shutdown_mask to determine whether present.
oneof shutdown {
uint32 shutdown_mask = 10;
}
// Timestamp of batch of messages containing this message.
int64 timestamp = 11;
}