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