/src/samba/third_party/ngtcp2/lib/ngtcp2_log.c
Line | Count | Source |
1 | | /* |
2 | | * ngtcp2 |
3 | | * |
4 | | * Copyright (c) 2018 ngtcp2 contributors |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining |
7 | | * a copy of this software and associated documentation files (the |
8 | | * "Software"), to deal in the Software without restriction, including |
9 | | * without limitation the rights to use, copy, modify, merge, publish, |
10 | | * distribute, sublicense, and/or sell copies of the Software, and to |
11 | | * permit persons to whom the Software is furnished to do so, subject to |
12 | | * the following conditions: |
13 | | * |
14 | | * The above copyright notice and this permission notice shall be |
15 | | * included in all copies or substantial portions of the Software. |
16 | | * |
17 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
18 | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
19 | | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
20 | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
21 | | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
22 | | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
23 | | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
24 | | */ |
25 | | #include "ngtcp2_log.h" |
26 | | |
27 | | #include <stdio.h> |
28 | | #ifdef HAVE_UNISTD_H |
29 | | # include <unistd.h> |
30 | | #endif /* defined(HAVE_UNISTD_H) */ |
31 | | #include <assert.h> |
32 | | #include <string.h> |
33 | | |
34 | | #include "ngtcp2_str.h" |
35 | | #include "ngtcp2_vec.h" |
36 | | #include "ngtcp2_macro.h" |
37 | | #include "ngtcp2_conv.h" |
38 | | #include "ngtcp2_unreachable.h" |
39 | | #include "ngtcp2_net.h" |
40 | | |
41 | | void ngtcp2_log_init(ngtcp2_log *log, const ngtcp2_cid *scid, |
42 | | ngtcp2_printf log_printf, ngtcp2_tstamp ts, |
43 | 0 | void *user_data) { |
44 | 0 | if (scid) { |
45 | 0 | ngtcp2_encode_hex_cstr(log->scid, scid->data, scid->datalen); |
46 | 0 | } else { |
47 | 0 | log->scid[0] = '\0'; |
48 | 0 | } |
49 | 0 | log->log_printf = log_printf; |
50 | 0 | log->events = 0xFF; |
51 | 0 | log->ts = log->last_ts = ts; |
52 | 0 | log->user_data = user_data; |
53 | 0 | } |
54 | | |
55 | | /* |
56 | | * # Log header |
57 | | * |
58 | | * <LEVEL><TIMESTAMP> <SCID> <EVENT> |
59 | | * |
60 | | * <LEVEL>: |
61 | | * Log level. I=Info, W=Warning, E=Error |
62 | | * |
63 | | * <TIMESTAMP>: |
64 | | * Timestamp relative to ngtcp2_log.ts field in milliseconds |
65 | | * resolution. |
66 | | * |
67 | | * <SCID>: |
68 | | * Source Connection ID in hex string. |
69 | | * |
70 | | * <EVENT>: |
71 | | * Event. See ngtcp2_log_event. |
72 | | * |
73 | | * # Frame event |
74 | | * |
75 | | * <DIR> <PKN> <PKTNAME> <FRAMENAME>(<FRAMETYPE>) |
76 | | * |
77 | | * <DIR>: |
78 | | * Flow direction. tx=transmission, rx=reception |
79 | | * |
80 | | * <PKN>: |
81 | | * Packet number. |
82 | | * |
83 | | * <PKTNAME>: |
84 | | * Packet name. (e.g., Initial, Handshake, 1RTT) |
85 | | * |
86 | | * <FRAMENAME>: |
87 | | * Frame name. (e.g., STREAM, ACK, PING) |
88 | | * |
89 | | * <FRAMETYPE>: |
90 | | * Frame type in hex string. |
91 | | */ |
92 | | |
93 | | #define NGTCP2_LOG_PKT "%s %" PRId64 " %s" |
94 | | #define NGTCP2_LOG_TP "remote transport_parameters" |
95 | | |
96 | | #define NGTCP2_LOG_PKT_HD_FIELDS(DIR) (DIR), hd->pkt_num, strpkttype(hd) |
97 | | |
98 | 0 | static const char *strerrorcode(uint64_t error_code) { |
99 | 0 | switch (error_code) { |
100 | 0 | case NGTCP2_NO_ERROR: |
101 | 0 | return "NO_ERROR"; |
102 | 0 | case NGTCP2_INTERNAL_ERROR: |
103 | 0 | return "INTERNAL_ERROR"; |
104 | 0 | case NGTCP2_CONNECTION_REFUSED: |
105 | 0 | return "CONNECTION_REFUSED"; |
106 | 0 | case NGTCP2_FLOW_CONTROL_ERROR: |
107 | 0 | return "FLOW_CONTROL_ERROR"; |
108 | 0 | case NGTCP2_STREAM_LIMIT_ERROR: |
109 | 0 | return "STREAM_LIMIT_ERROR"; |
110 | 0 | case NGTCP2_STREAM_STATE_ERROR: |
111 | 0 | return "STREAM_STATE_ERROR"; |
112 | 0 | case NGTCP2_FINAL_SIZE_ERROR: |
113 | 0 | return "FINAL_SIZE_ERROR"; |
114 | 0 | case NGTCP2_FRAME_ENCODING_ERROR: |
115 | 0 | return "FRAME_ENCODING_ERROR"; |
116 | 0 | case NGTCP2_TRANSPORT_PARAMETER_ERROR: |
117 | 0 | return "TRANSPORT_PARAMETER_ERROR"; |
118 | 0 | case NGTCP2_CONNECTION_ID_LIMIT_ERROR: |
119 | 0 | return "CONNECTION_ID_LIMIT_ERROR"; |
120 | 0 | case NGTCP2_PROTOCOL_VIOLATION: |
121 | 0 | return "PROTOCOL_VIOLATION"; |
122 | 0 | case NGTCP2_INVALID_TOKEN: |
123 | 0 | return "INVALID_TOKEN"; |
124 | 0 | case NGTCP2_APPLICATION_ERROR: |
125 | 0 | return "APPLICATION_ERROR"; |
126 | 0 | case NGTCP2_CRYPTO_BUFFER_EXCEEDED: |
127 | 0 | return "CRYPTO_BUFFER_EXCEEDED"; |
128 | 0 | case NGTCP2_KEY_UPDATE_ERROR: |
129 | 0 | return "KEY_UPDATE_ERROR"; |
130 | 0 | case NGTCP2_AEAD_LIMIT_REACHED: |
131 | 0 | return "AEAD_LIMIT_REACHED"; |
132 | 0 | case NGTCP2_NO_VIABLE_PATH: |
133 | 0 | return "NO_VIABLE_PATH"; |
134 | 0 | case NGTCP2_VERSION_NEGOTIATION_ERROR: |
135 | 0 | return "VERSION_NEGOTIATION_ERROR"; |
136 | 0 | default: |
137 | 0 | if (0x100U <= error_code && error_code <= 0x1FFU) { |
138 | 0 | return "CRYPTO_ERROR"; |
139 | 0 | } |
140 | 0 | return "(unknown)"; |
141 | 0 | } |
142 | 0 | } |
143 | | |
144 | 0 | static const char *strapperrorcode(uint64_t app_error_code) { |
145 | 0 | (void)app_error_code; |
146 | 0 | return "(unknown)"; |
147 | 0 | } |
148 | | |
149 | 0 | static const char *strpkttype(const ngtcp2_pkt_hd *hd) { |
150 | 0 | switch (hd->type) { |
151 | 0 | case NGTCP2_PKT_INITIAL: |
152 | 0 | return "Initial"; |
153 | 0 | case NGTCP2_PKT_0RTT: |
154 | 0 | return "0RTT"; |
155 | 0 | case NGTCP2_PKT_HANDSHAKE: |
156 | 0 | return "Handshake"; |
157 | 0 | case NGTCP2_PKT_RETRY: |
158 | 0 | return "Retry"; |
159 | 0 | case NGTCP2_PKT_1RTT: |
160 | 0 | return "1RTT"; |
161 | 0 | case NGTCP2_PKT_VERSION_NEGOTIATION: |
162 | 0 | return "VN"; |
163 | 0 | case NGTCP2_PKT_STATELESS_RESET: |
164 | 0 | return "SR"; |
165 | 0 | default: |
166 | 0 | return "(unknown)"; |
167 | 0 | } |
168 | 0 | } |
169 | | |
170 | 0 | static const char *strpkttype_type_flags(uint8_t type, uint8_t flags) { |
171 | 0 | return strpkttype(&(ngtcp2_pkt_hd){ |
172 | 0 | .type = type, |
173 | 0 | .flags = flags, |
174 | 0 | }); |
175 | 0 | } |
176 | | |
177 | | static void log_fr_stream(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
178 | 0 | const ngtcp2_stream *fr, const char *dir) { |
179 | 0 | ngtcp2_log_infof_raw( |
180 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
181 | 0 | NGTCP2_LOG_PKT " STREAM(0x%02" PRIx64 ") id=0x%" PRIx64 |
182 | 0 | " fin=%d offset=%" PRIu64 " len=%" PRIu64 " uni=%d", |
183 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type | fr->flags, fr->stream_id, fr->fin, |
184 | 0 | fr->offset, ngtcp2_vec_len(fr->data, fr->datacnt), |
185 | 0 | (fr->stream_id & 0x2) != 0); |
186 | 0 | } |
187 | | |
188 | | static void log_fr_ack(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
189 | 0 | const ngtcp2_ack *fr, const char *dir) { |
190 | 0 | int64_t largest_ack, min_ack; |
191 | 0 | size_t i; |
192 | |
|
193 | 0 | ngtcp2_log_infof_raw( |
194 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
195 | 0 | NGTCP2_LOG_PKT " ACK(0x%02" PRIx64 ") largest_ack=%" PRId64 |
196 | 0 | " ack_delay=%" PRIu64 "(%" PRIu64 ") ack_range_count=%zu", |
197 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->largest_ack, |
198 | 0 | fr->ack_delay_unscaled / NGTCP2_MILLISECONDS, fr->ack_delay, fr->rangecnt); |
199 | |
|
200 | 0 | largest_ack = fr->largest_ack; |
201 | 0 | min_ack = fr->largest_ack - (int64_t)fr->first_ack_range; |
202 | |
|
203 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
204 | 0 | NGTCP2_LOG_PKT " ACK(0x%02" PRIx64 ") range=[%" PRId64 |
205 | 0 | "..%" PRId64 "] len=%" PRIu64, |
206 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, largest_ack, |
207 | 0 | min_ack, fr->first_ack_range); |
208 | |
|
209 | 0 | for (i = 0; i < fr->rangecnt; ++i) { |
210 | 0 | const ngtcp2_ack_range *range = &fr->ranges[i]; |
211 | 0 | largest_ack = min_ack - (int64_t)range->gap - 2; |
212 | 0 | min_ack = largest_ack - (int64_t)range->len; |
213 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
214 | 0 | NGTCP2_LOG_PKT " ACK(0x%02" PRIx64 ") range=[%" PRId64 |
215 | 0 | "..%" PRId64 "] gap=%" PRIu64 |
216 | 0 | " len=%" PRIu64, |
217 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, largest_ack, |
218 | 0 | min_ack, range->gap, range->len); |
219 | 0 | } |
220 | |
|
221 | 0 | if (fr->type == NGTCP2_FRAME_ACK_ECN) { |
222 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
223 | 0 | NGTCP2_LOG_PKT " ACK(0x%02" PRIx64 ") ect0=%" PRIu64 |
224 | 0 | " ect1=%" PRIu64 " ce=%" PRIu64, |
225 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->ecn.ect0, |
226 | 0 | fr->ecn.ect1, fr->ecn.ce); |
227 | 0 | } |
228 | 0 | } |
229 | | |
230 | | static void log_fr_padding(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
231 | 0 | const ngtcp2_padding *fr, const char *dir) { |
232 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
233 | 0 | NGTCP2_LOG_PKT " PADDING(0x%02" PRIx64 ") len=%zu", |
234 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->len); |
235 | 0 | } |
236 | | |
237 | | static void log_fr_reset_stream(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
238 | | const ngtcp2_reset_stream *fr, |
239 | 0 | const char *dir) { |
240 | 0 | ngtcp2_log_infof_raw( |
241 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
242 | 0 | NGTCP2_LOG_PKT " RESET_STREAM(0x%02" PRIx64 ") id=0x%" PRIx64 |
243 | 0 | " app_error_code=%s(0x%" PRIx64 ") final_size=%" PRIu64, |
244 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->stream_id, |
245 | 0 | strapperrorcode(fr->app_error_code), fr->app_error_code, fr->final_size); |
246 | 0 | } |
247 | | |
248 | | static void log_fr_connection_close(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
249 | | const ngtcp2_connection_close *fr, |
250 | 0 | const char *dir) { |
251 | 0 | char reason[256]; |
252 | 0 | size_t reasonlen = ngtcp2_min_size(sizeof(reason) - 1, fr->reasonlen); |
253 | |
|
254 | 0 | ngtcp2_log_infof_raw( |
255 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
256 | 0 | NGTCP2_LOG_PKT " CONNECTION_CLOSE(0x%02" PRIx64 ") error_code=%s(0x%" PRIx64 |
257 | 0 | ") " |
258 | 0 | "frame_type=0x%" PRIx64 " reason_len=%zu reason=[%s]", |
259 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, |
260 | 0 | fr->type == NGTCP2_FRAME_CONNECTION_CLOSE ? strerrorcode(fr->error_code) |
261 | 0 | : strapperrorcode(fr->error_code), |
262 | 0 | fr->error_code, fr->frame_type, fr->reasonlen, |
263 | 0 | ngtcp2_encode_printable_ascii_cstr(reason, fr->reason, reasonlen)); |
264 | 0 | } |
265 | | |
266 | | static void log_fr_max_data(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
267 | 0 | const ngtcp2_max_data *fr, const char *dir) { |
268 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
269 | 0 | NGTCP2_LOG_PKT " MAX_DATA(0x%02" PRIx64 |
270 | 0 | ") max_data=%" PRIu64, |
271 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->max_data); |
272 | 0 | } |
273 | | |
274 | | static void log_fr_max_stream_data(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
275 | | const ngtcp2_max_stream_data *fr, |
276 | 0 | const char *dir) { |
277 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
278 | 0 | NGTCP2_LOG_PKT " MAX_STREAM_DATA(0x%02" PRIx64 |
279 | 0 | ") id=0x%" PRIx64 |
280 | 0 | " max_stream_data=%" PRIu64, |
281 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->stream_id, |
282 | 0 | fr->max_stream_data); |
283 | 0 | } |
284 | | |
285 | | static void log_fr_max_streams(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
286 | 0 | const ngtcp2_max_streams *fr, const char *dir) { |
287 | 0 | ngtcp2_log_infof_raw( |
288 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
289 | 0 | NGTCP2_LOG_PKT " MAX_STREAMS(0x%02" PRIx64 ") max_streams=%" PRIu64, |
290 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->max_streams); |
291 | 0 | } |
292 | | |
293 | | static void log_fr_ping(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
294 | 0 | const ngtcp2_ping *fr, const char *dir) { |
295 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
296 | 0 | NGTCP2_LOG_PKT " PING(0x%02" PRIx64 ")", |
297 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type); |
298 | 0 | } |
299 | | |
300 | | static void log_fr_data_blocked(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
301 | | const ngtcp2_data_blocked *fr, |
302 | 0 | const char *dir) { |
303 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
304 | 0 | NGTCP2_LOG_PKT " DATA_BLOCKED(0x%02" PRIx64 |
305 | 0 | ") offset=%" PRIu64, |
306 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->offset); |
307 | 0 | } |
308 | | |
309 | | static void log_fr_stream_data_blocked(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
310 | | const ngtcp2_stream_data_blocked *fr, |
311 | 0 | const char *dir) { |
312 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
313 | 0 | NGTCP2_LOG_PKT " STREAM_DATA_BLOCKED(0x%02" PRIx64 |
314 | 0 | ") id=0x%" PRIx64 " offset=%" PRIu64, |
315 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->stream_id, |
316 | 0 | fr->offset); |
317 | 0 | } |
318 | | |
319 | | static void log_fr_streams_blocked(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
320 | | const ngtcp2_streams_blocked *fr, |
321 | 0 | const char *dir) { |
322 | 0 | ngtcp2_log_infof_raw( |
323 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
324 | 0 | NGTCP2_LOG_PKT " STREAMS_BLOCKED(0x%02" PRIx64 ") max_streams=%" PRIu64, |
325 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->max_streams); |
326 | 0 | } |
327 | | |
328 | | static void log_fr_new_connection_id(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
329 | | const ngtcp2_new_connection_id *fr, |
330 | 0 | const char *dir) { |
331 | 0 | char buf[sizeof(fr->token.data) * 2 + 1]; |
332 | 0 | char cid[sizeof(fr->cid.data) * 2 + 1]; |
333 | |
|
334 | 0 | ngtcp2_log_infof_raw( |
335 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
336 | 0 | NGTCP2_LOG_PKT " NEW_CONNECTION_ID(0x%02" PRIx64 ") seq=%" PRIu64 |
337 | 0 | " cid=0x%s retire_prior_to=%" PRIu64 |
338 | 0 | " stateless_reset_token=0x%s", |
339 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->seq, |
340 | 0 | ngtcp2_encode_hex_cstr(cid, fr->cid.data, fr->cid.datalen), |
341 | 0 | fr->retire_prior_to, |
342 | 0 | ngtcp2_encode_hex_cstr(buf, fr->token.data, sizeof(fr->token.data))); |
343 | 0 | } |
344 | | |
345 | | static void log_fr_stop_sending(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
346 | | const ngtcp2_stop_sending *fr, |
347 | 0 | const char *dir) { |
348 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
349 | 0 | NGTCP2_LOG_PKT " STOP_SENDING(0x%02" PRIx64 |
350 | 0 | ") id=0x%" PRIx64 |
351 | 0 | " app_error_code=%s(0x%" PRIx64 ")", |
352 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->stream_id, |
353 | 0 | strapperrorcode(fr->app_error_code), fr->app_error_code); |
354 | 0 | } |
355 | | |
356 | | static void log_fr_path_challenge(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
357 | | const ngtcp2_path_challenge *fr, |
358 | 0 | const char *dir) { |
359 | 0 | char buf[sizeof(fr->data.data) * 2 + 1]; |
360 | |
|
361 | 0 | ngtcp2_log_infof_raw( |
362 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
363 | 0 | NGTCP2_LOG_PKT " PATH_CHALLENGE(0x%02" PRIx64 ") data=0x%s", |
364 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, |
365 | 0 | ngtcp2_encode_hex_cstr(buf, fr->data.data, sizeof(fr->data.data))); |
366 | 0 | } |
367 | | |
368 | | static void log_fr_path_response(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
369 | | const ngtcp2_path_response *fr, |
370 | 0 | const char *dir) { |
371 | 0 | char buf[sizeof(fr->data.data) * 2 + 1]; |
372 | |
|
373 | 0 | ngtcp2_log_infof_raw( |
374 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
375 | 0 | NGTCP2_LOG_PKT " PATH_RESPONSE(0x%02" PRIx64 ") data=0x%s", |
376 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, |
377 | 0 | ngtcp2_encode_hex_cstr(buf, fr->data.data, sizeof(fr->data.data))); |
378 | 0 | } |
379 | | |
380 | | static void log_fr_crypto(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
381 | 0 | const ngtcp2_stream *fr, const char *dir) { |
382 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
383 | 0 | NGTCP2_LOG_PKT " CRYPTO(0x%02" PRIx64 ") offset=%" PRIu64 |
384 | 0 | " len=%" PRIu64, |
385 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->offset, |
386 | 0 | ngtcp2_vec_len(fr->data, fr->datacnt)); |
387 | 0 | } |
388 | | |
389 | | static void log_fr_new_token(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
390 | 0 | const ngtcp2_new_token *fr, const char *dir) { |
391 | | /* Show at most first 64 bytes of token. If token is longer than 64 |
392 | | bytes, log first 64 bytes and then append "*" */ |
393 | 0 | char buf[128 + 1 + 1]; |
394 | 0 | char *p; |
395 | |
|
396 | 0 | if (fr->tokenlen > 64) { |
397 | 0 | p = ngtcp2_encode_hex_cstr(buf, fr->token, 64); |
398 | 0 | p[128] = '*'; |
399 | 0 | p[129] = '\0'; |
400 | 0 | } else { |
401 | 0 | p = ngtcp2_encode_hex_cstr(buf, fr->token, fr->tokenlen); |
402 | 0 | } |
403 | |
|
404 | 0 | ngtcp2_log_infof_raw( |
405 | 0 | log, NGTCP2_LOG_EVENT_FRM, |
406 | 0 | NGTCP2_LOG_PKT " NEW_TOKEN(0x%02" PRIx64 ") token=0x%s len=%zu", |
407 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, p, fr->tokenlen); |
408 | 0 | } |
409 | | |
410 | | static void log_fr_retire_connection_id(ngtcp2_log *log, |
411 | | const ngtcp2_pkt_hd *hd, |
412 | | const ngtcp2_retire_connection_id *fr, |
413 | 0 | const char *dir) { |
414 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
415 | 0 | NGTCP2_LOG_PKT " RETIRE_CONNECTION_ID(0x%02" PRIx64 |
416 | 0 | ") seq=%" PRIu64, |
417 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, fr->seq); |
418 | 0 | } |
419 | | |
420 | | static void log_fr_handshake_done(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
421 | | const ngtcp2_handshake_done *fr, |
422 | 0 | const char *dir) { |
423 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
424 | 0 | NGTCP2_LOG_PKT " HANDSHAKE_DONE(0x%02" PRIx64 ")", |
425 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type); |
426 | 0 | } |
427 | | |
428 | | static void log_fr_datagram(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
429 | 0 | const ngtcp2_datagram *fr, const char *dir) { |
430 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_FRM, |
431 | 0 | NGTCP2_LOG_PKT " DATAGRAM(0x%02" PRIx64 ") len=%" PRIu64, |
432 | 0 | NGTCP2_LOG_PKT_HD_FIELDS(dir), fr->type, |
433 | 0 | ngtcp2_vec_len(fr->data, fr->datacnt)); |
434 | 0 | } |
435 | | |
436 | | static void log_fr(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
437 | 0 | const ngtcp2_frame *fr, const char *dir) { |
438 | 0 | switch (fr->hd.type) { |
439 | 0 | case NGTCP2_FRAME_STREAM: |
440 | 0 | log_fr_stream(log, hd, &fr->stream, dir); |
441 | 0 | break; |
442 | 0 | case NGTCP2_FRAME_ACK: |
443 | 0 | case NGTCP2_FRAME_ACK_ECN: |
444 | 0 | log_fr_ack(log, hd, &fr->ack, dir); |
445 | 0 | break; |
446 | 0 | case NGTCP2_FRAME_PADDING: |
447 | 0 | log_fr_padding(log, hd, &fr->padding, dir); |
448 | 0 | break; |
449 | 0 | case NGTCP2_FRAME_RESET_STREAM: |
450 | 0 | log_fr_reset_stream(log, hd, &fr->reset_stream, dir); |
451 | 0 | break; |
452 | 0 | case NGTCP2_FRAME_CONNECTION_CLOSE: |
453 | 0 | case NGTCP2_FRAME_CONNECTION_CLOSE_APP: |
454 | 0 | log_fr_connection_close(log, hd, &fr->connection_close, dir); |
455 | 0 | break; |
456 | 0 | case NGTCP2_FRAME_MAX_DATA: |
457 | 0 | log_fr_max_data(log, hd, &fr->max_data, dir); |
458 | 0 | break; |
459 | 0 | case NGTCP2_FRAME_MAX_STREAM_DATA: |
460 | 0 | log_fr_max_stream_data(log, hd, &fr->max_stream_data, dir); |
461 | 0 | break; |
462 | 0 | case NGTCP2_FRAME_MAX_STREAMS_BIDI: |
463 | 0 | case NGTCP2_FRAME_MAX_STREAMS_UNI: |
464 | 0 | log_fr_max_streams(log, hd, &fr->max_streams, dir); |
465 | 0 | break; |
466 | 0 | case NGTCP2_FRAME_PING: |
467 | 0 | log_fr_ping(log, hd, &fr->ping, dir); |
468 | 0 | break; |
469 | 0 | case NGTCP2_FRAME_DATA_BLOCKED: |
470 | 0 | log_fr_data_blocked(log, hd, &fr->data_blocked, dir); |
471 | 0 | break; |
472 | 0 | case NGTCP2_FRAME_STREAM_DATA_BLOCKED: |
473 | 0 | log_fr_stream_data_blocked(log, hd, &fr->stream_data_blocked, dir); |
474 | 0 | break; |
475 | 0 | case NGTCP2_FRAME_STREAMS_BLOCKED_BIDI: |
476 | 0 | case NGTCP2_FRAME_STREAMS_BLOCKED_UNI: |
477 | 0 | log_fr_streams_blocked(log, hd, &fr->streams_blocked, dir); |
478 | 0 | break; |
479 | 0 | case NGTCP2_FRAME_NEW_CONNECTION_ID: |
480 | 0 | log_fr_new_connection_id(log, hd, &fr->new_connection_id, dir); |
481 | 0 | break; |
482 | 0 | case NGTCP2_FRAME_STOP_SENDING: |
483 | 0 | log_fr_stop_sending(log, hd, &fr->stop_sending, dir); |
484 | 0 | break; |
485 | 0 | case NGTCP2_FRAME_PATH_CHALLENGE: |
486 | 0 | log_fr_path_challenge(log, hd, &fr->path_challenge, dir); |
487 | 0 | break; |
488 | 0 | case NGTCP2_FRAME_PATH_RESPONSE: |
489 | 0 | log_fr_path_response(log, hd, &fr->path_response, dir); |
490 | 0 | break; |
491 | 0 | case NGTCP2_FRAME_CRYPTO: |
492 | 0 | log_fr_crypto(log, hd, &fr->stream, dir); |
493 | 0 | break; |
494 | 0 | case NGTCP2_FRAME_NEW_TOKEN: |
495 | 0 | log_fr_new_token(log, hd, &fr->new_token, dir); |
496 | 0 | break; |
497 | 0 | case NGTCP2_FRAME_RETIRE_CONNECTION_ID: |
498 | 0 | log_fr_retire_connection_id(log, hd, &fr->retire_connection_id, dir); |
499 | 0 | break; |
500 | 0 | case NGTCP2_FRAME_HANDSHAKE_DONE: |
501 | 0 | log_fr_handshake_done(log, hd, &fr->handshake_done, dir); |
502 | 0 | break; |
503 | 0 | case NGTCP2_FRAME_DATAGRAM: |
504 | 0 | case NGTCP2_FRAME_DATAGRAM_LEN: |
505 | 0 | log_fr_datagram(log, hd, &fr->datagram, dir); |
506 | 0 | break; |
507 | 0 | default: |
508 | 0 | ngtcp2_unreachable(); |
509 | 0 | } |
510 | 0 | } |
511 | | |
512 | | void ngtcp2_log_rx_fr(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
513 | 0 | const ngtcp2_frame *fr) { |
514 | 0 | if (!log->log_printf || !(log->events & NGTCP2_LOG_EVENT_FRM)) { |
515 | 0 | return; |
516 | 0 | } |
517 | | |
518 | 0 | log_fr(log, hd, fr, "rx"); |
519 | 0 | } |
520 | | |
521 | | void ngtcp2_log_tx_fr(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
522 | 0 | const ngtcp2_frame *fr) { |
523 | 0 | if (!log->log_printf || !(log->events & NGTCP2_LOG_EVENT_FRM)) { |
524 | 0 | return; |
525 | 0 | } |
526 | | |
527 | 0 | log_fr(log, hd, fr, "tx"); |
528 | 0 | } |
529 | | |
530 | | void ngtcp2_log_rx_vn(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
531 | 0 | const uint32_t *sv, size_t nsv) { |
532 | 0 | size_t i; |
533 | |
|
534 | 0 | if (!log->log_printf || !(log->events & NGTCP2_LOG_EVENT_PKT)) { |
535 | 0 | return; |
536 | 0 | } |
537 | | |
538 | 0 | for (i = 0; i < nsv; ++i) { |
539 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_PKT, NGTCP2_LOG_PKT " v=0x%08x", |
540 | 0 | NGTCP2_LOG_PKT_HD_FIELDS("rx"), sv[i]); |
541 | 0 | } |
542 | 0 | } |
543 | | |
544 | 0 | void ngtcp2_log_rx_sr(ngtcp2_log *log, const ngtcp2_pkt_stateless_reset2 *sr) { |
545 | 0 | char buf[sizeof(sr->token.data) * 2 + 1]; |
546 | 0 | ngtcp2_pkt_hd shd; |
547 | 0 | ngtcp2_pkt_hd *hd = &shd; |
548 | |
|
549 | 0 | if (!log->log_printf || !(log->events & NGTCP2_LOG_EVENT_PKT)) { |
550 | 0 | return; |
551 | 0 | } |
552 | | |
553 | 0 | shd = (ngtcp2_pkt_hd){ |
554 | 0 | .type = NGTCP2_PKT_STATELESS_RESET, |
555 | 0 | }; |
556 | |
|
557 | 0 | ngtcp2_log_infof_raw( |
558 | 0 | log, NGTCP2_LOG_EVENT_PKT, NGTCP2_LOG_PKT " token=0x%s randlen=%zu", |
559 | 0 | NGTCP2_LOG_PKT_HD_FIELDS("rx"), |
560 | 0 | ngtcp2_encode_hex_cstr(buf, sr->token.data, sizeof(sr->token.data)), |
561 | 0 | sr->randlen); |
562 | 0 | } |
563 | | |
564 | | void ngtcp2_log_remote_tp(ngtcp2_log *log, |
565 | 0 | const ngtcp2_transport_params *params) { |
566 | 0 | char token[sizeof(params->stateless_reset_token) * 2 + 1]; |
567 | 0 | char addr[16 * 2 + 7 + 1]; |
568 | 0 | char cid[NGTCP2_MAX_CIDLEN * 2 + 1]; |
569 | 0 | size_t i; |
570 | 0 | const ngtcp2_sockaddr_in *sa_in; |
571 | 0 | const ngtcp2_sockaddr_in6 *sa_in6; |
572 | 0 | const uint8_t *p; |
573 | 0 | uint32_t version; |
574 | |
|
575 | 0 | if (!log->log_printf || !(log->events & NGTCP2_LOG_EVENT_CRY)) { |
576 | 0 | return; |
577 | 0 | } |
578 | | |
579 | 0 | if (params->stateless_reset_token_present) { |
580 | 0 | ngtcp2_log_infof_raw( |
581 | 0 | log, NGTCP2_LOG_EVENT_CRY, NGTCP2_LOG_TP " stateless_reset_token=0x%s", |
582 | 0 | ngtcp2_encode_hex_cstr(token, params->stateless_reset_token, |
583 | 0 | sizeof(params->stateless_reset_token))); |
584 | 0 | } |
585 | |
|
586 | 0 | if (params->preferred_addr_present) { |
587 | 0 | if (params->preferred_addr.ipv4_present) { |
588 | 0 | sa_in = ¶ms->preferred_addr.ipv4; |
589 | |
|
590 | 0 | ngtcp2_log_infof_raw( |
591 | 0 | log, NGTCP2_LOG_EVENT_CRY, |
592 | 0 | NGTCP2_LOG_TP " preferred_address.ipv4_addr=%s", |
593 | 0 | ngtcp2_encode_ipv4_cstr(addr, (const uint8_t *)&sa_in->sin_addr)); |
594 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
595 | 0 | NGTCP2_LOG_TP " preferred_address.ipv4_port=%u", |
596 | 0 | ngtcp2_ntohs(sa_in->sin_port)); |
597 | 0 | } |
598 | |
|
599 | 0 | if (params->preferred_addr.ipv6_present) { |
600 | 0 | sa_in6 = ¶ms->preferred_addr.ipv6; |
601 | |
|
602 | 0 | ngtcp2_log_infof_raw( |
603 | 0 | log, NGTCP2_LOG_EVENT_CRY, |
604 | 0 | NGTCP2_LOG_TP " preferred_address.ipv6_addr=%s", |
605 | 0 | ngtcp2_encode_ipv6_cstr(addr, (const uint8_t *)&sa_in6->sin6_addr)); |
606 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
607 | 0 | NGTCP2_LOG_TP " preferred_address.ipv6_port=%u", |
608 | 0 | ngtcp2_ntohs(sa_in6->sin6_port)); |
609 | 0 | } |
610 | |
|
611 | 0 | ngtcp2_log_infof_raw( |
612 | 0 | log, NGTCP2_LOG_EVENT_CRY, NGTCP2_LOG_TP " preferred_address.cid=0x%s", |
613 | 0 | ngtcp2_encode_hex_cstr(cid, params->preferred_addr.cid.data, |
614 | 0 | params->preferred_addr.cid.datalen)); |
615 | 0 | ngtcp2_log_infof_raw( |
616 | 0 | log, NGTCP2_LOG_EVENT_CRY, |
617 | 0 | NGTCP2_LOG_TP " preferred_address.stateless_reset_token=0x%s", |
618 | 0 | ngtcp2_encode_hex_cstr( |
619 | 0 | token, params->preferred_addr.stateless_reset_token, |
620 | 0 | sizeof(params->preferred_addr.stateless_reset_token))); |
621 | 0 | } |
622 | |
|
623 | 0 | if (params->original_dcid_present) { |
624 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
625 | 0 | NGTCP2_LOG_TP |
626 | 0 | " original_destination_connection_id=0x%s", |
627 | 0 | ngtcp2_encode_hex_cstr(cid, params->original_dcid.data, |
628 | 0 | params->original_dcid.datalen)); |
629 | 0 | } |
630 | |
|
631 | 0 | if (params->retry_scid_present) { |
632 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
633 | 0 | NGTCP2_LOG_TP " retry_source_connection_id=0x%s", |
634 | 0 | ngtcp2_encode_hex_cstr(cid, params->retry_scid.data, |
635 | 0 | params->retry_scid.datalen)); |
636 | 0 | } |
637 | |
|
638 | 0 | if (params->initial_scid_present) { |
639 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
640 | 0 | NGTCP2_LOG_TP " initial_source_connection_id=0x%s", |
641 | 0 | ngtcp2_encode_hex_cstr(cid, params->initial_scid.data, |
642 | 0 | params->initial_scid.datalen)); |
643 | 0 | } |
644 | |
|
645 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
646 | 0 | NGTCP2_LOG_TP |
647 | 0 | " initial_max_stream_data_bidi_local=%" PRIu64, |
648 | 0 | params->initial_max_stream_data_bidi_local); |
649 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
650 | 0 | NGTCP2_LOG_TP |
651 | 0 | " initial_max_stream_data_bidi_remote=%" PRIu64, |
652 | 0 | params->initial_max_stream_data_bidi_remote); |
653 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
654 | 0 | NGTCP2_LOG_TP " initial_max_stream_data_uni=%" PRIu64, |
655 | 0 | params->initial_max_stream_data_uni); |
656 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
657 | 0 | NGTCP2_LOG_TP " initial_max_data=%" PRIu64, |
658 | 0 | params->initial_max_data); |
659 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
660 | 0 | NGTCP2_LOG_TP " initial_max_streams_bidi=%" PRIu64, |
661 | 0 | params->initial_max_streams_bidi); |
662 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
663 | 0 | NGTCP2_LOG_TP " initial_max_streams_uni=%" PRIu64, |
664 | 0 | params->initial_max_streams_uni); |
665 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
666 | 0 | NGTCP2_LOG_TP " max_idle_timeout=%" PRIu64, |
667 | 0 | params->max_idle_timeout / NGTCP2_MILLISECONDS); |
668 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
669 | 0 | NGTCP2_LOG_TP " max_udp_payload_size=%" PRIu64, |
670 | 0 | params->max_udp_payload_size); |
671 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
672 | 0 | NGTCP2_LOG_TP " ack_delay_exponent=%" PRIu64, |
673 | 0 | params->ack_delay_exponent); |
674 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
675 | 0 | NGTCP2_LOG_TP " max_ack_delay=%" PRIu64, |
676 | 0 | params->max_ack_delay / NGTCP2_MILLISECONDS); |
677 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
678 | 0 | NGTCP2_LOG_TP " active_connection_id_limit=%" PRIu64, |
679 | 0 | params->active_connection_id_limit); |
680 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
681 | 0 | NGTCP2_LOG_TP " disable_active_migration=%d", |
682 | 0 | params->disable_active_migration); |
683 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
684 | 0 | NGTCP2_LOG_TP " max_datagram_frame_size=%" PRIu64, |
685 | 0 | params->max_datagram_frame_size); |
686 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
687 | 0 | NGTCP2_LOG_TP " grease_quic_bit=%d", |
688 | 0 | params->grease_quic_bit); |
689 | |
|
690 | 0 | if (params->version_info_present) { |
691 | 0 | ngtcp2_log_infof_raw(log, NGTCP2_LOG_EVENT_CRY, |
692 | 0 | NGTCP2_LOG_TP |
693 | 0 | " version_information.chosen_version=0x%08x", |
694 | 0 | params->version_info.chosen_version); |
695 | |
|
696 | 0 | assert(!(params->version_info.available_versionslen & 0x3)); |
697 | |
|
698 | 0 | for (i = 0, p = params->version_info.available_versions; |
699 | 0 | i < params->version_info.available_versionslen; |
700 | 0 | i += sizeof(uint32_t)) { |
701 | 0 | p = ngtcp2_get_uint32be(&version, p); |
702 | |
|
703 | 0 | ngtcp2_log_infof_raw( |
704 | 0 | log, NGTCP2_LOG_EVENT_CRY, |
705 | 0 | NGTCP2_LOG_TP " version_information.available_versions[%zu]=0x%08x", |
706 | 0 | i >> 2, version); |
707 | 0 | } |
708 | 0 | } |
709 | 0 | } |
710 | | |
711 | | void ngtcp2_log_pkt_lost(ngtcp2_log *log, int64_t pkt_num, uint8_t type, |
712 | 0 | uint8_t flags, ngtcp2_tstamp sent_ts) { |
713 | 0 | if (!log->log_printf || !(log->events & NGTCP2_LOG_EVENT_LDC)) { |
714 | 0 | return; |
715 | 0 | } |
716 | | |
717 | 0 | ngtcp2_log_infof(log, NGTCP2_LOG_EVENT_LDC, |
718 | 0 | "pkn=%" PRId64 " lost type=%s sent_ts=%" PRIu64, pkt_num, |
719 | 0 | strpkttype_type_flags(type, flags), sent_ts); |
720 | 0 | } |
721 | | |
722 | | static void log_pkt_hd(ngtcp2_log *log, const ngtcp2_pkt_hd *hd, |
723 | 0 | const char *dir) { |
724 | 0 | char dcid[sizeof(hd->dcid.data) * 2 + 1]; |
725 | 0 | char scid[sizeof(hd->scid.data) * 2 + 1]; |
726 | |
|
727 | 0 | if (!log->log_printf || !(log->events & NGTCP2_LOG_EVENT_PKT)) { |
728 | 0 | return; |
729 | 0 | } |
730 | | |
731 | 0 | if (hd->type == NGTCP2_PKT_1RTT) { |
732 | 0 | ngtcp2_log_infof( |
733 | 0 | log, NGTCP2_LOG_EVENT_PKT, "%s pkn=%" PRId64 " dcid=0x%s type=%s k=%d", |
734 | 0 | dir, hd->pkt_num, |
735 | 0 | ngtcp2_encode_hex_cstr(dcid, hd->dcid.data, hd->dcid.datalen), |
736 | 0 | strpkttype(hd), (hd->flags & NGTCP2_PKT_FLAG_KEY_PHASE) != 0); |
737 | 0 | } else { |
738 | 0 | ngtcp2_log_infof( |
739 | 0 | log, NGTCP2_LOG_EVENT_PKT, |
740 | 0 | "%s pkn=%" PRId64 " dcid=0x%s scid=0x%s version=0x%08x type=%s len=%zu", |
741 | 0 | dir, hd->pkt_num, |
742 | 0 | ngtcp2_encode_hex_cstr(dcid, hd->dcid.data, hd->dcid.datalen), |
743 | 0 | ngtcp2_encode_hex_cstr(scid, hd->scid.data, hd->scid.datalen), |
744 | 0 | hd->version, strpkttype(hd), hd->len); |
745 | 0 | } |
746 | 0 | } |
747 | | |
748 | 0 | void ngtcp2_log_rx_pkt_hd(ngtcp2_log *log, const ngtcp2_pkt_hd *hd) { |
749 | 0 | log_pkt_hd(log, hd, "rx"); |
750 | 0 | } |
751 | | |
752 | 0 | void ngtcp2_log_tx_pkt_hd(ngtcp2_log *log, const ngtcp2_pkt_hd *hd) { |
753 | 0 | log_pkt_hd(log, hd, "tx"); |
754 | 0 | } |
755 | | |
756 | 0 | uint64_t ngtcp2_log_timestamp(const ngtcp2_log *log) { |
757 | 0 | return (log->last_ts - log->ts) / NGTCP2_MILLISECONDS; |
758 | 0 | } |