lsquic_frame_reader.c revision 72585dc9
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * lsquic_frame_reader.c -- Read HTTP frames from stream 4 */ 5 6#ifndef WIN32 7#include <arpa/inet.h> 8#endif 9#include <assert.h> 10#include <ctype.h> 11#include <errno.h> 12#include <inttypes.h> 13#include <stdlib.h> 14#include <string.h> 15#include <sys/queue.h> 16 17#include "lshpack.h" 18#include "lsquic.h" 19#include "lsquic_mm.h" 20#include "lsquic_frame_common.h" 21#include "lsquic_frame_reader.h" 22#include "lsquic_http1x_if.h" 23#include "lsquic_headers.h" 24#include "lsquic_ev_log.h" 25#include "lsquic_hash.h" 26#include "lsquic_conn.h" 27 28#define LSQUIC_LOGGER_MODULE LSQLM_FRAME_READER 29#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(lsquic_stream_conn(\ 30 fr->fr_stream)) 31#include "lsquic_logger.h" 32 33 34/* headers_state is used by HEADERS, PUSH_PROMISE, and CONTINUATION frames */ 35struct headers_state 36{ 37 enum http_frame_type 38 frame_type; 39 unsigned nread; /* Not counting pesw, only payload and padding */ 40 41 /* Values parsed out from pesw buffer: */ 42 uint32_t oth_stream_id; /* For HEADERS: ID of stream we depend on; 43 * for PUSH_PROMISE: promised stream ID. 44 */ 45 unsigned short weight; /* HEADERS only */ 46 signed char exclusive; /* HEADERS only */ 47 unsigned char pad_length; 48 49 unsigned char pseh; 50 51 /* PESW: Pad length, Exclusive, Stream Dependency, Weight. This is at 52 * most six bytes for HEADERS frame (RFC 7540, page 33) and five bytes 53 * for PUSH_PROMISE frame (Ibid, p. 40). 54 */ 55 unsigned char pesw_size; 56 unsigned char pesw_nread; 57 unsigned char pesw[6]; 58}; 59 60 61struct settings_state 62{ /* RFC 7540, Section 6.5.1 */ 63 unsigned char nread; 64 unsigned char set_buf[2 + 4]; /* We'll read one setting at a time */ 65}; 66 67 68struct priority_state 69{ /* RFC 7540, Section 6.3 */ 70 unsigned char nread; 71 union { 72 unsigned char prio_buf[sizeof(struct http_prio_frame)]; 73 struct http_prio_frame prio_frame; 74 } u; 75}; 76 77 78struct skip_state 79{ 80 uint32_t n_skipped; 81}; 82 83 84struct reader_state 85{ 86 unsigned nh_read; /* Number of bytes of header read */ 87 struct http_frame_header header; 88 enum { 89 READER_SKIP, 90 READER_HEADERS, 91 READER_PUSH_PROMISE, 92 READER_CONTIN, 93 READER_SETTINGS, 94 READER_PRIORITY, 95 } reader_type; 96 unsigned payload_length; 97 union { 98 struct headers_state headers_state; 99 struct skip_state skip_state; 100 struct settings_state settings_state; 101 struct priority_state priority_state; 102 } by_type; 103}; 104 105 106struct lsquic_frame_reader 107{ 108 struct lsquic_mm *fr_mm; 109 struct lshpack_dec *fr_hdec; 110 struct lsquic_stream *fr_stream; 111 fr_stream_read_f fr_read; 112 const struct frame_reader_callbacks 113 *fr_callbacks; 114 void *fr_cb_ctx; 115 const struct lsquic_hset_if *fr_hsi_if; 116 void *fr_hsi_ctx; 117 struct http1x_ctor_ctx fr_h1x_ctor_ctx; 118 /* The the header block is shared between HEADERS, PUSH_PROMISE, and 119 * CONTINUATION frames. It gets added to as block fragments come in. 120 */ 121 unsigned char *fr_header_block; 122#if LSQUIC_CONN_STATS 123 struct conn_stats *fr_conn_stats; 124#endif 125 unsigned fr_header_block_sz; 126 unsigned fr_max_headers_sz; /* 0 means no limit */ 127 enum frame_reader_flags fr_flags; 128 /* Keep some information about previous frame to catch framing errors. 129 */ 130 uint32_t fr_prev_stream_id; 131 enum http_frame_header_flags fr_prev_hfh_flags:8; 132 enum http_frame_type fr_prev_frame_type:8; 133 struct reader_state fr_state; 134}; 135 136 137#define reset_state(fr) do { \ 138 LSQ_DEBUG("reset state"); \ 139 (fr)->fr_state.nh_read = 0; \ 140} while (0) 141 142 143static uint32_t 144fr_get_stream_id (const struct lsquic_frame_reader *fr) 145{ 146 uint32_t stream_id; 147 assert(fr->fr_state.nh_read >= sizeof(fr->fr_state.header)); 148 memcpy(&stream_id, fr->fr_state.header.hfh_stream_id, sizeof(stream_id)); 149 stream_id = ntohl(stream_id); 150 return stream_id; 151} 152 153 154static const char * 155hft_to_string (enum http_frame_type hft) 156{ 157 static const char *const map[] = { 158 [HTTP_FRAME_DATA] = "HTTP_FRAME_DATA", 159 [HTTP_FRAME_HEADERS] = "HTTP_FRAME_HEADERS", 160 [HTTP_FRAME_PRIORITY] = "HTTP_FRAME_PRIORITY", 161 [HTTP_FRAME_RST_STREAM] = "HTTP_FRAME_RST_STREAM", 162 [HTTP_FRAME_SETTINGS] = "HTTP_FRAME_SETTINGS", 163 [HTTP_FRAME_PUSH_PROMISE] = "HTTP_FRAME_PUSH_PROMISE", 164 [HTTP_FRAME_PING] = "HTTP_FRAME_PING", 165 [HTTP_FRAME_GOAWAY] = "HTTP_FRAME_GOAWAY", 166 [HTTP_FRAME_WINDOW_UPDATE] = "HTTP_FRAME_WINDOW_UPDATE", 167 [HTTP_FRAME_CONTINUATION] = "HTTP_FRAME_CONTINUATION", 168 }; 169 if (hft < N_HTTP_FRAME_TYPES) 170 return map[hft]; 171 else 172 return "<unknown>"; 173} 174 175 176struct lsquic_frame_reader * 177lsquic_frame_reader_new (enum frame_reader_flags flags, 178 unsigned max_headers_sz, 179 struct lsquic_mm *mm, 180 struct lsquic_stream *stream, fr_stream_read_f read, 181 struct lshpack_dec *hdec, 182 const struct frame_reader_callbacks *cb, 183 void *frame_reader_cb_ctx, 184#if LSQUIC_CONN_STATS 185 struct conn_stats *conn_stats, 186#endif 187 const struct lsquic_hset_if *hsi_if, void *hsi_ctx) 188{ 189 struct lsquic_frame_reader *fr = malloc(sizeof(*fr)); 190 if (!fr) 191 return NULL; 192 fr->fr_mm = mm; 193 fr->fr_hdec = hdec; 194 fr->fr_flags = flags; 195 fr->fr_stream = stream; 196 fr->fr_read = read; 197 fr->fr_callbacks = cb; 198 fr->fr_cb_ctx = frame_reader_cb_ctx; 199 fr->fr_header_block = NULL; 200 fr->fr_max_headers_sz = max_headers_sz; 201 fr->fr_hsi_if = hsi_if; 202 if (hsi_if == lsquic_http1x_if) 203 { 204 fr->fr_h1x_ctor_ctx = (struct http1x_ctor_ctx) { 205 .conn = lsquic_stream_conn(stream), 206 .max_headers_sz = fr->fr_max_headers_sz, 207 .is_server = fr->fr_flags & FRF_SERVER, 208 }; 209 fr->fr_hsi_ctx = &fr->fr_h1x_ctor_ctx; 210 } 211 else 212 fr->fr_hsi_ctx = hsi_ctx; 213 reset_state(fr); 214#if LSQUIC_CONN_STATS 215 fr->fr_conn_stats = conn_stats; 216#endif 217 return fr; 218} 219 220 221void 222lsquic_frame_reader_destroy (struct lsquic_frame_reader *fr) 223{ 224 free(fr->fr_header_block); 225 free(fr); 226} 227 228 229#define RETURN_ERROR(nread) do { \ 230 assert(nread <= 0); \ 231 if (0 == nread) \ 232 { \ 233 LSQ_INFO("%s: unexpected EOF", __func__); \ 234 return -1; \ 235 } \ 236 else \ 237 { \ 238 LSQ_WARN("%s: error reading from stream: %s", __func__, \ 239 strerror(errno)); \ 240 return -1; \ 241 } \ 242} while (0) 243 244 245static int 246prepare_for_payload (struct lsquic_frame_reader *fr) 247{ 248 uint32_t stream_id; 249 unsigned char *header_block; 250 251 /* RFC 7540, Section 4.1: Ignore R bit: */ 252 fr->fr_state.header.hfh_stream_id[0] &= ~0x80; 253 254 fr->fr_state.payload_length = hfh_get_length(&fr->fr_state.header); 255 256 stream_id = fr_get_stream_id(fr); 257 258 if (fr->fr_state.header.hfh_type != HTTP_FRAME_CONTINUATION && 259 (fr->fr_flags & FRF_HAVE_PREV) && 260 (fr->fr_prev_frame_type == HTTP_FRAME_HEADERS || 261 fr->fr_prev_frame_type == HTTP_FRAME_PUSH_PROMISE || 262 fr->fr_prev_frame_type == HTTP_FRAME_CONTINUATION ) && 263 0 == (fr->fr_prev_hfh_flags & HFHF_END_HEADERS)) 264 { 265 LSQ_INFO("Framing error: expected CONTINUATION frame, got %u", 266 fr->fr_state.header.hfh_type); 267 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 268 FR_ERR_EXPECTED_CONTIN); 269 return -1; 270 } 271 272 switch (fr->fr_state.header.hfh_type) 273 { 274 case HTTP_FRAME_HEADERS: 275 if (fr->fr_max_headers_sz && 276 fr->fr_state.payload_length > fr->fr_max_headers_sz) 277 goto headers_too_large; 278 fr->fr_state.by_type.headers_state.frame_type = HTTP_FRAME_HEADERS; 279 fr->fr_state.by_type.headers_state.nread = 0; 280 fr->fr_state.by_type.headers_state.pesw_nread = 0; 281 fr->fr_state.by_type.headers_state.pseh = 0; 282 if (fr->fr_state.header.hfh_flags & HFHF_PADDED) 283 fr->fr_state.by_type.headers_state.pesw_size = 1; 284 else 285 { 286 fr->fr_state.by_type.headers_state.pad_length = 0; 287 fr->fr_state.by_type.headers_state.pesw_size = 0; 288 } 289 if (fr->fr_state.header.hfh_flags & HFHF_PRIORITY) 290 fr->fr_state.by_type.headers_state.pesw_size += 5; 291 else 292 { 293 fr->fr_state.by_type.headers_state.exclusive = -1; 294 fr->fr_state.by_type.headers_state.oth_stream_id = 0; 295 fr->fr_state.by_type.headers_state.weight = 0; 296 } 297 LSQ_DEBUG("pesw size: %u; payload length: %u; flags: 0x%X", 298 fr->fr_state.by_type.headers_state.pesw_size, 299 fr->fr_state.payload_length, fr->fr_state.header.hfh_flags); 300 if (fr->fr_state.by_type.headers_state.pesw_size > 301 fr->fr_state.payload_length) 302 { 303 LSQ_INFO("Invalid headers frame: payload length too small"); 304 errno = EBADMSG; 305 return -1; 306 } 307 fr->fr_state.reader_type = READER_HEADERS; 308 break; 309 case HTTP_FRAME_PUSH_PROMISE: 310 if (fr->fr_flags & FRF_SERVER) 311 { 312 LSQ_INFO("clients should not push promised"); 313 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 314 FR_ERR_UNEXPECTED_PUSH); 315 return -1; 316 } 317 if (fr->fr_max_headers_sz && 318 fr->fr_state.payload_length > fr->fr_max_headers_sz) 319 goto headers_too_large; 320 fr->fr_state.by_type.headers_state.frame_type = HTTP_FRAME_PUSH_PROMISE; 321 fr->fr_state.by_type.headers_state.nread = 0; 322 fr->fr_state.by_type.headers_state.pesw_nread = 0; 323 fr->fr_state.by_type.headers_state.pseh = 0; 324 if (fr->fr_state.header.hfh_flags & HFHF_PADDED) 325 fr->fr_state.by_type.headers_state.pesw_size = 5; 326 else 327 { 328 fr->fr_state.by_type.headers_state.pad_length = 0; 329 fr->fr_state.by_type.headers_state.pesw_size = 4; 330 } 331 LSQ_DEBUG("pesw size: %u; payload length: %u; flags: 0x%X", 332 fr->fr_state.by_type.headers_state.pesw_size, 333 fr->fr_state.payload_length, fr->fr_state.header.hfh_flags); 334 if (fr->fr_state.by_type.headers_state.pesw_size > 335 fr->fr_state.payload_length) 336 { 337 LSQ_INFO("Invalid headers frame: payload length too small"); 338 errno = EBADMSG; 339 return -1; 340 } 341 fr->fr_state.reader_type = READER_PUSH_PROMISE; 342 break; 343 case HTTP_FRAME_CONTINUATION: 344 if (0 == (fr->fr_flags & FRF_HAVE_PREV)) 345 { 346 LSQ_INFO("Framing error: unexpected CONTINUATION"); 347 return -1; 348 } 349 if (!(fr->fr_prev_frame_type == HTTP_FRAME_HEADERS || 350 fr->fr_prev_frame_type == HTTP_FRAME_PUSH_PROMISE || 351 fr->fr_prev_frame_type == HTTP_FRAME_CONTINUATION)) 352 { 353 LSQ_INFO("Framing error: unexpected CONTINUATION"); 354 return -1; 355 } 356 if (fr->fr_prev_hfh_flags & HFHF_END_HEADERS) 357 { 358 LSQ_INFO("Framing error: unexpected CONTINUATION"); 359 return -1; 360 } 361 if (stream_id != fr->fr_prev_stream_id) 362 { 363 LSQ_INFO("Framing error: CONTINUATION does not have matching " 364 "stream ID"); 365 return -1; 366 } 367 if (fr->fr_state.reader_type == READER_SKIP) 368 goto continue_skipping; 369 fr->fr_header_block_sz += fr->fr_state.payload_length; 370 if (fr->fr_max_headers_sz && 371 fr->fr_header_block_sz > fr->fr_max_headers_sz) 372 { 373 free(fr->fr_header_block); 374 fr->fr_header_block = NULL; 375 goto headers_too_large; 376 } 377 header_block = realloc(fr->fr_header_block, fr->fr_header_block_sz); 378 if (!header_block) 379 { 380 LSQ_WARN("cannot allocate %u bytes for header block", 381 fr->fr_header_block_sz); 382 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 383 FR_ERR_OTHER_ERROR); 384 return -1; 385 } 386 fr->fr_header_block = header_block; 387 fr->fr_state.by_type.headers_state.nread = 0; 388 fr->fr_state.reader_type = READER_CONTIN; 389 break; 390 case HTTP_FRAME_SETTINGS: 391 if (0 == fr->fr_state.payload_length || 392 0 != fr->fr_state.payload_length % 6) 393 { 394 LSQ_INFO("Framing error: %u is not a valid SETTINGS length", 395 fr->fr_state.payload_length); 396 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 397 FR_ERR_INVALID_FRAME_SIZE); 398 return -1; 399 } 400 if (stream_id) 401 { /* RFC 7540, Section 6.5 */ 402 LSQ_INFO("Error: SETTINGS frame should not have stream ID set"); 403 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 404 FR_ERR_NONZERO_STREAM_ID); 405 return -1; 406 } 407 fr->fr_state.by_type.settings_state.nread = 0; 408 fr->fr_state.reader_type = READER_SETTINGS; 409 break; 410 case HTTP_FRAME_PRIORITY: 411 if (fr->fr_state.payload_length != sizeof(struct http_prio_frame)) 412 { 413 LSQ_INFO("Framing error: %u is not a valid PRIORITY length", 414 fr->fr_state.payload_length); 415 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 416 FR_ERR_INVALID_FRAME_SIZE); 417 return -1; 418 } 419 if (!stream_id) 420 { /* RFC 7540, Section 6.3 */ 421 LSQ_INFO("Error: PRIORITY frame must have stream ID set"); 422 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 423 FR_ERR_ZERO_STREAM_ID); 424 return -1; 425 } 426 fr->fr_state.by_type.settings_state.nread = 0; 427 fr->fr_state.reader_type = READER_PRIORITY; 428 break; 429 headers_too_large: 430 LSQ_INFO("headers are too large (%u bytes), skipping", 431 fr->fr_state.payload_length); 432 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 433 FR_ERR_BAD_HEADER); 434 /* fallthru */ 435 continue_skipping: 436 default: 437 fr->fr_state.by_type.skip_state.n_skipped = 0; 438 fr->fr_state.reader_type = READER_SKIP; 439 break; 440 } 441 442 fr->fr_flags |= FRF_HAVE_PREV; 443 fr->fr_prev_frame_type = fr->fr_state.header.hfh_type; 444 fr->fr_prev_hfh_flags = fr->fr_state.header.hfh_flags; 445 fr->fr_prev_stream_id = stream_id; 446 447 return 0; 448} 449 450 451static int 452read_http_frame_header (struct lsquic_frame_reader *fr) 453{ 454 ssize_t nr; 455 size_t ntoread; 456 unsigned char *dst; 457 458 ntoread = sizeof(fr->fr_state.header) - fr->fr_state.nh_read; 459 dst = (unsigned char *) &fr->fr_state.header + fr->fr_state.nh_read; 460 nr = fr->fr_read(fr->fr_stream, dst, ntoread); 461 if (nr <= 0) 462 RETURN_ERROR(nr); 463 fr->fr_state.nh_read += nr; 464 if (fr->fr_state.nh_read == sizeof(fr->fr_state.header)) 465 { 466 LSQ_DEBUG("read in frame %s", hft_to_string(fr->fr_state.header.hfh_type)); 467 return prepare_for_payload(fr); 468 } 469 else 470 return 0; 471} 472 473 474static int 475skip_payload (struct lsquic_frame_reader *fr) 476{ 477 struct skip_state *ss = &fr->fr_state.by_type.skip_state; 478 size_t ntoread = fr->fr_state.payload_length - ss->n_skipped; 479 unsigned char buf[0x100]; 480 if (ntoread > sizeof(buf)) 481 ntoread = sizeof(buf); 482 ssize_t nr = fr->fr_read(fr->fr_stream, buf, ntoread); 483 if (nr <= 0) 484 RETURN_ERROR(nr); 485 ss->n_skipped += nr; 486 if (ss->n_skipped == fr->fr_state.payload_length) 487 reset_state(fr); 488 return 0; 489} 490 491 492static int 493skip_headers_padding (struct lsquic_frame_reader *fr) 494{ 495 unsigned char buf[0x100]; 496 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 497 unsigned pay_and_pad_length = fr->fr_state.payload_length - hs->pesw_size; 498 unsigned ntoread = pay_and_pad_length - hs->nread; 499 assert(ntoread <= sizeof(buf)); 500 if (ntoread > sizeof(buf)) 501 ntoread = sizeof(buf); 502 ssize_t nr = fr->fr_read(fr->fr_stream, buf, ntoread); 503 if (nr <= 0) 504 RETURN_ERROR(nr); 505 hs->nread += nr; 506 if (hs->nread == pay_and_pad_length) 507 reset_state(fr); 508 return 0; 509} 510 511 512static struct lsquic_stream * 513find_target_stream (const struct lsquic_frame_reader *fr) 514{ 515 lsquic_stream_id_t stream_id; 516 struct lsquic_conn *lconn; 517 518 stream_id = fr_get_stream_id(fr); 519 lconn = lsquic_stream_conn(fr->fr_stream); 520 if (lconn->cn_if->ci_get_stream_by_id) 521 return lconn->cn_if->ci_get_stream_by_id(lconn, stream_id); 522 523 return NULL; 524} 525 526 527static void 528skip_headers (struct lsquic_frame_reader *fr) 529{ 530 const unsigned char *comp, *end; 531 void *buf; 532 int s; 533 struct lsxpack_header xhdr; 534 const size_t buf_len = 64 * 1024; 535 536 buf = malloc(buf_len); 537 if (!buf) 538 { 539 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, fr_get_stream_id(fr), 540 FR_ERR_OTHER_ERROR); 541 goto end; 542 } 543 544 comp = fr->fr_header_block; 545 end = comp + fr->fr_header_block_sz; 546 while (comp < end) 547 { 548 lsxpack_header_prepare_decode(&xhdr, buf, 0, buf_len); 549 s = lshpack_dec_decode(fr->fr_hdec, &comp, end, &xhdr); 550 if (s != 0) 551 { 552 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, fr_get_stream_id(fr), 553 FR_ERR_OTHER_ERROR); 554 break; 555 } 556 } 557 558 end: 559 if (buf) 560 free(buf); 561} 562 563 564/* TODO: this function always returns 0. Make it void */ 565static int 566decode_and_pass_payload (struct lsquic_frame_reader *fr) 567{ 568 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 569 const unsigned char *comp, *end; 570 enum frame_reader_error err; 571 int s; 572 uint32_t stream_id32; 573 struct uncompressed_headers *uh = NULL; 574 void *hset = NULL; 575 struct lsxpack_header *hdr = NULL; 576 size_t req_space = 0; 577 lsquic_stream_t *target_stream = NULL; 578 579 if (!(fr->fr_flags & FRF_SERVER)) 580 { 581 target_stream = find_target_stream(fr); 582 /* If the response is for a stream that cannot be found, one of two 583 * things is true: a) the stream has been closed or b) this is an 584 * error. If (a), we discard this header block. We choose to do the 585 * same for (b) instead of erroring out for the sake of simplicity. 586 * There is no way to exploit this behavior. 587 */ 588 if (!target_stream) 589 { 590 skip_headers(fr); 591 return 0; 592 } 593 } 594 hset = fr->fr_hsi_if->hsi_create_header_set(fr->fr_hsi_ctx, target_stream, 595 READER_PUSH_PROMISE == fr->fr_state.reader_type); 596 if (!hset) 597 { 598 err = FR_ERR_OTHER_ERROR; 599 goto stream_error; 600 } 601 602 comp = fr->fr_header_block; 603 end = comp + fr->fr_header_block_sz; 604 605 while (comp < end) 606 { 607 prepare: 608 hdr = fr->fr_hsi_if->hsi_prepare_decode(hset, hdr, req_space); 609 if (!hdr) 610 { 611 err = FR_ERR_OTHER_ERROR; 612 goto stream_error; 613 } 614 s = lshpack_dec_decode(fr->fr_hdec, &comp, end, hdr); 615 if (s == 0) 616 { 617 s = fr->fr_hsi_if->hsi_process_header(hset, hdr); 618 if (s == 0) 619 { 620#if LSQUIC_CONN_STATS 621 fr->fr_conn_stats->in.headers_uncomp += hdr->name_len + 622 hdr->val_len; 623#endif 624 req_space = 0; 625 hdr = NULL; 626 continue; 627 } 628 else if (s > 0) 629 err = FR_ERR_BAD_HEADER; 630 else 631 err = FR_ERR_OTHER_ERROR; 632 } 633 else if (s == LSHPACK_ERR_MORE_BUF) 634 { 635 req_space = hdr->val_len; 636 goto prepare; 637 } 638 else 639 err = FR_ERR_DECOMPRESS; 640 goto stream_error; 641 } 642 assert(comp == end); 643 644 s = fr->fr_hsi_if->hsi_process_header(hset, NULL); 645 if (s != 0) 646 { 647 err = s < 0 ? FR_ERR_OTHER_ERROR : FR_ERR_BAD_HEADER; 648 goto stream_error; 649 } 650 651 uh = calloc(1, sizeof(*uh)); 652 if (!uh) 653 { 654 err = FR_ERR_OTHER_ERROR; 655 goto stream_error; 656 } 657 658 memcpy(&stream_id32, fr->fr_state.header.hfh_stream_id, 659 sizeof(stream_id32)); 660 uh->uh_stream_id = ntohl(stream_id32); 661 uh->uh_oth_stream_id = hs->oth_stream_id; 662 if (HTTP_FRAME_HEADERS == fr->fr_state.by_type.headers_state.frame_type) 663 { 664 uh->uh_weight = hs->weight; 665 uh->uh_exclusive = hs->exclusive; 666 uh->uh_flags = 0; 667 } 668 else 669 { 670 assert(HTTP_FRAME_PUSH_PROMISE == 671 fr->fr_state.by_type.headers_state.frame_type); 672 uh->uh_weight = 0; /* Zero unused value */ 673 uh->uh_exclusive = 0; /* Zero unused value */ 674 uh->uh_flags = UH_PP; 675 } 676 if (fr->fr_state.header.hfh_flags & HFHF_END_STREAM) 677 uh->uh_flags |= UH_FIN; 678 if (fr->fr_hsi_if == lsquic_http1x_if) 679 uh->uh_flags |= UH_H1H; 680 uh->uh_hset = hset; 681 682 EV_LOG_HTTP_HEADERS_IN(LSQUIC_LOG_CONN_ID, fr->fr_flags & FRF_SERVER, uh); 683 if (HTTP_FRAME_HEADERS == fr->fr_state.by_type.headers_state.frame_type) 684 fr->fr_callbacks->frc_on_headers(fr->fr_cb_ctx, uh); 685 else 686 fr->fr_callbacks->frc_on_push_promise(fr->fr_cb_ctx, uh); 687#if LSQUIC_CONN_STATS 688 fr->fr_conn_stats->in.headers_comp += fr->fr_header_block_sz; 689#endif 690 691 return 0; 692 693 stream_error: 694 LSQ_INFO("%s: stream error %u", __func__, err); 695 if (hset) 696 fr->fr_hsi_if->hsi_discard_header_set(hset); 697 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, fr_get_stream_id(fr), err); 698 return 0; 699} 700 701 702static int 703read_headers_block_fragment (struct lsquic_frame_reader *fr) 704{ 705 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 706 ssize_t nr; 707 unsigned payload_length = fr->fr_state.payload_length - hs->pesw_size - 708 hs->pad_length; 709 if (!fr->fr_header_block) 710 { 711 fr->fr_header_block_sz = payload_length; 712 fr->fr_header_block = malloc(payload_length); 713 if (!fr->fr_header_block) 714 return -1; 715 } 716 nr = fr->fr_read(fr->fr_stream, fr->fr_header_block + hs->nread, 717 fr->fr_header_block_sz - hs->nread); 718 if (nr <= 0) 719 { 720 free(fr->fr_header_block); 721 fr->fr_header_block = NULL; 722 RETURN_ERROR(nr); 723 } 724 hs->nread += nr; 725 if (hs->nread == payload_length && 726 (fr->fr_state.header.hfh_flags & HFHF_END_HEADERS)) 727 { 728 int rv = decode_and_pass_payload(fr); 729 free(fr->fr_header_block); 730 fr->fr_header_block = NULL; 731 return rv; 732 } 733 else 734 return 0; 735} 736 737 738static int 739read_headers_block_fragment_and_padding (struct lsquic_frame_reader *fr) 740{ 741 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 742 unsigned payload_length = fr->fr_state.payload_length - hs->pesw_size; 743 int rv; 744 if (hs->nread < payload_length - hs->pad_length) 745 rv = read_headers_block_fragment(fr); 746 else if (payload_length) 747 rv = skip_headers_padding(fr); 748 else 749 { /* Edge case where PESW takes up the whole frame */ 750 fr->fr_header_block_sz = 0; 751 fr->fr_header_block = NULL; 752 rv = 0; 753 } 754 if (0 == rv && hs->nread == payload_length) 755 reset_state(fr); 756 return rv; 757} 758 759 760static int 761read_headers_pesw (struct lsquic_frame_reader *fr) 762{ 763 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 764 ssize_t nr = fr->fr_read(fr->fr_stream, hs->pesw + hs->pesw_nread, 765 hs->pesw_size - hs->pesw_nread); 766 if (nr <= 0) 767 RETURN_ERROR(nr); 768 hs->pesw_nread += nr; 769 if (hs->pesw_nread == hs->pesw_size) 770 { 771 unsigned char *p = hs->pesw; 772 if (fr->fr_state.header.hfh_flags & HFHF_PADDED) 773 hs->pad_length = *p++; 774 if (fr->fr_state.header.hfh_flags & HFHF_PRIORITY) 775 { 776 hs->exclusive = p[0] >> 7; 777 p[0] &= ~0x80; /* Note that we are modifying pesw buffer. */ 778 memcpy(&hs->oth_stream_id, p, sizeof(hs->oth_stream_id)); 779 hs->oth_stream_id = ntohl(hs->oth_stream_id); 780 p += 4; 781 hs->weight = 1 + *p++; 782 } 783 assert(p - hs->pesw == hs->pesw_size); 784 785 if (hs->pesw_size + hs->pad_length > fr->fr_state.payload_length) 786 { 787 LSQ_INFO("Invalid headers frame: pesw length and padding length " 788 "are larger than the payload length"); 789 errno = EBADMSG; 790 return -1; 791 } 792 } 793 return 0; 794} 795 796 797static int 798read_headers (struct lsquic_frame_reader *fr) 799{ 800 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 801 if (hs->pesw_nread < hs->pesw_size) 802 return read_headers_pesw(fr); 803 else 804 return read_headers_block_fragment_and_padding(fr); 805} 806 807 808static int 809read_push_promise_pesw (struct lsquic_frame_reader *fr) 810{ 811 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 812 ssize_t nr = fr->fr_read(fr->fr_stream, hs->pesw + hs->pesw_nread, 813 hs->pesw_size - hs->pesw_nread); 814 if (nr <= 0) 815 RETURN_ERROR(nr); 816 hs->pesw_nread += nr; 817 if (hs->pesw_nread == hs->pesw_size) 818 { 819 unsigned char *p = hs->pesw; 820 if (fr->fr_state.header.hfh_flags & HFHF_PADDED) 821 hs->pad_length = *p++; 822 p[0] &= ~0x80; /* Clear reserved bit. Note: modifying pesw buffer. */ 823 memcpy(&hs->oth_stream_id, p, sizeof(hs->oth_stream_id)); 824 hs->oth_stream_id = ntohl(hs->oth_stream_id); 825 p += 4; 826 assert(p - hs->pesw == hs->pesw_size); 827 if (hs->pesw_size + hs->pad_length > fr->fr_state.payload_length) 828 { 829 LSQ_INFO("Invalid PUSH_PROMISE frame: pesw length and padding length " 830 "are larger than the payload length"); 831 errno = EBADMSG; 832 return -1; 833 } 834 } 835 return 0; 836} 837 838 839static int 840read_push_promise (struct lsquic_frame_reader *fr) 841{ 842 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 843 if (hs->pesw_nread < hs->pesw_size) 844 return read_push_promise_pesw(fr); 845 else 846 return read_headers_block_fragment_and_padding(fr); 847} 848 849 850static int 851read_contin (struct lsquic_frame_reader *fr) 852{ 853 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 854 unsigned ntoread; 855 ssize_t nr; 856 857 ntoread = fr->fr_state.payload_length - hs->nread; 858 nr = fr->fr_read(fr->fr_stream, 859 fr->fr_header_block + fr->fr_header_block_sz - ntoread, 860 ntoread); 861 if (nr <= 0) 862 RETURN_ERROR(nr); 863 hs->nread += nr; 864 if (hs->nread == fr->fr_state.payload_length) 865 { 866 if (fr->fr_state.header.hfh_flags & HFHF_END_HEADERS) 867 { 868 int rv = decode_and_pass_payload(fr); 869 free(fr->fr_header_block); 870 fr->fr_header_block = NULL; 871 reset_state(fr); 872 return rv; 873 } 874 else 875 { 876 reset_state(fr); 877 return 0; 878 } 879 } 880 else 881 return 0; 882} 883 884 885static int 886read_settings (struct lsquic_frame_reader *fr) 887{ 888 struct settings_state *ss = &fr->fr_state.by_type.settings_state; 889 unsigned ntoread; 890 ssize_t nr; 891 uint32_t setting_value; 892 uint16_t setting_id; 893 894 ntoread = sizeof(ss->set_buf) - ss->nread; 895 nr = fr->fr_read(fr->fr_stream, ss->set_buf + ss->nread, ntoread); 896 if (nr <= 0) 897 RETURN_ERROR(nr); 898 ss->nread += nr; 899 if (ss->nread == sizeof(ss->set_buf)) 900 { 901 memcpy(&setting_id, ss->set_buf, 2); 902 memcpy(&setting_value, ss->set_buf + 2, 4); 903 setting_id = ntohs(setting_id); 904 setting_value = ntohl(setting_value); 905 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "read HTTP SETTING %s=%"PRIu32, 906 lsquic_http_setting_id2str(setting_id), setting_value); 907 fr->fr_callbacks->frc_on_settings(fr->fr_cb_ctx, setting_id, 908 setting_value); 909 910 fr->fr_state.payload_length -= sizeof(ss->set_buf); 911 if (0 == fr->fr_state.payload_length) 912 reset_state(fr); 913 else 914 ss->nread = 0; 915 } 916 return 0; 917} 918 919 920static int 921read_priority (struct lsquic_frame_reader *fr) 922{ 923 struct priority_state *ps = &fr->fr_state.by_type.priority_state; 924 unsigned ntoread; 925 ssize_t nr; 926 uint32_t stream_id, dep_stream_id; 927 int exclusive; 928 929 ntoread = sizeof(ps->u.prio_buf) - ps->nread; 930 nr = fr->fr_read(fr->fr_stream, ps->u.prio_buf + ps->nread, ntoread); 931 if (nr <= 0) 932 RETURN_ERROR(nr); 933 ps->nread += nr; 934 if (ps->nread == sizeof(ps->u.prio_buf)) 935 { 936 memcpy(&dep_stream_id, ps->u.prio_frame.hpf_stream_id, 4); 937 dep_stream_id = ntohl(dep_stream_id); 938 exclusive = dep_stream_id >> 31; 939 dep_stream_id &= ~(1UL << 31); 940 stream_id = fr_get_stream_id(fr); 941 if (stream_id == dep_stream_id) 942 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 943 FR_ERR_SELF_DEP_STREAM); 944 else 945 { 946 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "read PRIORITY frame; " 947 "stream: %"PRIu32", dep stream %"PRIu32", exclusive: %d, " 948 "weight: %u", stream_id, dep_stream_id, exclusive, 949 ps->u.prio_frame.hpf_weight + 1); 950 fr->fr_callbacks->frc_on_priority(fr->fr_cb_ctx, stream_id, 951 exclusive, dep_stream_id, ps->u.prio_frame.hpf_weight + 1); 952 } 953 reset_state(fr); 954 } 955 return 0; 956} 957 958 959static int 960read_payload (struct lsquic_frame_reader *fr) 961{ 962 switch (fr->fr_state.reader_type) 963 { 964 case READER_HEADERS: 965 return read_headers(fr); 966 case READER_PUSH_PROMISE: 967 return read_push_promise(fr); 968 case READER_CONTIN: 969 return read_contin(fr); 970 case READER_SETTINGS: 971 return read_settings(fr); 972 case READER_PRIORITY: 973 return read_priority(fr); 974 default: 975 assert(READER_SKIP == fr->fr_state.reader_type); 976 return skip_payload(fr); 977 } 978} 979 980 981int 982lsquic_frame_reader_read (struct lsquic_frame_reader *fr) 983{ 984 if (fr->fr_state.nh_read < sizeof(fr->fr_state.header)) 985 return read_http_frame_header(fr); 986 else 987 return read_payload(fr); 988} 989 990 991size_t 992lsquic_frame_reader_mem_used (const struct lsquic_frame_reader *fr) 993{ 994 size_t size; 995 size = sizeof(*fr); 996 if (fr->fr_header_block) 997 size += fr->fr_header_block_sz; 998 return size; 999} 1000