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