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