lsquic_parse_gquic_be.c revision 10c492f0
1/* Copyright (c) 2017 - 2018 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 370static int 371parse_ack_frame_without_blocks (const unsigned char *buf, size_t buf_len, 372 ack_info_t *ack) 373{ 374 /* 01nullmm */ 375 lsquic_packno_t tmp_packno; 376 const unsigned char type = buf[0]; 377 const unsigned char *p = buf + 1; 378 const unsigned char *const pend = buf + buf_len; 379 380 const int ack_block_len = twobit_to_1246(type & 3); /* mm */ 381 const int largest_obs_len = twobit_to_1246((type >> 2) & 3); /* ll */ 382 383 CHECK_SPACE(largest_obs_len + 2 + ack_block_len + 1, p, pend); 384 385 READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len); 386 p += largest_obs_len; 387 388 ack->lack_delta = gquic_be_read_float_time16(p); 389 p += 2; 390 391 READ_UINT(tmp_packno, 64, p, ack_block_len); 392 ack->ranges[0].low = ack->ranges[0].high - tmp_packno + 1; 393 p += ack_block_len; 394 395 ack->n_ranges = 1; 396 397 ack->n_timestamps = *p; 398 ++p; 399 400 if (ack->n_timestamps) 401 { 402 unsigned timestamps_size = 5 + 3 * (ack->n_timestamps - 1); 403 CHECK_SPACE(timestamps_size, p, pend); 404 p += timestamps_size; 405 } 406 407 assert(p <= pend); 408 409 return p - (unsigned char *) buf; 410} 411 412 413static int 414parse_ack_frame_with_blocks (const unsigned char *buf, size_t buf_len, ack_info_t *ack) 415{ 416 /* 01nullmm */ 417 lsquic_packno_t tmp_packno; 418 const unsigned char type = buf[0]; 419 const unsigned char *p = buf + 1; 420 const unsigned char *const pend = buf + buf_len; 421 422 assert((type & 0xC0) == 0x40); /* We're passed correct frame type */ 423 424 const int ack_block_len = twobit_to_1246(type & 3); /* mm */ 425 const int largest_obs_len = twobit_to_1246((type >> 2) & 3); /* ll */ 426 427 CHECK_SPACE(largest_obs_len + 2 + 1 + ack_block_len, p, pend); 428 429 READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len); 430 p += largest_obs_len; 431 432 ack->lack_delta = gquic_be_read_float_time16(p); 433 p += 2; 434 435 unsigned n_blocks; 436 CHECK_SPACE(1, p , pend); 437 n_blocks = *p; 438 ++p; 439 440 READ_UINT(tmp_packno, 64, p, ack_block_len); 441 ack->ranges[0].low = ack->ranges[0].high - tmp_packno + 1; 442 p += ack_block_len; 443 444 CHECK_SPACE((ack_block_len + 1) * n_blocks + /* timestamp count: */ 1, 445 p , pend); 446 unsigned i, n, gap; 447 for (i = 0, n = 1, gap = 0; i < n_blocks; ++i) 448 { 449 uint64_t length; 450 gap += *p; 451 READ_UINT(length, 64, p + 1, ack_block_len); 452 p += 1 + ack_block_len; 453 if (length) 454 { 455 ack->ranges[n].high = ack->ranges[n - 1].low - gap - 1; 456 ack->ranges[n].low = ack->ranges[n].high - length + 1; 457 ++n; 458 gap = 0; 459 } 460 } 461 ack->n_ranges = n; 462 463 ack->n_timestamps = *p; 464 ++p; 465 466 if (ack->n_timestamps) 467 { 468#if LSQUIC_PARSE_ACK_TIMESTAMPS 469 CHECK_SPACE(5, p , pend); 470 ack->timestamps[0].packet_delta = *p++; 471 memcpy(&ack->timestamps[0].delta_usec, p, 4); 472 p += 4; 473 unsigned i; 474 for (i = 1; i < ack->n_timestamps; ++i) 475 { 476 CHECK_SPACE(3, p , pend); 477 ack->timestamps[i].packet_delta = *p++; 478 uint64_t delta_time = read_float_time16(p); 479 p += 2; 480 ack->timestamps[i].delta_usec = 481 ack->timestamps[i - 1].delta_usec + delta_time; 482 } 483#else 484 unsigned timestamps_size = 5 + 3 * (ack->n_timestamps - 1); 485 CHECK_SPACE(timestamps_size, p, pend); 486 p += timestamps_size; 487#endif 488 } 489 490 assert(p <= pend); 491 492 return p - (unsigned char *) buf; 493} 494 495 496/* Return parsed (used) buffer length. 497 * If parsing failed, negative value is returned. 498 */ 499int 500gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len, ack_info_t *ack) 501{ 502 if (!(buf[0] & 0x20)) 503 return parse_ack_frame_without_blocks(buf, buf_len, ack); 504 else 505 return parse_ack_frame_with_blocks(buf, buf_len, ack); 506} 507 508 509int 510gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len, 511 lsquic_packno_t cur_packno, enum lsquic_packno_bits bits, 512 lsquic_packno_t least_unacked_packno) 513{ 514 lsquic_packno_t delta; 515 unsigned packnum_len = packno_bits2len(bits); 516 517 if (buf_len >= 1 + packnum_len) 518 { 519 *buf = 0x06; 520 delta = cur_packno - least_unacked_packno; 521#if __BYTE_ORDER == __LITTLE_ENDIAN 522 delta = bswap_64(delta); 523#endif 524 memcpy(buf + 1, (unsigned char *) &delta + 8 - packnum_len, 525 packnum_len); 526 return 1 + packnum_len; 527 } 528 else 529 return -1; 530} 531 532 533int 534gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len, 535 lsquic_packno_t cur_packno, enum lsquic_packno_bits bits, 536 lsquic_packno_t *least_unacked) 537{ 538 lsquic_packno_t delta; 539 unsigned packnum_len = packno_bits2len(bits); 540 541 if (buf_len >= 1 + packnum_len) 542 { 543 READ_UINT(delta, 64, buf + 1, packnum_len); 544 *least_unacked = cur_packno - delta; 545 return 1 + packnum_len; 546 } 547 else 548 return -1; 549} 550 551 552int 553gquic_be_skip_stop_waiting_frame (size_t buf_len, enum lsquic_packno_bits bits) 554{ 555 unsigned packnum_len = packno_bits2len(bits); 556 if (buf_len >= 1 + packnum_len) 557 return 1 + packnum_len; 558 else 559 return -1; 560} 561 562 563int 564gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len, uint32_t stream_id, 565 uint64_t offset) 566{ 567 if (buf_len < QUIC_WUF_SZ) 568 return -1; 569 570 *buf = 0x04; 571#if __BYTE_ORDER == __LITTLE_ENDIAN 572 stream_id = bswap_32(stream_id); 573#endif 574 memcpy(buf + 1, (unsigned char *) &stream_id, 4); 575#if __BYTE_ORDER == __LITTLE_ENDIAN 576 offset = bswap_64(offset); 577#endif 578 memcpy(buf + 1 + 4, (unsigned char *) &offset, 8); 579 return QUIC_WUF_SZ; 580} 581 582 583int 584gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len, 585 uint32_t *stream_id, uint64_t *offset) 586{ 587 if (buf_len < QUIC_WUF_SZ) 588 return -1; 589 590 READ_UINT(*stream_id, 32, buf + 1, 4); 591 READ_UINT(*offset, 64, buf + 1 + 4, 8); 592 return QUIC_WUF_SZ; 593} 594 595 596int 597gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len, uint32_t stream_id) 598{ 599 if (buf_len < QUIC_BLOCKED_FRAME_SZ) 600 return -1; 601 602 *buf = 0x05; 603#if __BYTE_ORDER == __LITTLE_ENDIAN 604 stream_id = bswap_32(stream_id); 605#endif 606 memcpy(buf + 1, &stream_id, 4); 607 return QUIC_BLOCKED_FRAME_SZ; 608} 609 610 611int 612gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len, 613 uint32_t *stream_id) 614{ 615 if (buf_len < QUIC_BLOCKED_FRAME_SZ) 616 return -1; 617 618 READ_UINT(*stream_id, 32, buf + 1, 4); 619 return QUIC_BLOCKED_FRAME_SZ; 620} 621 622 623int 624gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len, uint32_t stream_id, 625 uint64_t offset, uint32_t error_code) 626{ 627 unsigned char *p = buf; 628 if (buf_len < QUIC_RST_STREAM_SZ) 629 return -1; 630 631 *p = 0x01; 632 ++p; 633#if __BYTE_ORDER == __LITTLE_ENDIAN 634 stream_id = bswap_32(stream_id); 635#endif 636 memcpy(p, &stream_id, 4); 637 p += 4; 638#if __BYTE_ORDER == __LITTLE_ENDIAN 639 offset = bswap_64(offset); 640#endif 641 memcpy(p, &offset, 8); 642 p += 8; 643#if __BYTE_ORDER == __LITTLE_ENDIAN 644 error_code = bswap_32(error_code); 645#endif 646 memcpy(p, &error_code, 4); 647 p += 4; 648 return p - buf; 649} 650 651 652int 653gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len, uint32_t *stream_id, 654 uint64_t *offset, uint32_t *error_code) 655{ 656 if (buf_len < QUIC_RST_STREAM_SZ) 657 return -1; 658 659 READ_UINT(*stream_id, 32, buf + 1, 4); 660 READ_UINT(*offset, 64, buf + 1 + 4, 8); 661 READ_UINT(*error_code, 32, buf + 1 + 4 + 8, 4); 662 return QUIC_RST_STREAM_SZ; 663} 664 665 666int 667gquic_be_gen_ping_frame (unsigned char *buf, int buf_len) 668{ 669 if (buf_len > 0) 670 { 671 buf[0] = 0x07; 672 return 1; 673 } 674 else 675 return -1; 676} 677 678 679int 680gquic_be_gen_connect_close_frame (unsigned char *buf, int buf_len, uint32_t error_code, 681 const char *reason, int reason_len) 682{ 683 unsigned char *p = buf; 684 if (buf_len < 7) 685 return -1; 686 687 *p = 0x02; 688 ++p; 689#if __BYTE_ORDER == __LITTLE_ENDIAN 690 error_code = bswap_32(error_code); 691#endif 692 memcpy(p, &error_code, 4); 693 p += 4; 694#if __BYTE_ORDER == __LITTLE_ENDIAN 695 const uint16_t copy = bswap_16(reason_len); 696 memcpy(p, ©, 2); 697#else 698 memcpy(p, &reason_len, 2); 699#endif 700 p += 2; 701 memcpy(p, reason, reason_len); 702 p += reason_len; 703 if (buf_len < p - buf) 704 return -2; 705 706 return p - buf; 707} 708 709 710int 711gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len, 712 uint32_t *error_code, uint16_t *reason_len, uint8_t *reason_offset) 713{ 714 if (buf_len < 7) 715 return -1; 716 717 READ_UINT(*error_code, 32, buf + 1, 4); 718 READ_UINT(*reason_len, 16, buf + 1 + 4, 2); 719 *reason_offset = 7; 720 if (buf_len < 7u + *reason_len) 721 return -2; 722 723 return 7 + *reason_len; 724} 725 726 727int 728gquic_be_gen_goaway_frame(unsigned char *buf, size_t buf_len, uint32_t error_code, 729 uint32_t last_good_stream_id, const char *reason, 730 size_t reason_len) 731{ 732 unsigned char *p = buf; 733 if (buf_len < QUIC_GOAWAY_FRAME_SZ + reason_len) 734 return -1; 735 736 *p = 0x03; 737 ++p; 738#if __BYTE_ORDER == __LITTLE_ENDIAN 739 error_code = bswap_32(error_code); 740#endif 741 memcpy(p, &error_code, 4); 742 p += 4; 743#if __BYTE_ORDER == __LITTLE_ENDIAN 744 last_good_stream_id = bswap_32(last_good_stream_id); 745#endif 746 memcpy(p, &last_good_stream_id, 4); 747 p += 4; 748#if __BYTE_ORDER == __LITTLE_ENDIAN 749 uint16_t copy = bswap_16(reason_len); 750 memcpy(p, ©, 2); 751#else 752 memcpy(p, &reason_len, 2); 753#endif 754 p += 2; 755 if (reason_len) 756 { 757 memcpy(p, reason, reason_len); 758 p += reason_len; 759 } 760 761 return p - buf; 762} 763 764 765/* the reason is buf + *reason_offset, length is *reason_length */ 766int 767gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len, 768 uint32_t *error_code, uint32_t *last_good_stream_id, 769 uint16_t *reason_length, const char **reason) 770{ 771 if (buf_len < QUIC_GOAWAY_FRAME_SZ) 772 return -1; 773 774 READ_UINT(*error_code, 32, buf + 1, 4); 775 READ_UINT(*last_good_stream_id, 32, buf + 1 + 4, 4); 776 READ_UINT(*reason_length, 16, buf + 1 + 4 + 4, 2); 777 if (*reason_length) 778 { 779 if ((int)buf_len < QUIC_GOAWAY_FRAME_SZ + *reason_length) 780 return -2; 781 *reason = (const char *) buf + QUIC_GOAWAY_FRAME_SZ; 782 } 783 else 784 *reason = NULL; 785 786 return QUIC_GOAWAY_FRAME_SZ + *reason_length; 787} 788 789 790/* Returns number of bytes written or -1 on failure */ 791/* This function makes an assumption that there is at least one range */ 792int 793gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz, 794 gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next, 795 gaf_rechist_largest_recv_f rechist_largest_recv, 796 void *rechist, lsquic_time_t now, int *has_missing, 797 lsquic_packno_t *largest_received) 798{ 799 lsquic_time_t time_diff; 800 lsquic_packno_t tmp_packno; 801 const struct lsquic_packno_range *const first = rechist_first(rechist); 802 if (!first) 803 { 804 errno = EINVAL; 805 return -1; 806 } 807 808 /* Copy values from the first range, because the memory the pointer 809 * points to may change: 810 */ 811 const lsquic_packno_t first_low = first->low, first_high = first->high; 812 813 unsigned char *p = outbuf; 814 unsigned char *const type = p; 815 unsigned char *const end = p + outbuf_sz; 816 817#define AVAIL() (end - p) 818 819#define CHECKOUT(sz) do { \ 820 if ((intptr_t) (sz) > AVAIL()) { \ 821 errno = ENOBUFS; \ 822 return -1; \ 823 } \ 824} while (0) 825 826 CHECKOUT(1); 827 ++p; 828 829 /* 01nullmm */ 830 *type = 0x40; 831 832 unsigned largest_acked_len, ack_block_len, bits; 833 834 /* Calculate largest ACKed len and set `ll' bits: */ 835 const lsquic_packno_t maxno = first_high; 836 bits = (maxno >= (1ULL << 8)) 837 + (maxno >= (1ULL << 16)) 838 + (maxno >= (1ULL << 32)); 839 largest_acked_len = (1 << bits) - ((maxno >= (1ULL << 32)) << 1); 840 *type |= bits << 2; 841 842 /* Calculate largest ACK block length and set `mm' bits: */ 843 unsigned n_ranges = 0; 844 lsquic_packno_t maxdiff = 0; 845 const struct lsquic_packno_range *range; 846 for (range = rechist_first(rechist); range; range = rechist_next(rechist)) 847 { 848 ++n_ranges; 849 const lsquic_packno_t diff = range->high - range->low + 1; 850 if (diff > maxdiff) 851 maxdiff = diff; 852 } 853 bits = (maxdiff >= (1ULL << 8)) 854 + (maxdiff >= (1ULL << 16)) 855 + (maxdiff >= (1ULL << 32)); 856 ack_block_len = (1 << bits) - ((maxdiff >= (1ULL << 32)) << 1); 857 *type |= bits; 858 859 CHECKOUT(largest_acked_len); 860 tmp_packno = maxno; 861#if __BYTE_ORDER == __LITTLE_ENDIAN 862 tmp_packno = bswap_64(maxno); 863#endif 864 memcpy(p, (unsigned char *) &tmp_packno + 8 - largest_acked_len, 865 largest_acked_len); 866 p += largest_acked_len; 867 868 CHECKOUT(2); 869 time_diff = now - rechist_largest_recv(rechist); 870 gquic_be_write_float_time16(time_diff, p); 871 LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, time_diff, 872 *(uint16_t*)p); 873 p += 2; 874 875 if (n_ranges > 1) 876 { 877 *has_missing = 1; 878 *type |= 0x20; 879 /* We need to write out at least one range */ 880 CHECKOUT(2 * (1 + ack_block_len)); 881 unsigned char *const n_ranges_p = p; /* Set this later */ 882 lsquic_packno_t diff = maxno - first_low + 1; 883#if __BYTE_ORDER == __LITTLE_ENDIAN 884 diff = bswap_64(diff); 885#endif 886 memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len, 887 ack_block_len); 888 p += ack_block_len + 1; 889 /* Write out ack blocks until one of the following occurs: 890 * 1. We run out of intervals. 891 * 2. We run out of room. 892 * 3. We run out of highest possible number of ACK blocks (0xFF). 893 */ 894 range = rechist_first(rechist); 895 lsquic_packno_t gap = 0; 896 n_ranges = 0; 897 do { 898 if (0 == gap) 899 { 900 const lsquic_packno_t prev_low = range->low; 901 range = rechist_next(rechist); 902 if (!range) 903 break; 904 gap = prev_low - range->high - 1; 905 } 906 if (gap >= 0x100) 907 { 908 *p = 0xFF; 909 gap -= 0xFF; 910 memset(p + 1, 0, ack_block_len); 911 } 912 else 913 { 914 *p = gap; 915 gap = 0; 916 diff = range->high - range->low + 1; 917#if __BYTE_ORDER == __LITTLE_ENDIAN 918 diff = bswap_64(diff); 919#endif 920 memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len, 921 ack_block_len); 922 } 923 p += ack_block_len + 1; 924 ++n_ranges; 925 } while (n_ranges < 0xFF && 926 AVAIL() >= (intptr_t) ack_block_len + 1 + 1 /* timestamp byte */); 927 *n_ranges_p = n_ranges; 928 } 929 else 930 { 931 *has_missing = 0; 932 CHECKOUT(ack_block_len); 933 lsquic_packno_t diff = maxno - first_low + 1; 934#if __BYTE_ORDER == __LITTLE_ENDIAN 935 diff = bswap_64(diff); 936#endif 937 memcpy(p, (unsigned char *) &diff + 8 - ack_block_len, ack_block_len); 938 p += ack_block_len; 939 } 940 941 /* We do not generate timestamp list because the reference implementation 942 * does not use them. When that changes, we will start sending timestamps 943 * over. 944 */ 945 CHECKOUT(1); 946 *p = 0; 947 ++p; 948 949 *largest_received = maxno; 950 return p - (unsigned char *) outbuf; 951 952#undef CHECKOUT 953} 954 955 956const struct parse_funcs lsquic_parse_funcs_gquic_Q039 = 957{ 958 .pf_gen_ver_nego_pkt = gquic_be_gen_ver_nego_pkt, 959 .pf_gen_reg_pkt_header = gquic_be_gen_reg_pkt_header, 960 .pf_parse_packet_in_finish = gquic_be_parse_packet_in_finish, 961 .pf_gen_stream_frame = gquic_be_gen_stream_frame, 962 .pf_calc_stream_frame_header_sz = calc_stream_frame_header_sz_gquic, 963 .pf_parse_stream_frame_header_sz = parse_stream_frame_header_sz_gquic, 964 .pf_parse_stream_frame = gquic_be_parse_stream_frame, 965 .pf_parse_ack_frame = gquic_be_parse_ack_frame, 966 .pf_gen_ack_frame = gquic_be_gen_ack_frame, 967 .pf_gen_stop_waiting_frame = gquic_be_gen_stop_waiting_frame, 968 .pf_parse_stop_waiting_frame = gquic_be_parse_stop_waiting_frame, 969 .pf_skip_stop_waiting_frame = gquic_be_skip_stop_waiting_frame, 970 .pf_gen_window_update_frame = gquic_be_gen_window_update_frame, 971 .pf_parse_window_update_frame = gquic_be_parse_window_update_frame, 972 .pf_gen_blocked_frame = gquic_be_gen_blocked_frame, 973 .pf_parse_blocked_frame = gquic_be_parse_blocked_frame, 974 .pf_gen_rst_frame = gquic_be_gen_rst_frame, 975 .pf_parse_rst_frame = gquic_be_parse_rst_frame, 976 .pf_gen_connect_close_frame = gquic_be_gen_connect_close_frame, 977 .pf_parse_connect_close_frame = gquic_be_parse_connect_close_frame, 978 .pf_gen_goaway_frame = gquic_be_gen_goaway_frame, 979 .pf_parse_goaway_frame = gquic_be_parse_goaway_frame, 980 .pf_gen_ping_frame = gquic_be_gen_ping_frame, 981#ifndef NDEBUG 982 .pf_write_float_time16 = gquic_be_write_float_time16, 983 .pf_read_float_time16 = gquic_be_read_float_time16, 984#endif 985 .pf_parse_frame_type = parse_frame_type_gquic_Q035_thru_Q039, 986 .pf_turn_on_fin = lsquic_turn_on_fin_Q035_thru_Q039, 987}; 988