lsquic_parse_gquic_be.c revision c51ce338
1/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * lsquic_parse_gquic_be.c -- Parsing functions specific to big-endian 4 * (Q039 and higher) GQUIC. 5 */ 6 7#include <assert.h> 8#include <inttypes.h> 9#include <errno.h> 10#include <stdlib.h> 11#include <string.h> 12#include <sys/queue.h> 13#include <sys/types.h> 14 15#include "lsquic_types.h" 16#include "lsquic_alarmset.h" 17#include "lsquic_packet_common.h" 18#include "lsquic_packet_in.h" 19#include "lsquic_parse.h" 20#include "lsquic_rechist.h" 21#include "lsquic_sfcw.h" 22#include "lsquic_stream.h" 23#include "lsquic_mm.h" 24#include "lsquic_malo.h" 25#include "lsquic_version.h" 26#include "lsquic.h" 27#include "lsquic_parse_gquic_be.h" /* Include to catch mismatches */ 28 29#define LSQUIC_LOGGER_MODULE LSQLM_PARSE 30#include "lsquic_logger.h" 31 32 33/* read 16 bits(2 bytes) time, unit: us */ 34uint64_t 35gquic_be_read_float_time16 (const void *mem) 36{ 37 uint16_t val; 38 READ_UINT(val, 16, mem, 2); 39 uint64_t temp = val; 40 uint16_t exp = (temp >> 11) & 0x1F; 41 if (0 == exp) 42 return temp; 43 else 44 { 45 --exp; 46 temp &= 0x7FF; 47 temp |= 0x800; 48 return temp << exp; 49 } 50} 51 52 53void 54gquic_be_write_float_time16 (lsquic_time_t time_us, void *mem) 55{ 56 uint16_t ret = 0; 57 uint16_t high, i; 58 59 if (time_us < ((uint64_t)1 << 11)) 60 ret = time_us; 61 else if(time_us > 0x3FFC0000000) 62 ret = 0xFFFF; 63 else 64 { 65 high = 0; 66 for (i = 16; i > 0; i /= 2) 67 { 68 if (time_us >= (uint64_t)1 << (11 + i)) 69 { 70 high |= i; 71 time_us >>= i; 72 } 73 } 74 ret = time_us + (high << 11); 75 } 76#if __BYTE_ORDER == __LITTLE_ENDIAN 77 ret = bswap_16(ret); 78#endif 79 memcpy(mem, (void *)&ret, 2); 80} 81 82 83/* Parse out packet number */ 84void 85gquic_be_parse_packet_in_finish (lsquic_packet_in_t *packet_in, 86 struct packin_parse_state *state) 87{ 88 lsquic_packno_t packno; 89 if (state->pps_nbytes) 90 { 91 READ_UINT(packno, 64, state->pps_p, state->pps_nbytes); 92 packet_in->pi_packno = packno; 93 } 94} 95 96 97int 98gquic_be_gen_ver_nego_pkt (unsigned char *buf, size_t bufsz, uint64_t conn_id, 99 unsigned version_bitmask) 100{ 101 int sz; 102 unsigned char *p = buf; 103 unsigned char *const pend = p + bufsz; 104 105 CHECK_SPACE(1, p, pend); 106 *p = PACKET_PUBLIC_FLAGS_VERSION | PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID; 107 ++p; 108 109 CHECK_SPACE(8, p, pend); 110 memcpy(p, &conn_id, 8); 111 p += 8; 112 113 sz = gen_ver_tags(p, pend - p, version_bitmask); 114 if (sz < 0) 115 return -1; 116 117 return p + sz - buf; 118} 119 120 121int 122gquic_be_gen_reg_pkt_header (unsigned char *buf, size_t bufsz, const lsquic_cid_t *conn_id, 123 const lsquic_ver_tag_t *ver, const unsigned char *nonce, 124 lsquic_packno_t packno, enum lsquic_packno_bits bits) 125{ 126 unsigned packnum_len, header_len; 127 unsigned char *p; 128 129 packnum_len = packno_bits2len(bits); 130 131 header_len = 1 + (!!conn_id << 3) + (!!ver << 2) + ((!!nonce) << 5) 132 + packnum_len; 133 if (header_len > bufsz) 134 { 135 errno = ENOBUFS; 136 return -1; 137 } 138 139 p = buf; 140 141 *p = (!!conn_id << 3) 142 | (bits << 4) 143 | ((!!nonce) << 2) 144 | !!ver; 145 ++p; 146 147 if (conn_id) 148 { 149 memcpy(p, conn_id , sizeof(*conn_id)); 150 p += sizeof(*conn_id); 151 } 152 153 if (ver) 154 { 155 memcpy(p, ver, 4); 156 p += 4; 157 } 158 159 if (nonce) 160 { 161 memcpy(p, nonce , 32); 162 p += 32; 163 } 164 165#if __BYTE_ORDER == __LITTLE_ENDIAN 166 packno = bswap_64(packno); 167#endif 168 memcpy(p, (unsigned char *) &packno + 8 - packnum_len, packnum_len); 169 p += packnum_len; 170 171 assert(p - buf == (intptr_t) header_len); 172 173 return header_len; 174} 175 176 177int 178gquic_be_gen_stream_frame (unsigned char *buf, size_t buf_len, uint32_t stream_id, 179 uint64_t offset, gsf_fin_f gsf_fin, gsf_size_f gsf_size, 180 gsf_read_f gsf_read, void *stream) 181{ 182 /* 1fdoooss */ 183 unsigned slen, olen, dlen; 184 unsigned char *p = buf + 1; 185 int fin; 186 187 /* ss: Stream ID length: 1, 2, 3, or 4 bytes */ 188 slen = (stream_id > 0x0000FF) 189 + (stream_id > 0x00FFFF) 190 + (stream_id > 0xFFFFFF) 191 + 1; 192 193 /* ooo: Offset length: 0, 2, 3, 4, 5, 6, 7, or 8 bytes */ 194 olen = (offset >= (1ULL << 56)) 195 + (offset >= (1ULL << 48)) 196 + (offset >= (1ULL << 40)) 197 + (offset >= (1ULL << 32)) 198 + (offset >= (1ULL << 24)) 199 + (offset >= (1ULL << 16)) 200 + ((offset > 0) << 1); 201 202 fin = gsf_fin(stream); 203 if (!fin) 204 { 205 unsigned size, n_avail; 206 uint16_t nr; 207 208 size = gsf_size(stream); 209 n_avail = buf_len - (p + slen + olen - buf); 210 211 /* If we cannot fill remaining buffer, we need to include data 212 * length. 213 */ 214 dlen = (size < n_avail) << 1; 215 n_avail -= dlen; 216 217 CHECK_SPACE(1 + olen + slen + dlen + 218 + 1 /* We need to write at least 1 byte */, buf, buf + buf_len); 219 220#if __BYTE_ORDER == __LITTLE_ENDIAN 221 stream_id = bswap_32(stream_id); 222#endif 223 memcpy(p, (unsigned char *) &stream_id + 4 - slen, slen); 224 p += slen; 225 226#if __BYTE_ORDER == __LITTLE_ENDIAN 227 offset = bswap_64(offset); 228#endif 229 memcpy(p, (unsigned char *) &offset + 8 - olen, olen); 230 p += olen; 231 232 /* Read as much as we can */ 233 nr = gsf_read(stream, p + dlen, n_avail, &fin); 234 assert(nr != 0); 235 236 if (dlen) 237 { 238 uint16_t nr_copy = nr; 239#if __BYTE_ORDER == __LITTLE_ENDIAN 240 nr_copy = bswap_16(nr_copy); 241#endif 242 memcpy(p, &nr_copy, 2); 243 } 244 245 p += dlen + nr; 246 } 247 else 248 { 249 dlen = 2; 250 CHECK_SPACE(1 + slen + olen + 2, buf, buf + buf_len); 251#if __BYTE_ORDER == __LITTLE_ENDIAN 252 stream_id = bswap_32(stream_id); 253#endif 254 memcpy(p, (unsigned char *) &stream_id + 4 - slen, slen); 255 p += slen; 256#if __BYTE_ORDER == __LITTLE_ENDIAN 257 offset = bswap_64(offset); 258#endif 259 memcpy(p, (unsigned char *) &offset + 8 - olen, olen); 260 p += olen; 261 memset(p, 0, 2); 262 p += 2; 263 } 264 265 /* Convert slen to bit representation: 0 - 3: */ 266 slen -= 1; 267 assert(slen <= 3); 268 269 /* Convert olen to bit representation: 0 - 7: */ 270 olen += !olen; 271 olen -= 1; 272 assert(olen <= 7); 273 274 buf[0] = 0x80 275 | (fin << 6) 276 | (dlen << 4) 277 | (olen << 2) 278 | slen 279 ; 280 return p - buf; 281} 282 283 284/* return parsed (used) buffer length */ 285int 286gquic_be_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz, 287 stream_frame_t *stream_frame) 288{ 289 /* 1fdoooss */ 290 const unsigned char *p = buf; 291 const unsigned char *const pend = p + rem_packet_sz; 292 293 CHECK_SPACE(1, p, pend); 294 const char type = *p++; 295 296 const unsigned data_len = (type >> 4) & 2; 297 const unsigned offset_len = ((type >> 2) & 7) + 1 - !((type >> 2) & 7); 298 const unsigned stream_id_len = 1 + (type & 3); 299 const unsigned need = data_len + offset_len + stream_id_len; 300 CHECK_SPACE(need, p, pend); 301 302 memset(stream_frame, 0, sizeof(*stream_frame)); 303 304 stream_frame->data_frame.df_fin = (type >> 6) & 1; 305 306 memcpy((unsigned char *) &stream_frame->stream_id + 4 - stream_id_len, p, 307 stream_id_len); 308 309#if __BYTE_ORDER == __LITTLE_ENDIAN 310 stream_frame->stream_id = bswap_32(stream_frame->stream_id); 311#endif 312 p += stream_id_len; 313 314 memcpy((unsigned char *) &stream_frame->data_frame.df_offset 315 + 8 - offset_len, p, offset_len); 316#if __BYTE_ORDER == __LITTLE_ENDIAN 317 stream_frame->data_frame.df_offset = 318 bswap_64(stream_frame->data_frame.df_offset); 319#endif 320 p += offset_len; 321 322 if (data_len) 323 { 324 memcpy(&stream_frame->data_frame.df_size, p, data_len); 325#if __BYTE_ORDER == __LITTLE_ENDIAN 326 stream_frame->data_frame.df_size = 327 bswap_16(stream_frame->data_frame.df_size); 328#endif 329 p += data_len; 330 CHECK_SPACE(stream_frame->data_frame.df_size, p, pend); 331 stream_frame->data_frame.df_data = p; 332 p += stream_frame->data_frame.df_size; 333 } 334 else 335 { 336 stream_frame->data_frame.df_size = pend - p; 337 stream_frame->data_frame.df_data = p; 338 p = pend; 339 } 340 341 /* From the spec: "A stream frame must always have either non-zero 342 * data length or the FIN bit set.' 343 */ 344 if (!(stream_frame->data_frame.df_size || 345 stream_frame->data_frame.df_fin)) 346 return -1; 347 348 assert(p <= pend); 349 350 return p - (unsigned char *) buf; 351} 352 353 354/* This is a special function: it is used to extract the largest observed 355 * packet number from ACK frame that we ourselves generated. This allows 356 * us to skip some checks. 357 */ 358lsquic_packno_t 359gquic_be_parse_ack_high (const unsigned char *buf, size_t buf_len) 360{ 361 unsigned char type; 362 unsigned largest_obs_len; 363 lsquic_packno_t packno; 364 365 type = buf[0]; 366 largest_obs_len = twobit_to_1246((type >> 2) & 3); 367 assert(parse_frame_type_gquic_Q035_thru_Q039(type) == QUIC_FRAME_ACK); 368 assert(buf_len >= 1 + largest_obs_len); 369 READ_UINT(packno, 64, buf + 1, largest_obs_len); 370 return packno; 371} 372 373 374/* Return parsed (used) buffer length. 375 * If parsing failed, negative value is returned. 376 */ 377int 378gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len, ack_info_t *ack) 379{ 380 /* 01nullmm */ 381 lsquic_packno_t tmp_packno; 382 const unsigned char type = buf[0]; 383 const unsigned char *p = buf + 1; 384 const unsigned char *const pend = buf + buf_len; 385 386 assert((type & 0xC0) == 0x40); /* We're passed correct frame type */ 387 388 const int ack_block_len = twobit_to_1246(type & 3); /* mm */ 389 const int largest_obs_len = twobit_to_1246((type >> 2) & 3); /* ll */ 390 391 CHECK_SPACE(largest_obs_len, p , pend); 392 393 READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len); 394 p += largest_obs_len; 395 396 CHECK_SPACE(2, p , pend); 397 ack->lack_delta = gquic_be_read_float_time16(p); 398 p += 2; 399 400 unsigned n_blocks; 401 if (type & 0x20) 402 { 403 CHECK_SPACE(1, p , pend); 404 n_blocks = *p; 405 ++p; 406 } 407 else 408 n_blocks = 0; 409 410 CHECK_SPACE(ack_block_len, p , pend); 411 READ_UINT(tmp_packno, 64, p, ack_block_len); 412 ack->ranges[0].low = ack->ranges[0].high - tmp_packno + 1; 413 p += ack_block_len; 414 415 if (n_blocks) 416 { 417 CHECK_SPACE((ack_block_len + 1) * n_blocks, p , pend); 418 unsigned i, n, gap; 419 for (i = 0, n = 1, gap = 0; i < n_blocks; ++i) 420 { 421 uint64_t length; 422 gap += *p; 423 READ_UINT(length, 64, p + 1, ack_block_len); 424 p += 1 + ack_block_len; 425 if (length) 426 { 427 ack->ranges[n].high = ack->ranges[n - 1].low - gap - 1; 428 ack->ranges[n].low = ack->ranges[n].high - length + 1; 429 ++n; 430 gap = 0; 431 } 432 } 433 ack->n_ranges = n; 434 } 435 else 436 ack->n_ranges = 1; 437 438 CHECK_SPACE(1, p , pend); 439 ack->n_timestamps = *p; 440 ++p; 441 442 if (ack->n_timestamps) 443 { 444#if LSQUIC_PARSE_ACK_TIMESTAMPS 445 CHECK_SPACE(5, p , pend); 446 ack->timestamps[0].packet_delta = *p++; 447 memcpy(&ack->timestamps[0].delta_usec, p, 4); 448 p += 4; 449 unsigned i; 450 for (i = 1; i < ack->n_timestamps; ++i) 451 { 452 CHECK_SPACE(3, p , pend); 453 ack->timestamps[i].packet_delta = *p++; 454 uint64_t delta_time = read_float_time16(p); 455 p += 2; 456 ack->timestamps[i].delta_usec = 457 ack->timestamps[i - 1].delta_usec + delta_time; 458 } 459#else 460 unsigned timestamps_size = 5 + 3 * (ack->n_timestamps - 1); 461 CHECK_SPACE(timestamps_size, p, pend); 462 p += timestamps_size; 463#endif 464 } 465 466 assert(p <= pend); 467 468 return p - (unsigned char *) buf; 469} 470 471 472int 473gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len, 474 lsquic_packno_t cur_packno, enum lsquic_packno_bits bits, 475 lsquic_packno_t least_unacked_packno) 476{ 477 lsquic_packno_t delta; 478 unsigned packnum_len = packno_bits2len(bits); 479 480 if (buf_len >= 1 + packnum_len) 481 { 482 *buf = 0x06; 483 delta = cur_packno - least_unacked_packno; 484#if __BYTE_ORDER == __LITTLE_ENDIAN 485 delta = bswap_64(delta); 486#endif 487 memcpy(buf + 1, (unsigned char *) &delta + 8 - packnum_len, 488 packnum_len); 489 return 1 + packnum_len; 490 } 491 else 492 return -1; 493} 494 495 496int 497gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len, 498 lsquic_packno_t cur_packno, enum lsquic_packno_bits bits, 499 lsquic_packno_t *least_unacked) 500{ 501 lsquic_packno_t delta; 502 unsigned packnum_len = packno_bits2len(bits); 503 504 if (buf_len >= 1 + packnum_len) 505 { 506 READ_UINT(delta, 64, buf + 1, packnum_len); 507 *least_unacked = cur_packno - delta; 508 return 1 + packnum_len; 509 } 510 else 511 return -1; 512} 513 514 515int 516gquic_be_skip_stop_waiting_frame (size_t buf_len, enum lsquic_packno_bits bits) 517{ 518 unsigned packnum_len = packno_bits2len(bits); 519 if (buf_len >= 1 + packnum_len) 520 return 1 + packnum_len; 521 else 522 return -1; 523} 524 525 526int 527gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len, uint32_t stream_id, 528 uint64_t offset) 529{ 530 if (buf_len < QUIC_WUF_SZ) 531 return -1; 532 533 *buf = 0x04; 534#if __BYTE_ORDER == __LITTLE_ENDIAN 535 stream_id = bswap_32(stream_id); 536#endif 537 memcpy(buf + 1, (unsigned char *) &stream_id, 4); 538#if __BYTE_ORDER == __LITTLE_ENDIAN 539 offset = bswap_64(offset); 540#endif 541 memcpy(buf + 1 + 4, (unsigned char *) &offset, 8); 542 return QUIC_WUF_SZ; 543} 544 545 546int 547gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len, 548 uint32_t *stream_id, uint64_t *offset) 549{ 550 if (buf_len < QUIC_WUF_SZ) 551 return -1; 552 553 READ_UINT(*stream_id, 32, buf + 1, 4); 554 READ_UINT(*offset, 64, buf + 1 + 4, 8); 555 return QUIC_WUF_SZ; 556} 557 558 559int 560gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len, uint32_t stream_id) 561{ 562 if (buf_len < QUIC_BLOCKED_FRAME_SZ) 563 return -1; 564 565 *buf = 0x05; 566#if __BYTE_ORDER == __LITTLE_ENDIAN 567 stream_id = bswap_32(stream_id); 568#endif 569 memcpy(buf + 1, &stream_id, 4); 570 return QUIC_BLOCKED_FRAME_SZ; 571} 572 573 574int 575gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len, 576 uint32_t *stream_id) 577{ 578 if (buf_len < QUIC_BLOCKED_FRAME_SZ) 579 return -1; 580 581 READ_UINT(*stream_id, 32, buf + 1, 4); 582 return QUIC_BLOCKED_FRAME_SZ; 583} 584 585 586int 587gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len, uint32_t stream_id, 588 uint64_t offset, uint32_t error_code) 589{ 590 unsigned char *p = buf; 591 if (buf_len < QUIC_RST_STREAM_SZ) 592 return -1; 593 594 *p = 0x01; 595 ++p; 596#if __BYTE_ORDER == __LITTLE_ENDIAN 597 stream_id = bswap_32(stream_id); 598#endif 599 memcpy(p, &stream_id, 4); 600 p += 4; 601#if __BYTE_ORDER == __LITTLE_ENDIAN 602 offset = bswap_64(offset); 603#endif 604 memcpy(p, &offset, 8); 605 p += 8; 606#if __BYTE_ORDER == __LITTLE_ENDIAN 607 error_code = bswap_32(error_code); 608#endif 609 memcpy(p, &error_code, 4); 610 p += 4; 611 return p - buf; 612} 613 614 615int 616gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len, uint32_t *stream_id, 617 uint64_t *offset, uint32_t *error_code) 618{ 619 if (buf_len < QUIC_RST_STREAM_SZ) 620 return -1; 621 622 READ_UINT(*stream_id, 32, buf + 1, 4); 623 READ_UINT(*offset, 64, buf + 1 + 4, 8); 624 READ_UINT(*error_code, 32, buf + 1 + 4 + 8, 4); 625 return QUIC_RST_STREAM_SZ; 626} 627 628 629int 630gquic_be_gen_ping_frame (unsigned char *buf, int buf_len) 631{ 632 if (buf_len > 0) 633 { 634 buf[0] = 0x07; 635 return 1; 636 } 637 else 638 return -1; 639} 640 641 642int 643gquic_be_gen_connect_close_frame (unsigned char *buf, int buf_len, uint32_t error_code, 644 const char *reason, int reason_len) 645{ 646 unsigned char *p = buf; 647 if (buf_len < 7) 648 return -1; 649 650 *p = 0x02; 651 ++p; 652#if __BYTE_ORDER == __LITTLE_ENDIAN 653 error_code = bswap_32(error_code); 654#endif 655 memcpy(p, &error_code, 4); 656 p += 4; 657#if __BYTE_ORDER == __LITTLE_ENDIAN 658 const uint16_t copy = bswap_16(reason_len); 659 memcpy(p, ©, 2); 660#else 661 memcpy(p, &reason_len, 2); 662#endif 663 p += 2; 664 memcpy(p, reason, reason_len); 665 p += reason_len; 666 if (buf_len < p - buf) 667 return -2; 668 669 return p - buf; 670} 671 672 673int 674gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len, 675 uint32_t *error_code, uint16_t *reason_len, uint8_t *reason_offset) 676{ 677 if (buf_len < 7) 678 return -1; 679 680 READ_UINT(*error_code, 32, buf + 1, 4); 681 READ_UINT(*reason_len, 16, buf + 1 + 4, 2); 682 *reason_offset = 7; 683 if (buf_len < 7u + *reason_len) 684 return -2; 685 686 return 7 + *reason_len; 687} 688 689 690int 691gquic_be_gen_goaway_frame(unsigned char *buf, size_t buf_len, uint32_t error_code, 692 uint32_t last_good_stream_id, const char *reason, 693 size_t reason_len) 694{ 695 unsigned char *p = buf; 696 if (buf_len < QUIC_GOAWAY_FRAME_SZ + reason_len) 697 return -1; 698 699 *p = 0x03; 700 ++p; 701#if __BYTE_ORDER == __LITTLE_ENDIAN 702 error_code = bswap_32(error_code); 703#endif 704 memcpy(p, &error_code, 4); 705 p += 4; 706#if __BYTE_ORDER == __LITTLE_ENDIAN 707 last_good_stream_id = bswap_32(last_good_stream_id); 708#endif 709 memcpy(p, &last_good_stream_id, 4); 710 p += 4; 711#if __BYTE_ORDER == __LITTLE_ENDIAN 712 uint16_t copy = bswap_16(reason_len); 713 memcpy(p, ©, 2); 714#else 715 memcpy(p, &reason_len, 2); 716#endif 717 p += 2; 718 if (reason_len) 719 { 720 memcpy(p, reason, reason_len); 721 p += reason_len; 722 } 723 724 return p - buf; 725} 726 727 728/* the reason is buf + *reason_offset, length is *reason_length */ 729int 730gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len, 731 uint32_t *error_code, uint32_t *last_good_stream_id, 732 uint16_t *reason_length, const char **reason) 733{ 734 if (buf_len < QUIC_GOAWAY_FRAME_SZ) 735 return -1; 736 737 READ_UINT(*error_code, 32, buf + 1, 4); 738 READ_UINT(*last_good_stream_id, 32, buf + 1 + 4, 4); 739 READ_UINT(*reason_length, 16, buf + 1 + 4 + 4, 2); 740 if (*reason_length) 741 { 742 if ((int)buf_len < QUIC_GOAWAY_FRAME_SZ + *reason_length) 743 return -2; 744 *reason = (const char *) buf + QUIC_GOAWAY_FRAME_SZ; 745 } 746 else 747 *reason = NULL; 748 749 return QUIC_GOAWAY_FRAME_SZ + *reason_length; 750} 751 752 753/* Returns number of bytes written or -1 on failure */ 754/* This function makes an assumption that there is at least one range */ 755int 756gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz, 757 gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next, 758 gaf_rechist_largest_recv_f rechist_largest_recv, 759 void *rechist, lsquic_time_t now, int *has_missing) 760{ 761 lsquic_packno_t tmp_packno; 762 const struct lsquic_packno_range *const first = rechist_first(rechist); 763 if (!first) 764 { 765 errno = EINVAL; 766 return -1; 767 } 768 769 /* Copy values from the first range, because the memory the pointer 770 * points to may change: 771 */ 772 const lsquic_packno_t first_low = first->low, first_high = first->high; 773 774 unsigned char *p = outbuf; 775 unsigned char *const type = p; 776 unsigned char *const end = p + outbuf_sz; 777 778#define AVAIL() (end - p) 779 780#define CHECKOUT(sz) do { \ 781 if ((intptr_t) (sz) > AVAIL()) { \ 782 errno = ENOBUFS; \ 783 return -1; \ 784 } \ 785} while (0) 786 787 CHECKOUT(1); 788 ++p; 789 790 /* 01nullmm */ 791 *type = 0x40; 792 793 unsigned largest_acked_len, ack_block_len, bits; 794 795 /* Calculate largest ACKed len and set `ll' bits: */ 796 const lsquic_packno_t maxno = first_high; 797 bits = (maxno >= (1ULL << 8)) 798 + (maxno >= (1ULL << 16)) 799 + (maxno >= (1ULL << 32)); 800 largest_acked_len = (1 << bits) - ((maxno >= (1ULL << 32)) << 1); 801 *type |= bits << 2; 802 803 /* Calculate largest ACK block length and set `mm' bits: */ 804 unsigned n_ranges = 0; 805 lsquic_packno_t maxdiff = 0; 806 const struct lsquic_packno_range *range; 807 for (range = rechist_first(rechist); range; range = rechist_next(rechist)) 808 { 809 ++n_ranges; 810 const lsquic_packno_t diff = range->high - range->low + 1; 811 if (diff > maxdiff) 812 maxdiff = diff; 813 } 814 bits = (maxdiff >= (1ULL << 8)) 815 + (maxdiff >= (1ULL << 16)) 816 + (maxdiff >= (1ULL << 32)); 817 ack_block_len = (1 << bits) - ((maxdiff >= (1ULL << 32)) << 1); 818 *type |= bits; 819 820 CHECKOUT(largest_acked_len); 821 tmp_packno = maxno; 822#if __BYTE_ORDER == __LITTLE_ENDIAN 823 tmp_packno = bswap_64(maxno); 824#endif 825 memcpy(p, (unsigned char *) &tmp_packno + 8 - largest_acked_len, 826 largest_acked_len); 827 p += largest_acked_len; 828 829 CHECKOUT(2); 830 lsquic_time_t diff = now - rechist_largest_recv(rechist); 831 gquic_be_write_float_time16(diff, p); 832 LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, diff, 833 *(uint16_t*)p); 834 p += 2; 835 836 if (n_ranges > 1) 837 { 838 *has_missing = 1; 839 *type |= 0x20; 840 /* We need to write out at least one range */ 841 CHECKOUT(2 * (1 + ack_block_len)); 842 unsigned char *const n_ranges_p = p; /* Set this later */ 843 lsquic_packno_t diff = maxno - first_low + 1; 844#if __BYTE_ORDER == __LITTLE_ENDIAN 845 diff = bswap_64(diff); 846#endif 847 memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len, 848 ack_block_len); 849 p += ack_block_len + 1; 850 /* Write out ack blocks until one of the following occurs: 851 * 1. We run out of intervals. 852 * 2. We run out of room. 853 * 3. We run out of highest possible number of ACK blocks (0xFF). 854 */ 855 range = rechist_first(rechist); 856 lsquic_packno_t gap = 0; 857 n_ranges = 0; 858 do { 859 if (0 == gap) 860 { 861 const lsquic_packno_t prev_low = range->low; 862 range = rechist_next(rechist); 863 if (!range) 864 break; 865 gap = prev_low - range->high - 1; 866 } 867 if (gap >= 0x100) 868 { 869 *p = 0xFF; 870 gap -= 0xFF; 871 memset(p + 1, 0, ack_block_len); 872 } 873 else 874 { 875 *p = gap; 876 gap = 0; 877 diff = range->high - range->low + 1; 878#if __BYTE_ORDER == __LITTLE_ENDIAN 879 diff = bswap_64(diff); 880#endif 881 memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len, 882 ack_block_len); 883 } 884 p += ack_block_len + 1; 885 ++n_ranges; 886 } while (n_ranges < 0xFF && 887 AVAIL() >= (intptr_t) ack_block_len + 1 + 1 /* timestamp byte */); 888 *n_ranges_p = n_ranges; 889 } 890 else 891 { 892 *has_missing = 0; 893 CHECKOUT(ack_block_len); 894 lsquic_packno_t diff = maxno - first_low + 1; 895#if __BYTE_ORDER == __LITTLE_ENDIAN 896 diff = bswap_64(diff); 897#endif 898 memcpy(p, (unsigned char *) &diff + 8 - ack_block_len, ack_block_len); 899 p += ack_block_len; 900 } 901 902 /* We do not generate timestamp list because the reference implementation 903 * does not use them. When that changes, we will start sending timestamps 904 * over. 905 */ 906 CHECKOUT(1); 907 *p = 0; 908 ++p; 909 910 return p - (unsigned char *) outbuf; 911 912#undef CHECKOUT 913} 914 915 916const struct parse_funcs lsquic_parse_funcs_gquic_Q039 = 917{ 918 .pf_gen_ver_nego_pkt = gquic_be_gen_ver_nego_pkt, 919 .pf_gen_reg_pkt_header = gquic_be_gen_reg_pkt_header, 920 .pf_parse_packet_in_finish = gquic_be_parse_packet_in_finish, 921 .pf_gen_stream_frame = gquic_be_gen_stream_frame, 922 .pf_calc_stream_frame_header_sz = calc_stream_frame_header_sz_gquic, 923 .pf_parse_stream_frame_header_sz = parse_stream_frame_header_sz_gquic, 924 .pf_parse_stream_frame = gquic_be_parse_stream_frame, 925 .pf_parse_ack_frame = gquic_be_parse_ack_frame, 926 .pf_parse_ack_high = gquic_be_parse_ack_high, 927 .pf_gen_ack_frame = gquic_be_gen_ack_frame, 928 .pf_gen_stop_waiting_frame = gquic_be_gen_stop_waiting_frame, 929 .pf_parse_stop_waiting_frame = gquic_be_parse_stop_waiting_frame, 930 .pf_skip_stop_waiting_frame = gquic_be_skip_stop_waiting_frame, 931 .pf_gen_window_update_frame = gquic_be_gen_window_update_frame, 932 .pf_parse_window_update_frame = gquic_be_parse_window_update_frame, 933 .pf_gen_blocked_frame = gquic_be_gen_blocked_frame, 934 .pf_parse_blocked_frame = gquic_be_parse_blocked_frame, 935 .pf_gen_rst_frame = gquic_be_gen_rst_frame, 936 .pf_parse_rst_frame = gquic_be_parse_rst_frame, 937 .pf_gen_connect_close_frame = gquic_be_gen_connect_close_frame, 938 .pf_parse_connect_close_frame = gquic_be_parse_connect_close_frame, 939 .pf_gen_goaway_frame = gquic_be_gen_goaway_frame, 940 .pf_parse_goaway_frame = gquic_be_parse_goaway_frame, 941 .pf_gen_ping_frame = gquic_be_gen_ping_frame, 942#ifndef NDEBUG 943 .pf_write_float_time16 = gquic_be_write_float_time16, 944 .pf_read_float_time16 = gquic_be_read_float_time16, 945#endif 946 .pf_parse_frame_type = parse_frame_type_gquic_Q035_thru_Q039, 947 .pf_turn_on_fin = lsquic_turn_on_fin_Q035_thru_Q039, 948}; 949