test_parse_packet_in.c revision a74702c6
1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <stdint.h> 4#include <stdlib.h> 5#include <string.h> 6#include <sys/queue.h> 7 8#include "lsquic.h" 9#include "lsquic_mm.h" 10#include "lsquic_types.h" 11#include "lsquic_int_types.h" 12#include "lsquic_packet_common.h" 13#include "lsquic_parse.h" 14#include "lsquic_parse_common.h" 15#include "lsquic_packet_in.h" 16#include "lsquic_engine_public.h" 17#include "lsquic_version.h" 18 19 20struct parse_packet_in_test 21{ 22 int ppit_lineno; 23 /* Input */ 24 unsigned char ppit_buf[0x100]; 25 unsigned ppit_bufsz; 26 int ppit_is_server; 27 enum lsquic_version ppit_version; 28 /* Output */ 29 int ppit_retval; 30 int ppit_pi_flags; 31 uint64_t ppit_conn_id; 32 lsquic_packno_t ppit_packno; 33 unsigned short ppit_header_sz; 34 unsigned short ppit_data_sz; 35 unsigned char ppit_quic_ver; 36 unsigned char ppit_nonce; 37}; 38 39 40static const struct parse_packet_in_test tests[] = { 41 /* 42 * BIG-ENDIAN TESTS: 43 */ 44 { .ppit_lineno = __LINE__, 45 .ppit_buf = { 46 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION| 47 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 48 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 49 /* Version: */ 'Q', '0', '4', '3', 50 /* Packet #: */ 0x73, 51 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 52 }, 53 .ppit_bufsz = 1 + 8 + 4 + 1 + 7, 54 .ppit_is_server = 1, 55 .ppit_version = LSQVER_043, 56 .ppit_retval = 0, 57 .ppit_pi_flags = PI_CONN_ID, 58 .ppit_conn_id = 0x5500000000000000, 59 .ppit_packno = 0x73, 60 .ppit_header_sz = 1 + 8 + 4 + 1, 61 .ppit_data_sz = 1 + 8 + 4 + 1 + 7, 62 .ppit_quic_ver = 1 + 8, 63 .ppit_nonce = 0, 64 }, 65 66 { .ppit_lineno = __LINE__, 67 .ppit_buf = { 68 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION| 69 0x10 /* 2-byte packet number */| 70 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 71 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 72 /* Version: */ 'Q', '0', '4', '3', 73 /* Packet #: */ 0x73, 0x64, 74 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 75 }, 76 .ppit_bufsz = 1 + 8 + 4 + 2 + 7, 77 .ppit_is_server = 1, 78 .ppit_version = LSQVER_043, 79 .ppit_retval = 0, 80 .ppit_pi_flags = PI_CONN_ID, 81 .ppit_conn_id = 0x5500000000000000, 82 .ppit_packno = 0x7364, 83 .ppit_header_sz = 1 + 8 + 4 + 2, 84 .ppit_data_sz = 1 + 8 + 4 + 2 + 7, 85 .ppit_quic_ver = 1 + 8, 86 .ppit_nonce = 0, 87 }, 88 89 { .ppit_lineno = __LINE__, 90 .ppit_buf = { 91 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION| 92 0x20 /* 4-byte packet number */| 93 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 94 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 95 /* Version: */ 'Q', '0', '4', '3', 96 /* Packet #: */ 0x73, 0x64, 0x55, 0x46, 97 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 98 }, 99 .ppit_bufsz = 1 + 8 + 4 + 4 + 7, 100 .ppit_is_server = 1, 101 .ppit_version = LSQVER_043, 102 .ppit_retval = 0, 103 .ppit_pi_flags = PI_CONN_ID, 104 .ppit_conn_id = 0x5500000000000000, 105 .ppit_packno = 0x73645546, 106 .ppit_header_sz = 1 + 8 + 4 + 4, 107 .ppit_data_sz = 1 + 8 + 4 + 4 + 7, 108 .ppit_quic_ver = 1 + 8, 109 .ppit_nonce = 0, 110 }, 111 112 { .ppit_lineno = __LINE__, 113 .ppit_buf = { 114 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION| 115 0x30 /* 6-byte packet number */| 116 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 117 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 118 /* Version: */ 'Q', '0', '4', '3', 119 /* Packet #: */ 0x73, 0x64, 0x55, 0x46, 0x37, 0x28, 120 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 121 }, 122 .ppit_bufsz = 1 + 8 + 4 + 6 + 7, 123 .ppit_is_server = 1, 124 .ppit_version = LSQVER_043, 125 .ppit_retval = 0, 126 .ppit_pi_flags = PI_CONN_ID, 127 .ppit_conn_id = 0x5500000000000000, 128 .ppit_packno = 0x736455463728, 129 .ppit_header_sz = 1 + 8 + 4 + 6, 130 .ppit_data_sz = 1 + 8 + 4 + 6 + 7, 131 .ppit_quic_ver = 1 + 8, 132 .ppit_nonce = 0, 133 }, 134 135 { .ppit_lineno = __LINE__, /* Same as above minus connection ID */ 136 .ppit_buf = { 137 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION, 138 /* Version: */ 'Q', '0', '4', '3', 139 /* Packet #: */ 0x73, 140 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 141 }, 142 .ppit_bufsz = 1 + 0 + 4 + 1 + 7, 143 .ppit_is_server = 1, 144 .ppit_version = LSQVER_043, 145 .ppit_retval = 0, 146 .ppit_pi_flags = 0, 147 .ppit_conn_id = 0, 148 .ppit_packno = 0x73, 149 .ppit_header_sz = 1 + 0 + 4 + 1, 150 .ppit_data_sz = 1 + 0 + 4 + 1 + 7, 151 .ppit_quic_ver = 1 + 0, 152 .ppit_nonce = 0, 153 }, 154 155 { .ppit_lineno = __LINE__, /* Same as above minus version */ 156 .ppit_buf = { 157 /* Flags: */ 0, 158 /* Packet #: */ 0x73, 159 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 160 }, 161 .ppit_bufsz = 1 + 0 + 0 + 1 + 7, 162 .ppit_is_server = 1, 163 .ppit_version = LSQVER_043, 164 .ppit_retval = 0, 165 .ppit_pi_flags = 0, 166 .ppit_conn_id = 0, 167 .ppit_packno = 0x73, 168 .ppit_header_sz = 1 + 0 + 0 + 1, 169 .ppit_data_sz = 1 + 0 + 0 + 1 + 7, 170 .ppit_quic_ver = 0, 171 .ppit_nonce = 0, 172 }, 173 174 { .ppit_lineno = __LINE__, 175 .ppit_buf = { 176 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION| 177 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 178 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 179 /* Version: */ 'Q', '0', '4', '3', 180 /* Packet #: */ 0x73, 181 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 182 }, 183 .ppit_bufsz = 1 + 8 + 4, 184 .ppit_is_server = 1, 185 .ppit_version = LSQVER_043, 186 .ppit_retval = -1, 187 }, 188 189 { .ppit_lineno = __LINE__, 190 .ppit_buf = { 191 /* Flags: */ PACKET_PUBLIC_FLAGS_NONCE| 192 0x10 /* 2-byte packet number */| 193 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 194 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 195 /* Nonce: */ 000, 001, 002, 003, 004, 005, 006, 007, 196 010, 011, 012, 013, 014, 015, 016, 017, 197 020, 021, 022, 023, 024, 025, 026, 027, 198 030, 031, 032, 033, 034, 035, 036, 037, 199 /* Packet #: */ 0x73, 0x64, 200 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 201 }, 202 .ppit_bufsz = 1 + 8 + 32+ 2 + 7, 203 .ppit_is_server = 0, 204 .ppit_version = LSQVER_043, 205 .ppit_retval = 0, 206 .ppit_pi_flags = PI_CONN_ID, 207 .ppit_conn_id = 0x5500000000000000, 208 .ppit_packno = 0x7364, 209 .ppit_header_sz = 1 + 8 + 32+ 2, 210 .ppit_data_sz = 1 + 8 + 32+ 2 + 7, 211 .ppit_quic_ver = 0, 212 .ppit_nonce = 1 + 8, 213 }, 214 215 { .ppit_lineno = __LINE__, 216 .ppit_buf = { 217 /* Flags: */ PACKET_PUBLIC_FLAGS_NONCE| 218 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 219 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 220 /* Nonce: */ 000, 001, 002, 003, 004, 005, 006, 007, 221 010, 011, 012, 013, 014, 015, 016, 017, 222 020, 021, 022, 023, 024, 025, 026, 027, 223 030, 031, 032, 033, 034, 035, 036, 037, 224 /* Packet #: */ 0x73, 225 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 226 }, 227 .ppit_bufsz = 1 + 8 + 32+ 1 + 7, 228 .ppit_is_server = 0, 229 .ppit_version = LSQVER_043, 230 .ppit_retval = 0, 231 .ppit_pi_flags = PI_CONN_ID, 232 .ppit_conn_id = 0x5500000000000000, 233 .ppit_packno = 0x73, 234 .ppit_header_sz = 1 + 8 + 32+ 1, 235 .ppit_data_sz = 1 + 8 + 32+ 1 + 7, 236 .ppit_quic_ver = 0, 237 .ppit_nonce = 1 + 8, 238 }, 239 240 { .ppit_lineno = __LINE__, 241 .ppit_buf = { 242 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION| 243 0x20 /* 4-byte packet number */| 244 PACKET_PUBLIC_FLAGS_NONCE| /* Nonce flag is ignored by server */ 245 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 246 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 247 /* Version: */ 'Q', '0', '4', '3', 248 /* Packet #: */ 0x73, 0x64, 0x55, 0x46, 249 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 250 }, 251 .ppit_bufsz = 1 + 8 + 4 + 4 + 7, 252 .ppit_is_server = 1, 253 .ppit_version = LSQVER_043, 254 .ppit_retval = 0, 255 .ppit_pi_flags = PI_CONN_ID, 256 .ppit_conn_id = 0x5500000000000000, 257 .ppit_packno = 0x73645546, 258 .ppit_header_sz = 1 + 8 + 4 + 4, 259 .ppit_data_sz = 1 + 8 + 4 + 4 + 7, 260 .ppit_quic_ver = 1 + 8, 261 .ppit_nonce = 0, 262 }, 263 264 { .ppit_lineno = __LINE__, 265 .ppit_buf = { 266 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION| 267 PACKET_PUBLIC_FLAGS_NONCE| /* Nonce flag is ignored by server */ 268 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 269 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 270 /* Version: */ 'Q', '0', '4', '3', 271 /* Packet #: */ 0x73, 272 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 273 }, 274 .ppit_bufsz = 1 + 8 + 4 + 1 + 7, 275 .ppit_is_server = 1, 276 .ppit_version = LSQVER_043, 277 .ppit_retval = 0, 278 .ppit_pi_flags = PI_CONN_ID, 279 .ppit_conn_id = 0x5500000000000000, 280 .ppit_packno = 0x73, 281 .ppit_header_sz = 1 + 8 + 4 + 1, 282 .ppit_data_sz = 1 + 8 + 4 + 1 + 7, 283 .ppit_quic_ver = 1 + 8, 284 .ppit_nonce = 0, 285 }, 286 287 { .ppit_lineno = __LINE__, 288 .ppit_buf = { 289 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION| 290 0x30 /* 6-byte packet number */| 291 PACKET_PUBLIC_FLAGS_NONCE| /* Nonce flag is ignored by server */ 292 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 293 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 294 /* Version: */ 'Q', '0', '4', '3', 295 /* Packet #: */ 0x73, 0x64, 0x55, 0x46, 0x37, 0x28, 296 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 297 }, 298 .ppit_bufsz = 1 + 8 + 4 + 6 + 7, 299 .ppit_is_server = 1, 300 .ppit_version = LSQVER_043, 301 .ppit_retval = 0, 302 .ppit_pi_flags = PI_CONN_ID, 303 .ppit_conn_id = 0x5500000000000000, 304 .ppit_packno = 0x736455463728, 305 .ppit_header_sz = 1 + 8 + 4 + 6, 306 .ppit_data_sz = 1 + 8 + 4 + 6 + 7, 307 .ppit_quic_ver = 1 + 8, 308 .ppit_nonce = 0, 309 }, 310 311 { .ppit_lineno = __LINE__, 312 .ppit_buf = { 313 /* Flags: */ PACKET_PUBLIC_FLAGS_VERSION| 314 PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID, 315 /* CID: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 316 /* Versions: */ 'Q', '0', '4', '0', 317 'Q', '0', '4', '3', 318 }, 319 .ppit_bufsz = 1 + 8 + 8, 320 .ppit_is_server = 0, 321 .ppit_version = LSQVER_043, 322 .ppit_retval = 0, 323 .ppit_pi_flags = PI_CONN_ID, 324 .ppit_conn_id = 0x5500000000000000, 325 .ppit_packno = 0, 326 .ppit_header_sz = 1 + 8 + 8, 327 .ppit_data_sz = 1 + 8 + 8, 328 .ppit_quic_ver = 1 + 8, 329 .ppit_nonce = 0, 330 }, 331 332 { .ppit_lineno = __LINE__, 333 .ppit_buf = { 334 /* Flags: */ 0x40, 335 /* CID: */ 0x01, 0x02, 0x03, 0x04, 0x50, 0x60, 0x70, 0x80, 336 /* Packet number: */0x9B, 337 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 338 }, 339 .ppit_version = LSQVER_046, 340 .ppit_retval = 0, 341 .ppit_is_server = 1, 342 .ppit_pi_flags = PI_CONN_ID, 343 .ppit_conn_id = 0x8070605004030201, 344 .ppit_packno = 0x9B, 345 .ppit_header_sz = 1 + 8 + 1, 346 .ppit_data_sz = 1 + 8 + 1 + 7, 347 .ppit_bufsz = 1 + 8 + 1 + 7, 348 .ppit_quic_ver = 0, 349 .ppit_nonce = 0, 350 }, 351 352 { .ppit_lineno = __LINE__, 353 .ppit_buf = { 354 /* Flags: */ 0x43, 355 /* CID: */ 0x01, 0x02, 0x03, 0x04, 0x50, 0x60, 0x70, 0x80, 356 /* Packet number: */0x9B, 0x03, 0x02, 0x01, 357 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 358 }, 359 .ppit_version = LSQVER_046, 360 .ppit_retval = 0, 361 .ppit_packno = 0x9B030201, 362 .ppit_is_server = 1, 363 .ppit_header_sz = 1 + 8 + 4, 364 .ppit_bufsz = 1 + 8 + 4 + 7, 365 .ppit_data_sz = 1 + 8 + 4 + 7, 366 .ppit_pi_flags = PI_CONN_ID, 367 .ppit_conn_id = 0x8070605004030201, 368 .ppit_quic_ver = 0, 369 .ppit_nonce = 0, 370 }, 371 372 /* TODO: check invalid type in finish() -- convert the latter to return 373 * status instead of being void function. 374 */ 375#if 0 376 { .ppit_lineno = __LINE__, 377 .ppit_buf = { 378 /* Flags: */ 0x30 379 | 0x3 /* <--- Invalid type */, 380 /* CID: */ 0x01, 0x02, 0x03, 0x04, 0x50, 0x60, 0x70, 0x80, 381 /* Packet number: */0x9B, 382 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 383 }, 384 .ppit_bufsz = 1 + 8 + 1 + 7, 385 .ppit_is_server = 1, 386 .ppit_version = LSQVER_044, 387 .ppit_retval = -1, 388 }, 389#endif 390 391 { .ppit_lineno = __LINE__, 392 .ppit_buf = { 393 /* Type: */ 0x83 /* Initial */, 394 /* Version: */ 'Q', '0', '4', '6', 395 /* DCIL/SCIL: */ 0x5 /* DCIL */ << 4 | 0x0 /* SCIL */, 396 /* CID: */ 0x01, 0x02, 0x03, 0x04, 0x50, 0x60, 0x70, 0x80, 397 /* Packet number: */0x21, 0x22, 0x23, 0x34, 398 /* Payload: */ 'P', 'A', 'Y', 'L', 'O', 'A', 'D', 399 }, 400 .ppit_bufsz = 1 + 4 + 1 + 8 + 4 + 7, 401 .ppit_is_server = 1, 402 .ppit_version = LSQVER_046, 403 .ppit_retval = 0, 404 .ppit_pi_flags = PI_CONN_ID, 405 .ppit_conn_id = 0x8070605004030201, 406 .ppit_packno = 0x21222334, 407 .ppit_header_sz = 1 + 4 + 1 + 8 + 4, 408 .ppit_data_sz = 1 + 4 + 1 + 8 + 4 + 7, 409 .ppit_quic_ver = 1, 410 .ppit_nonce = 0, 411 }, 412 413}; 414 415 416static void 417run_ppi_test (struct lsquic_mm *mm, const struct parse_packet_in_test *ppit) 418{ 419 int s; 420 lsquic_packet_in_t *packet_in; 421 struct packin_parse_state ppstate; 422 423 packet_in = lsquic_mm_get_packet_in(mm); 424 packet_in->pi_data = lsquic_mm_get_packet_in_buf(mm, 1370); 425 packet_in->pi_flags |= PI_OWN_DATA; 426 memcpy(packet_in->pi_data, ppit->ppit_buf, ppit->ppit_bufsz); 427 428 /* Server should be able to differentiate different header formats 429 * because it expect the connection ID to be there, while the client 430 * needs help. 431 */ 432 if (ppit->ppit_is_server && 433 /* In addition, some tests verify parsing of GQUIC packets in 434 * server mode where there is no connection ID. This is for 435 * completeness and does not represent a real-life scenario, 436 * as the server will always require the client to send the 437 * connection ID. 438 */ 439 !(!(ppit->ppit_pi_flags & PI_CONN_ID) 440 && ppit->ppit_version < LSQVER_046)) 441 s = lsquic_parse_packet_in_server_begin(packet_in, ppit->ppit_bufsz, 442 ppit->ppit_is_server, 8, &ppstate); 443 else 444 if (ppit->ppit_version < LSQVER_046) 445 s = lsquic_gquic_parse_packet_in_begin(packet_in, ppit->ppit_bufsz, 446 ppit->ppit_is_server, -1 /* GQUIC does not use it */, &ppstate); 447 else if (ppit->ppit_version == LSQVER_046) 448 s = lsquic_Q046_parse_packet_in_begin(packet_in, ppit->ppit_bufsz, 449 ppit->ppit_is_server, 8, &ppstate); 450 else 451 s = lsquic_ietf_v1_parse_packet_in_begin(packet_in, ppit->ppit_bufsz, 452 ppit->ppit_is_server, 8, &ppstate); 453 454 assert(s == ppit->ppit_retval); 455 if (0 == s) 456 { 457 const struct parse_funcs *pf; 458 if (ppit->ppit_quic_ver && ppit->ppit_is_server /* Server packets 459 with version are version negotiation packets. */) 460 { 461 uint32_t tag; 462 enum lsquic_version ver; 463 assert(packet_in->pi_quic_ver); 464 memcpy(&tag, packet_in->pi_data + packet_in->pi_quic_ver, 4); 465 ver = lsquic_tag2ver(tag); 466 assert((enum lsquic_version) -1 != ver); 467 assert(ver == ppit->ppit_version); 468 } 469 pf = select_pf_by_ver(ppit->ppit_version); 470 pf->pf_parse_packet_in_finish(packet_in, &ppstate); 471 } 472 473 if (0 == s) 474 { 475 if (ppit->ppit_conn_id) 476 { 477 lsquic_cid_t cid; 478 memset(&cid, 0, sizeof(cid)); 479 cid.len = sizeof(ppit->ppit_conn_id);; 480 memcpy(cid.idbuf, &ppit->ppit_conn_id, sizeof(ppit->ppit_conn_id)); 481 assert(LSQUIC_CIDS_EQ(&packet_in->pi_conn_id, &cid)); 482 } 483 484 assert((packet_in->pi_flags & PI_CONN_ID) == (ppit->ppit_pi_flags & PI_CONN_ID)); 485 assert(packet_in->pi_packno == ppit->ppit_packno); 486 assert(packet_in->pi_header_sz == ppit->ppit_header_sz); 487 assert(packet_in->pi_data_sz == ppit->ppit_data_sz); 488 assert(packet_in->pi_quic_ver == ppit->ppit_quic_ver); 489 assert(packet_in->pi_nonce == ppit->ppit_nonce); 490 if (ppit->ppit_nonce) 491 assert(lsquic_packet_in_nonce(packet_in)); 492 else 493 assert(!lsquic_packet_in_nonce(packet_in)); 494 } 495 496 lsquic_mm_put_packet_in(mm, packet_in); 497} 498 499 500int 501main (void) 502{ 503 struct lsquic_mm mm; 504 unsigned i; 505 506 lsquic_mm_init(&mm); 507 508 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) 509 run_ppi_test(&mm, &tests[i]); 510 511 lsquic_mm_cleanup(&mm); 512 return 0; 513} 514