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