lsquic_parse_gquic_be.c revision fb96f4dd
1/* Copyright (c) 2017 - 2020 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 46gquic_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 65gquic_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 96gquic_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 (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 109gquic_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) 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 193gquic_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 296 297/* return parsed (used) buffer length */ 298int 299gquic_be_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz, 300 stream_frame_t *stream_frame) 301{ 302 /* 1fdoooss */ 303 uint32_t stream_id; 304 const unsigned char *p = buf; 305 const unsigned char *const pend = p + rem_packet_sz; 306 307 CHECK_SPACE(1, p, pend); 308 const char type = *p++; 309 310 const unsigned data_len = (type >> 4) & 2; 311 const unsigned offset_len = ((type >> 2) & 7) + 1 - !((type >> 2) & 7); 312 const unsigned stream_id_len = 1 + (type & 3); 313 const unsigned need = data_len + offset_len + stream_id_len; 314 CHECK_SPACE(need, p, pend); 315 316 memset(stream_frame, 0, sizeof(*stream_frame)); 317 318 stream_frame->data_frame.df_fin = (type >> 6) & 1; 319 320 stream_id = 0; 321 memcpy((unsigned char *) &stream_id + 4 - stream_id_len, p, stream_id_len); 322 323#if __BYTE_ORDER == __LITTLE_ENDIAN 324 stream_id = bswap_32(stream_id); 325#endif 326 stream_frame->stream_id = stream_id; 327 p += stream_id_len; 328 329 memcpy((unsigned char *) &stream_frame->data_frame.df_offset 330 + 8 - offset_len, p, offset_len); 331#if __BYTE_ORDER == __LITTLE_ENDIAN 332 stream_frame->data_frame.df_offset = 333 bswap_64(stream_frame->data_frame.df_offset); 334#endif 335 p += offset_len; 336 337 if (data_len) 338 { 339 memcpy(&stream_frame->data_frame.df_size, p, data_len); 340#if __BYTE_ORDER == __LITTLE_ENDIAN 341 stream_frame->data_frame.df_size = 342 bswap_16(stream_frame->data_frame.df_size); 343#endif 344 p += data_len; 345 CHECK_SPACE(stream_frame->data_frame.df_size, p, pend); 346 stream_frame->data_frame.df_data = p; 347 p += stream_frame->data_frame.df_size; 348 } 349 else 350 { 351 stream_frame->data_frame.df_size = pend - p; 352 stream_frame->data_frame.df_data = p; 353 p = pend; 354 } 355 356 /* From the spec: "A stream frame must always have either non-zero 357 * data length or the FIN bit set.' 358 */ 359 if (!(stream_frame->data_frame.df_size || 360 stream_frame->data_frame.df_fin)) 361 return -1; 362 363 assert(p <= pend); 364 365 return p - (unsigned char *) buf; 366} 367 368 369static int 370parse_ack_frame_without_blocks (const unsigned char *buf, size_t buf_len, 371 struct ack_info *ack) 372{ 373 /* 01nullmm */ 374 lsquic_packno_t tmp_packno; 375 const unsigned char type = buf[0]; 376 const unsigned char *p = buf + 1; 377 const unsigned char *const pend = buf + buf_len; 378 unsigned char n_timestamps; 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 n_timestamps = *p; 398 ++p; 399 400 if (n_timestamps) 401 { 402 unsigned timestamps_size = 5 + 3 * (n_timestamps - 1); 403 CHECK_SPACE(timestamps_size, p, pend); 404 p += timestamps_size; 405 } 406 407 assert(p <= pend); 408 409 ack->flags = 0; 410 return p - (unsigned char *) buf; 411} 412 413 414static int 415parse_ack_frame_with_blocks (const unsigned char *buf, size_t buf_len, 416 struct ack_info *ack) 417{ 418 /* 01nullmm */ 419 lsquic_packno_t tmp_packno; 420 const unsigned char type = buf[0]; 421 const unsigned char *p = buf + 1; 422 const unsigned char *const pend = buf + buf_len; 423 unsigned char n_timestamps; 424 425 assert((type & 0xC0) == 0x40); /* We're passed correct frame type */ 426 427 const int ack_block_len = twobit_to_1246(type & 3); /* mm */ 428 const int largest_obs_len = twobit_to_1246((type >> 2) & 3); /* ll */ 429 430 CHECK_SPACE(largest_obs_len + 2 + 1 + ack_block_len, p, pend); 431 432 READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len); 433 p += largest_obs_len; 434 435 ack->lack_delta = gquic_be_read_float_time16(p); 436 p += 2; 437 438 unsigned n_blocks; 439 CHECK_SPACE(1, p , pend); 440 n_blocks = *p; 441 ++p; 442 443 READ_UINT(tmp_packno, 64, p, ack_block_len); 444 ack->ranges[0].low = ack->ranges[0].high - tmp_packno + 1; 445 p += ack_block_len; 446 447 CHECK_SPACE((ack_block_len + 1) * n_blocks + /* timestamp count: */ 1, 448 p , pend); 449 unsigned i, n, gap; 450 for (i = 0, n = 1, gap = 0; i < n_blocks; ++i) 451 { 452 uint64_t length; 453 gap += *p; 454 READ_UINT(length, 64, p + 1, ack_block_len); 455 p += 1 + ack_block_len; 456 if (length) 457 { 458 ack->ranges[n].high = ack->ranges[n - 1].low - gap - 1; 459 ack->ranges[n].low = ack->ranges[n].high - length + 1; 460 ++n; 461 gap = 0; 462 } 463 } 464 ack->n_ranges = n; 465 466 n_timestamps = *p; 467 ++p; 468 469 if (n_timestamps) 470 { 471 unsigned timestamps_size = 5 + 3 * (n_timestamps - 1); 472 CHECK_SPACE(timestamps_size, p, pend); 473 p += timestamps_size; 474 } 475 476 assert(p <= pend); 477 478 ack->flags = 0; 479 return p - (unsigned char *) buf; 480} 481 482 483/* Return parsed (used) buffer length. 484 * If parsing failed, negative value is returned. 485 */ 486int 487gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len, 488 struct ack_info *ack, uint8_t UNUSED_exp) 489{ 490 if (!(buf[0] & 0x20)) 491 return parse_ack_frame_without_blocks(buf, buf_len, ack); 492 else 493 return parse_ack_frame_with_blocks(buf, buf_len, ack); 494} 495 496 497int 498gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len, 499 lsquic_packno_t cur_packno, enum packno_bits bits, 500 lsquic_packno_t least_unacked_packno) 501{ 502 lsquic_packno_t delta; 503 unsigned packnum_len = gquic_packno_bits2len(bits); 504 505 if (buf_len >= 1 + packnum_len) 506 { 507 *buf = 0x06; 508 delta = cur_packno - least_unacked_packno; 509#if __BYTE_ORDER == __LITTLE_ENDIAN 510 delta = bswap_64(delta); 511#endif 512 memcpy(buf + 1, (unsigned char *) &delta + 8 - packnum_len, 513 packnum_len); 514 return 1 + packnum_len; 515 } 516 else 517 return -1; 518} 519 520 521int 522gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len, 523 lsquic_packno_t cur_packno, enum packno_bits bits, 524 lsquic_packno_t *least_unacked) 525{ 526 lsquic_packno_t delta; 527 unsigned packnum_len = gquic_packno_bits2len(bits); 528 529 if (buf_len >= 1 + packnum_len) 530 { 531 READ_UINT(delta, 64, buf + 1, packnum_len); 532 *least_unacked = cur_packno - delta; 533 return 1 + packnum_len; 534 } 535 else 536 return -1; 537} 538 539 540int 541gquic_be_skip_stop_waiting_frame (size_t buf_len, enum packno_bits bits) 542{ 543 unsigned packnum_len = gquic_packno_bits2len(bits); 544 if (buf_len >= 1 + packnum_len) 545 return 1 + packnum_len; 546 else 547 return -1; 548} 549 550 551int 552gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len, 553 lsquic_stream_id_t stream_id64, uint64_t offset) 554{ 555 uint32_t stream_id = stream_id64; 556 557 if (buf_len < GQUIC_WUF_SZ) 558 return -1; 559 560 *buf = 0x04; 561#if __BYTE_ORDER == __LITTLE_ENDIAN 562 stream_id = bswap_32(stream_id); 563#endif 564 memcpy(buf + 1, (unsigned char *) &stream_id, 4); 565#if __BYTE_ORDER == __LITTLE_ENDIAN 566 offset = bswap_64(offset); 567#endif 568 memcpy(buf + 1 + 4, (unsigned char *) &offset, 8); 569 return GQUIC_WUF_SZ; 570} 571 572 573int 574gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len, 575 lsquic_stream_id_t *stream_id_p, uint64_t *offset) 576{ 577 uint32_t stream_id; 578 579 if (buf_len < GQUIC_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 *stream_id_p = stream_id; 585 return GQUIC_WUF_SZ; 586} 587 588 589int 590gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len, 591 lsquic_stream_id_t stream_id64) 592{ 593 uint32_t stream_id = stream_id64; 594 595 if (buf_len < GQUIC_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 GQUIC_BLOCKED_FRAME_SZ; 604} 605 606 607int 608gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len, 609 lsquic_stream_id_t *stream_id_p) 610{ 611 uint32_t stream_id; 612 if (buf_len < GQUIC_BLOCKED_FRAME_SZ) 613 return -1; 614 615 READ_UINT(stream_id, 32, buf + 1, 4); 616 *stream_id_p = stream_id; 617 return GQUIC_BLOCKED_FRAME_SZ; 618} 619 620 621static unsigned 622gquic_be_rst_frame_size (lsquic_stream_id_t stream_id, uint64_t error_code, 623 uint64_t final_size) 624{ 625 assert(0); /* This function is not called */ 626 return GQUIC_RST_STREAM_SZ; 627} 628 629 630int 631gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len, 632 lsquic_stream_id_t stream_id64, uint64_t offset, uint64_t error_code64) 633{ 634 uint32_t stream_id = stream_id64, error_code = error_code64; 635 unsigned char *p = buf; 636 if (buf_len < GQUIC_RST_STREAM_SZ) 637 return -1; 638 639 *p = 0x01; 640 ++p; 641#if __BYTE_ORDER == __LITTLE_ENDIAN 642 stream_id = bswap_32(stream_id); 643#endif 644 memcpy(p, &stream_id, 4); 645 p += 4; 646#if __BYTE_ORDER == __LITTLE_ENDIAN 647 offset = bswap_64(offset); 648#endif 649 memcpy(p, &offset, 8); 650 p += 8; 651#if __BYTE_ORDER == __LITTLE_ENDIAN 652 error_code = bswap_32(error_code); 653#endif 654 memcpy(p, &error_code, 4); 655 p += 4; 656 return p - buf; 657} 658 659 660int 661gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len, 662 lsquic_stream_id_t *stream_id_p, uint64_t *offset, uint64_t *error_code_p) 663{ 664 uint32_t stream_id, error_code; 665 666 if (buf_len < GQUIC_RST_STREAM_SZ) 667 return -1; 668 669 READ_UINT(stream_id, 32, buf + 1, 4); 670 READ_UINT(*offset, 64, buf + 1 + 4, 8); 671 READ_UINT(error_code, 32, buf + 1 + 4 + 8, 4); 672 *stream_id_p = stream_id; 673 *error_code_p = error_code; 674 return GQUIC_RST_STREAM_SZ; 675} 676 677 678int 679gquic_be_gen_ping_frame (unsigned char *buf, int buf_len) 680{ 681 if (buf_len > 0) 682 { 683 buf[0] = 0x07; 684 return 1; 685 } 686 else 687 return -1; 688} 689 690 691size_t 692gquic_be_connect_close_frame_size (int app_error, unsigned error_code, 693 unsigned frame_type, size_t reason_len) 694{ 695 return 1 + 4 + 2 + reason_len; 696} 697 698 699int 700gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len, 701 int app_error_UNUSED, unsigned ecode, const char *reason, int reason_len) 702{ 703 uint32_t error_code; 704 unsigned char *p = buf; 705 if ((int) buf_len < 7 + reason_len) 706 return -1; 707 708 *p = 0x02; 709 ++p; 710 error_code = ecode; 711#if __BYTE_ORDER == __LITTLE_ENDIAN 712 error_code = bswap_32(error_code); 713#endif 714 memcpy(p, &error_code, 4); 715 p += 4; 716#if __BYTE_ORDER == __LITTLE_ENDIAN 717 const uint16_t copy = bswap_16(reason_len); 718 memcpy(p, ©, 2); 719#else 720 memcpy(p, &reason_len, 2); 721#endif 722 p += 2; 723 memcpy(p, reason, reason_len); 724 p += reason_len; 725 726 return p - buf; 727} 728 729 730int 731gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len, 732 int *app_error, uint64_t *error_code_p, 733 uint16_t *reason_len, uint8_t *reason_offset) 734{ 735 uint32_t error_code; 736 737 if (buf_len < 7) 738 return -1; 739 740 READ_UINT(error_code, 32, buf + 1, 4); 741 READ_UINT(*reason_len, 16, buf + 1 + 4, 2); 742 *reason_offset = 7; 743 if (buf_len < 7u + *reason_len) 744 return -2; 745 746 *error_code_p = error_code; 747 if (app_error) 748 *app_error = 0; 749 750 return 7 + *reason_len; 751} 752 753 754int 755gquic_be_gen_goaway_frame (unsigned char *buf, size_t buf_len, 756 uint32_t error_code, lsquic_stream_id_t last_good_stream_id64, 757 const char *reason, size_t reason_len) 758{ 759 uint32_t last_good_stream_id = last_good_stream_id64; 760 unsigned char *p = buf; 761 if (buf_len < GQUIC_GOAWAY_FRAME_SZ + reason_len) 762 return -1; 763 764 *p = 0x03; 765 ++p; 766#if __BYTE_ORDER == __LITTLE_ENDIAN 767 error_code = bswap_32(error_code); 768#endif 769 memcpy(p, &error_code, 4); 770 p += 4; 771#if __BYTE_ORDER == __LITTLE_ENDIAN 772 last_good_stream_id = bswap_32(last_good_stream_id); 773#endif 774 memcpy(p, &last_good_stream_id, 4); 775 p += 4; 776#if __BYTE_ORDER == __LITTLE_ENDIAN 777 uint16_t copy = bswap_16(reason_len); 778 memcpy(p, ©, 2); 779#else 780 memcpy(p, &reason_len, 2); 781#endif 782 p += 2; 783 if (reason_len) 784 { 785 memcpy(p, reason, reason_len); 786 p += reason_len; 787 } 788 789 return p - buf; 790} 791 792 793/* the reason is buf + *reason_offset, length is *reason_length */ 794int 795gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len, 796 uint32_t *error_code, lsquic_stream_id_t *last_good_stream_id, 797 uint16_t *reason_length, const char **reason) 798{ 799 uint32_t stream_id; 800 if (buf_len < GQUIC_GOAWAY_FRAME_SZ) 801 return -1; 802 803 READ_UINT(*error_code, 32, buf + 1, 4); 804 READ_UINT(stream_id, 32, buf + 1 + 4, 4); 805 READ_UINT(*reason_length, 16, buf + 1 + 4 + 4, 2); 806 if (*reason_length) 807 { 808 if ((int)buf_len < GQUIC_GOAWAY_FRAME_SZ + *reason_length) 809 return -2; 810 *reason = (const char *) buf + GQUIC_GOAWAY_FRAME_SZ; 811 } 812 else 813 *reason = NULL; 814 815 *last_good_stream_id = stream_id; 816 return GQUIC_GOAWAY_FRAME_SZ + *reason_length; 817} 818 819 820/* Returns number of bytes written or -1 on failure */ 821/* This function makes an assumption that there is at least one range */ 822int 823gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz, 824 gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next, 825 gaf_rechist_largest_recv_f rechist_largest_recv, 826 void *rechist, lsquic_time_t now, int *has_missing, 827 lsquic_packno_t *largest_received, const uint64_t *unused) 828{ 829 lsquic_time_t time_diff; 830 lsquic_packno_t tmp_packno; 831 const struct lsquic_packno_range *const first = rechist_first(rechist); 832 if (!first) 833 { 834 errno = EINVAL; 835 return -1; 836 } 837 838 /* Copy values from the first range, because the memory the pointer 839 * points to may change: 840 */ 841 const lsquic_packno_t first_low = first->low, first_high = first->high; 842 843 unsigned char *p = outbuf; 844 unsigned char *const type = p; 845 unsigned char *const end = p + outbuf_sz; 846 847#define AVAIL() (end - p) 848 849#define CHECKOUT(sz) do { \ 850 if ((intptr_t) (sz) > AVAIL()) { \ 851 errno = ENOBUFS; \ 852 return -1; \ 853 } \ 854} while (0) 855 856 CHECKOUT(1); 857 ++p; 858 859 /* 01nullmm */ 860 *type = 0x40; 861 862 unsigned largest_acked_len, ack_block_len, bits; 863 864 /* Calculate largest ACKed len and set `ll' bits: */ 865 const lsquic_packno_t maxno = first_high; 866 bits = (maxno >= (1ULL << 8)) 867 + (maxno >= (1ULL << 16)) 868 + (maxno >= (1ULL << 32)); 869 largest_acked_len = (1 << bits) - ((maxno >= (1ULL << 32)) << 1); 870 *type |= bits << 2; 871 872 /* Calculate largest ACK block length and set `mm' bits: */ 873 unsigned n_ranges = 0; 874 lsquic_packno_t maxdiff = 0; 875 const struct lsquic_packno_range *range; 876 for (range = rechist_first(rechist); range; range = rechist_next(rechist)) 877 { 878 ++n_ranges; 879 const lsquic_packno_t diff = range->high - range->low + 1; 880 if (diff > maxdiff) 881 maxdiff = diff; 882 } 883 bits = (maxdiff >= (1ULL << 8)) 884 + (maxdiff >= (1ULL << 16)) 885 + (maxdiff >= (1ULL << 32)); 886 ack_block_len = (1 << bits) - ((maxdiff >= (1ULL << 32)) << 1); 887 *type |= bits; 888 889 CHECKOUT(largest_acked_len); 890 tmp_packno = maxno; 891#if __BYTE_ORDER == __LITTLE_ENDIAN 892 tmp_packno = bswap_64(maxno); 893#endif 894 memcpy(p, (unsigned char *) &tmp_packno + 8 - largest_acked_len, 895 largest_acked_len); 896 p += largest_acked_len; 897 898 CHECKOUT(2); 899 time_diff = now - rechist_largest_recv(rechist); 900 gquic_be_write_float_time16(time_diff, p); 901 LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, time_diff, 902 *(uint16_t*)p); 903 p += 2; 904 905 if (n_ranges > 1) 906 { 907 *has_missing = 1; 908 *type |= 0x20; 909 /* We need to write out at least one range */ 910 CHECKOUT(2 * (1 + ack_block_len)); 911 unsigned char *const n_ranges_p = p; /* Set this later */ 912 lsquic_packno_t diff = maxno - first_low + 1; 913#if __BYTE_ORDER == __LITTLE_ENDIAN 914 diff = bswap_64(diff); 915#endif 916 memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len, 917 ack_block_len); 918 p += ack_block_len + 1; 919 /* Write out ack blocks until one of the following occurs: 920 * 1. We run out of intervals. 921 * 2. We run out of room. 922 * 3. We run out of highest possible number of ACK blocks (0xFF). 923 */ 924 range = rechist_first(rechist); 925 lsquic_packno_t gap = 0; 926 n_ranges = 0; 927 do { 928 if (0 == gap) 929 { 930 const lsquic_packno_t prev_low = range->low; 931 range = rechist_next(rechist); 932 if (!range) 933 break; 934 gap = prev_low - range->high - 1; 935 } 936 if (gap >= 0x100) 937 { 938 *p = 0xFF; 939 gap -= 0xFF; 940 memset(p + 1, 0, ack_block_len); 941 } 942 else 943 { 944 *p = gap; 945 gap = 0; 946 diff = range->high - range->low + 1; 947#if __BYTE_ORDER == __LITTLE_ENDIAN 948 diff = bswap_64(diff); 949#endif 950 memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len, 951 ack_block_len); 952 } 953 p += ack_block_len + 1; 954 ++n_ranges; 955 } while (n_ranges < 0xFF && 956 AVAIL() >= (intptr_t) ack_block_len + 1 + 1 /* timestamp byte */); 957 *n_ranges_p = n_ranges; 958 } 959 else 960 { 961 *has_missing = 0; 962 CHECKOUT(ack_block_len); 963 lsquic_packno_t diff = maxno - first_low + 1; 964#if __BYTE_ORDER == __LITTLE_ENDIAN 965 diff = bswap_64(diff); 966#endif 967 memcpy(p, (unsigned char *) &diff + 8 - ack_block_len, ack_block_len); 968 p += ack_block_len; 969 } 970 971 /* We do not generate timestamp list because the reference implementation 972 * does not use them. When that changes, we will start sending timestamps 973 * over. 974 */ 975 CHECKOUT(1); 976 *p = 0; 977 ++p; 978 979 *largest_received = maxno; 980 return p - (unsigned char *) outbuf; 981 982#undef CHECKOUT 983} 984 985 986static int 987gquic_be_gen_crypto_frame (unsigned char *buf, size_t buf_len, 988 uint64_t offset, size_t size, gcf_read_f gcf_read, void *stream) 989{ 990 assert(0); 991 return -1; 992} 993 994 995static int 996gquic_be_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz, 997 struct stream_frame *stream_frame) 998{ 999 assert(0); 1000 return -1; 1001} 1002 1003 1004static void 1005gquic_be_packno_info (const struct lsquic_conn *lconn, 1006 const struct lsquic_packet_out *packet_out, unsigned *packno_off, 1007 unsigned *packno_len) 1008{ 1009 assert(0); 1010} 1011 1012 1013const struct parse_funcs lsquic_parse_funcs_gquic_Q043 = 1014{ 1015 .pf_gen_reg_pkt_header = gquic_be_gen_reg_pkt_header, 1016 .pf_parse_packet_in_finish = gquic_be_parse_packet_in_finish, 1017 .pf_gen_stream_frame = gquic_be_gen_stream_frame, 1018 .pf_calc_stream_frame_header_sz = calc_stream_frame_header_sz_gquic, 1019 .pf_parse_stream_frame = gquic_be_parse_stream_frame, 1020 .pf_parse_ack_frame = gquic_be_parse_ack_frame, 1021 .pf_gen_ack_frame = gquic_be_gen_ack_frame, 1022 .pf_gen_stop_waiting_frame = gquic_be_gen_stop_waiting_frame, 1023 .pf_parse_stop_waiting_frame = gquic_be_parse_stop_waiting_frame, 1024 .pf_skip_stop_waiting_frame = gquic_be_skip_stop_waiting_frame, 1025 .pf_gen_window_update_frame = gquic_be_gen_window_update_frame, 1026 .pf_parse_window_update_frame = gquic_be_parse_window_update_frame, 1027 .pf_gen_blocked_frame = gquic_be_gen_blocked_frame, 1028 .pf_parse_blocked_frame = gquic_be_parse_blocked_frame, 1029 .pf_rst_frame_size = gquic_be_rst_frame_size, 1030 .pf_gen_rst_frame = gquic_be_gen_rst_frame, 1031 .pf_parse_rst_frame = gquic_be_parse_rst_frame, 1032 .pf_connect_close_frame_size = gquic_be_connect_close_frame_size, 1033 .pf_gen_connect_close_frame = gquic_be_gen_connect_close_frame, 1034 .pf_parse_connect_close_frame = gquic_be_parse_connect_close_frame, 1035 .pf_gen_goaway_frame = gquic_be_gen_goaway_frame, 1036 .pf_parse_goaway_frame = gquic_be_parse_goaway_frame, 1037 .pf_gen_ping_frame = gquic_be_gen_ping_frame, 1038#ifndef NDEBUG 1039 .pf_write_float_time16 = gquic_be_write_float_time16, 1040 .pf_read_float_time16 = gquic_be_read_float_time16, 1041#endif 1042 .pf_generate_simple_prst = lsquic_generate_gquic_reset, 1043 .pf_parse_frame_type = lsquic_parse_frame_type_gquic_Q035_thru_Q046, 1044 .pf_turn_on_fin = lsquic_turn_on_fin_Q035_thru_Q046, 1045 .pf_packout_size = lsquic_gquic_packout_size, 1046 .pf_packout_max_header_size = lsquic_gquic_packout_header_size, 1047 .pf_calc_packno_bits = lsquic_gquic_calc_packno_bits, 1048 .pf_packno_bits2len = lsquic_gquic_packno_bits2len, 1049 .pf_gen_crypto_frame = gquic_be_gen_crypto_frame, 1050 .pf_parse_crypto_frame = gquic_be_parse_crypto_frame, 1051 .pf_packno_info = gquic_be_packno_info, 1052}; 1053