lsquic_frame_reader.c revision bea64822
1/* Copyright (c) 2017 - 2018 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_ev_log.h" 23 24#define LSQUIC_LOGGER_MODULE LSQLM_FRAME_READER 25#define LSQUIC_LOG_CONN_ID lsquic_conn_id(lsquic_stream_conn(fr->fr_stream)) 26#include "lsquic_logger.h" 27 28 29enum pseudo_header 30{ 31 PSEH_METHOD, 32 PSEH_SCHEME, 33 PSEH_AUTHORITY, 34 PSEH_PATH, 35 PSEH_STATUS, 36 N_PSEH 37}; 38 39#define BIT(x) (1 << (x)) 40 41#define ALL_REQUEST_PSEH (BIT(PSEH_METHOD)|BIT(PSEH_SCHEME)|BIT(PSEH_AUTHORITY)|BIT(PSEH_PATH)) 42#define REQUIRED_REQUEST_PSEH (BIT(PSEH_METHOD)|BIT(PSEH_SCHEME)|BIT(PSEH_PATH)) 43 44#define ALL_SERVER_PSEH BIT(PSEH_STATUS) 45#define REQUIRED_SERVER_PSEH ALL_SERVER_PSEH 46 47#define PSEH_LEN(h) (sizeof(#h) - 5) 48 49 50/* headers_state is used by HEADERS, PUSH_PROMISE, and CONTINUATION frames */ 51struct headers_state 52{ 53 enum http_frame_type 54 frame_type; 55 unsigned nread; /* Not counting pesw, only payload and padding */ 56 57 /* Values parsed out from pesw buffer: */ 58 uint32_t oth_stream_id; /* For HEADERS: ID of stream we depend on; 59 * for PUSH_PROMISE: promised stream ID. 60 */ 61 unsigned short weight; /* HEADERS only */ 62 signed char exclusive; /* HEADERS only */ 63 unsigned char pad_length; 64 65 unsigned char pseh; 66 67 /* PESW: Pad length, Exclusive, Stream Dependency, Weight. This is at 68 * most six bytes for HEADERS frame (RFC 7540, page 33) and five bytes 69 * for PUSH_PROMISE frame (Ibid, p. 40). 70 */ 71 unsigned char pesw_size; 72 unsigned char pesw_nread; 73 unsigned char pesw[6]; 74}; 75 76 77struct settings_state 78{ /* RFC 7540, Section 6.5.1 */ 79 unsigned char nread; 80 unsigned char set_buf[2 + 4]; /* We'll read one setting at a time */ 81}; 82 83 84struct priority_state 85{ /* RFC 7540, Section 6.3 */ 86 unsigned char nread; 87 union { 88 unsigned char prio_buf[sizeof(struct http_prio_frame)]; 89 struct http_prio_frame prio_frame; 90 } u; 91}; 92 93 94struct skip_state 95{ 96 uint32_t n_skipped; 97}; 98 99 100struct reader_state 101{ 102 unsigned nh_read; /* Number of bytes of header read */ 103 struct http_frame_header header; 104 enum { 105 READER_SKIP, 106 READER_HEADERS, 107 READER_PUSH_PROMISE, 108 READER_CONTIN, 109 READER_SETTINGS, 110 READER_PRIORITY, 111 } reader_type; 112 unsigned payload_length; 113 union { 114 struct headers_state headers_state; 115 struct skip_state skip_state; 116 struct settings_state settings_state; 117 struct priority_state priority_state; 118 } by_type; 119}; 120 121 122struct lsquic_frame_reader 123{ 124 struct lsquic_mm *fr_mm; 125 struct lshpack_dec *fr_hdec; 126 struct lsquic_stream *fr_stream; 127 fr_stream_read_f fr_read; 128 const struct frame_reader_callbacks 129 *fr_callbacks; 130 void *fr_cb_ctx; 131 /* The the header block is shared between HEADERS, PUSH_PROMISE, and 132 * CONTINUATION frames. It gets added to as block fragments come in. 133 */ 134 unsigned char *fr_header_block; 135 unsigned fr_header_block_sz; 136 unsigned fr_max_headers_sz; /* 0 means no limit */ 137 enum frame_reader_flags fr_flags; 138 /* Keep some information about previous frame to catch framing errors. 139 */ 140 uint32_t fr_prev_stream_id; 141 enum http_frame_header_flags fr_prev_hfh_flags:8; 142 enum http_frame_type fr_prev_frame_type:8; 143 struct reader_state fr_state; 144}; 145 146 147#define reset_state(fr) do { \ 148 LSQ_DEBUG("reset state"); \ 149 (fr)->fr_state.nh_read = 0; \ 150} while (0) 151 152 153static uint32_t 154fr_get_stream_id (const struct lsquic_frame_reader *fr) 155{ 156 uint32_t stream_id; 157 assert(fr->fr_state.nh_read >= sizeof(fr->fr_state.header)); 158 memcpy(&stream_id, fr->fr_state.header.hfh_stream_id, sizeof(stream_id)); 159 stream_id = ntohl(stream_id); 160 return stream_id; 161} 162 163 164static const char * 165hft_to_string (enum http_frame_type hft) 166{ 167 static const char *const map[] = { 168 [HTTP_FRAME_DATA] = "HTTP_FRAME_DATA", 169 [HTTP_FRAME_HEADERS] = "HTTP_FRAME_HEADERS", 170 [HTTP_FRAME_PRIORITY] = "HTTP_FRAME_PRIORITY", 171 [HTTP_FRAME_RST_STREAM] = "HTTP_FRAME_RST_STREAM", 172 [HTTP_FRAME_SETTINGS] = "HTTP_FRAME_SETTINGS", 173 [HTTP_FRAME_PUSH_PROMISE] = "HTTP_FRAME_PUSH_PROMISE", 174 [HTTP_FRAME_PING] = "HTTP_FRAME_PING", 175 [HTTP_FRAME_GOAWAY] = "HTTP_FRAME_GOAWAY", 176 [HTTP_FRAME_WINDOW_UPDATE] = "HTTP_FRAME_WINDOW_UPDATE", 177 [HTTP_FRAME_CONTINUATION] = "HTTP_FRAME_CONTINUATION", 178 }; 179 if (hft < N_HTTP_FRAME_TYPES) 180 return map[hft]; 181 else 182 return "<unknown>"; 183} 184 185 186struct lsquic_frame_reader * 187lsquic_frame_reader_new (enum frame_reader_flags flags, 188 unsigned max_headers_sz, 189 struct lsquic_mm *mm, 190 struct lsquic_stream *stream, fr_stream_read_f read, 191 struct lshpack_dec *hdec, 192 const struct frame_reader_callbacks *cb, 193 void *frame_reader_cb_ctx) 194{ 195 struct lsquic_frame_reader *fr = malloc(sizeof(*fr)); 196 if (!fr) 197 return NULL; 198 fr->fr_mm = mm; 199 fr->fr_hdec = hdec; 200 fr->fr_flags = flags; 201 fr->fr_stream = stream; 202 fr->fr_read = read; 203 fr->fr_callbacks = cb; 204 fr->fr_cb_ctx = frame_reader_cb_ctx; 205 fr->fr_header_block = NULL; 206 fr->fr_max_headers_sz = max_headers_sz; 207 reset_state(fr); 208 return fr; 209} 210 211 212void 213lsquic_frame_reader_destroy (struct lsquic_frame_reader *fr) 214{ 215 free(fr->fr_header_block); 216 free(fr); 217} 218 219 220#define RETURN_ERROR(nread) do { \ 221 assert(nread <= 0); \ 222 if (0 == nread) \ 223 { \ 224 LSQ_INFO("%s: unexpected EOF", __func__); \ 225 return -1; \ 226 } \ 227 else \ 228 { \ 229 LSQ_WARN("%s: error reading from stream: %s", __func__, \ 230 strerror(errno)); \ 231 return -1; \ 232 } \ 233} while (0) 234 235 236static int 237prepare_for_payload (struct lsquic_frame_reader *fr) 238{ 239 uint32_t stream_id; 240 unsigned char *header_block; 241 242 /* RFC 7540, Section 4.1: Ignore R bit: */ 243 fr->fr_state.header.hfh_stream_id[0] &= ~0x80; 244 245 fr->fr_state.payload_length = hfh_get_length(&fr->fr_state.header); 246 247 stream_id = fr_get_stream_id(fr); 248 249 if (fr->fr_state.header.hfh_type != HTTP_FRAME_CONTINUATION && 250 (fr->fr_flags & FRF_HAVE_PREV) && 251 (fr->fr_prev_frame_type == HTTP_FRAME_HEADERS || 252 fr->fr_prev_frame_type == HTTP_FRAME_PUSH_PROMISE || 253 fr->fr_prev_frame_type == HTTP_FRAME_CONTINUATION ) && 254 0 == (fr->fr_prev_hfh_flags & HFHF_END_HEADERS)) 255 { 256 LSQ_INFO("Framing error: expected CONTINUATION frame, got %u", 257 fr->fr_state.header.hfh_type); 258 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 259 FR_ERR_EXPECTED_CONTIN); 260 return -1; 261 } 262 263 switch (fr->fr_state.header.hfh_type) 264 { 265 case HTTP_FRAME_HEADERS: 266 if (fr->fr_max_headers_sz && 267 fr->fr_state.payload_length > fr->fr_max_headers_sz) 268 goto headers_too_large; 269 fr->fr_state.by_type.headers_state.frame_type = HTTP_FRAME_HEADERS; 270 fr->fr_state.by_type.headers_state.nread = 0; 271 fr->fr_state.by_type.headers_state.pesw_nread = 0; 272 fr->fr_state.by_type.headers_state.pseh = 0; 273 if (fr->fr_state.header.hfh_flags & HFHF_PADDED) 274 fr->fr_state.by_type.headers_state.pesw_size = 1; 275 else 276 { 277 fr->fr_state.by_type.headers_state.pad_length = 0; 278 fr->fr_state.by_type.headers_state.pesw_size = 0; 279 } 280 if (fr->fr_state.header.hfh_flags & HFHF_PRIORITY) 281 fr->fr_state.by_type.headers_state.pesw_size += 5; 282 else 283 { 284 fr->fr_state.by_type.headers_state.exclusive = -1; 285 fr->fr_state.by_type.headers_state.oth_stream_id = 0; 286 fr->fr_state.by_type.headers_state.weight = 0; 287 } 288 LSQ_DEBUG("pesw size: %u; payload length: %u; flags: 0x%X", 289 fr->fr_state.by_type.headers_state.pesw_size, 290 fr->fr_state.payload_length, fr->fr_state.header.hfh_flags); 291 if (fr->fr_state.by_type.headers_state.pesw_size > 292 fr->fr_state.payload_length) 293 { 294 LSQ_INFO("Invalid headers frame: payload length too small"); 295 errno = EBADMSG; 296 return -1; 297 } 298 fr->fr_state.reader_type = READER_HEADERS; 299 break; 300 case HTTP_FRAME_PUSH_PROMISE: 301 if (fr->fr_flags & FRF_SERVER) 302 { 303 LSQ_INFO("clients should not push promised"); 304 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 305 FR_ERR_UNEXPECTED_PUSH); 306 return -1; 307 } 308 if (fr->fr_max_headers_sz && 309 fr->fr_state.payload_length > fr->fr_max_headers_sz) 310 goto headers_too_large; 311 fr->fr_state.by_type.headers_state.frame_type = HTTP_FRAME_PUSH_PROMISE; 312 fr->fr_state.by_type.headers_state.nread = 0; 313 fr->fr_state.by_type.headers_state.pesw_nread = 0; 314 fr->fr_state.by_type.headers_state.pseh = 0; 315 if (fr->fr_state.header.hfh_flags & HFHF_PADDED) 316 fr->fr_state.by_type.headers_state.pesw_size = 5; 317 else 318 { 319 fr->fr_state.by_type.headers_state.pad_length = 0; 320 fr->fr_state.by_type.headers_state.pesw_size = 4; 321 } 322 LSQ_DEBUG("pesw size: %u; payload length: %u; flags: 0x%X", 323 fr->fr_state.by_type.headers_state.pesw_size, 324 fr->fr_state.payload_length, fr->fr_state.header.hfh_flags); 325 if (fr->fr_state.by_type.headers_state.pesw_size > 326 fr->fr_state.payload_length) 327 { 328 LSQ_INFO("Invalid headers frame: payload length too small"); 329 errno = EBADMSG; 330 return -1; 331 } 332 fr->fr_state.reader_type = READER_PUSH_PROMISE; 333 break; 334 case HTTP_FRAME_CONTINUATION: 335 if (0 == (fr->fr_flags & FRF_HAVE_PREV)) 336 { 337 LSQ_INFO("Framing error: unexpected CONTINUATION"); 338 return -1; 339 } 340 if (!(fr->fr_prev_frame_type == HTTP_FRAME_HEADERS || 341 fr->fr_prev_frame_type == HTTP_FRAME_PUSH_PROMISE || 342 fr->fr_prev_frame_type == HTTP_FRAME_CONTINUATION)) 343 { 344 LSQ_INFO("Framing error: unexpected CONTINUATION"); 345 return -1; 346 } 347 if (fr->fr_prev_hfh_flags & HFHF_END_HEADERS) 348 { 349 LSQ_INFO("Framing error: unexpected CONTINUATION"); 350 return -1; 351 } 352 if (stream_id != fr->fr_prev_stream_id) 353 { 354 LSQ_INFO("Framing error: CONTINUATION does not have matching " 355 "stream ID"); 356 return -1; 357 } 358 if (fr->fr_state.reader_type == READER_SKIP) 359 goto continue_skipping; 360 fr->fr_header_block_sz += fr->fr_state.payload_length; 361 if (fr->fr_max_headers_sz && 362 fr->fr_header_block_sz > fr->fr_max_headers_sz) 363 { 364 free(fr->fr_header_block); 365 fr->fr_header_block = NULL; 366 goto headers_too_large; 367 } 368 header_block = realloc(fr->fr_header_block, fr->fr_header_block_sz); 369 if (!header_block) 370 { 371 LSQ_WARN("cannot allocate %u bytes for header block", 372 fr->fr_header_block_sz); 373 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 374 FR_ERR_NOMEM); 375 return -1; 376 } 377 fr->fr_header_block = header_block; 378 fr->fr_state.by_type.headers_state.nread = 0; 379 fr->fr_state.reader_type = READER_CONTIN; 380 break; 381 case HTTP_FRAME_SETTINGS: 382 if (0 == fr->fr_state.payload_length || 383 0 != fr->fr_state.payload_length % 6) 384 { 385 LSQ_INFO("Framing error: %u is not a valid SETTINGS length", 386 fr->fr_state.payload_length); 387 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 388 FR_ERR_INVALID_FRAME_SIZE); 389 return -1; 390 } 391 if (stream_id) 392 { /* RFC 7540, Section 6.5 */ 393 LSQ_INFO("Error: SETTINGS frame should not have stream ID set"); 394 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 395 FR_ERR_NONZERO_STREAM_ID); 396 return -1; 397 } 398 fr->fr_state.by_type.settings_state.nread = 0; 399 fr->fr_state.reader_type = READER_SETTINGS; 400 break; 401 case HTTP_FRAME_PRIORITY: 402 if (fr->fr_state.payload_length != sizeof(struct http_prio_frame)) 403 { 404 LSQ_INFO("Framing error: %u is not a valid PRIORITY length", 405 fr->fr_state.payload_length); 406 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 407 FR_ERR_INVALID_FRAME_SIZE); 408 return -1; 409 } 410 if (!stream_id) 411 { /* RFC 7540, Section 6.3 */ 412 LSQ_INFO("Error: PRIORITY frame must have stream ID set"); 413 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 414 FR_ERR_ZERO_STREAM_ID); 415 return -1; 416 } 417 fr->fr_state.by_type.settings_state.nread = 0; 418 fr->fr_state.reader_type = READER_PRIORITY; 419 break; 420 headers_too_large: 421 LSQ_INFO("headers are too large (%u bytes), skipping", 422 fr->fr_state.payload_length); 423 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 424 FR_ERR_HEADERS_TOO_LARGE); 425 continue_skipping: 426 default: 427 fr->fr_state.by_type.skip_state.n_skipped = 0; 428 fr->fr_state.reader_type = READER_SKIP; 429 break; 430 } 431 432 fr->fr_flags |= FRF_HAVE_PREV; 433 fr->fr_prev_frame_type = fr->fr_state.header.hfh_type; 434 fr->fr_prev_hfh_flags = fr->fr_state.header.hfh_flags; 435 fr->fr_prev_stream_id = stream_id; 436 437 return 0; 438} 439 440 441static int 442read_http_frame_header (struct lsquic_frame_reader *fr) 443{ 444 ssize_t nr; 445 size_t ntoread; 446 unsigned char *dst; 447 448 ntoread = sizeof(fr->fr_state.header) - fr->fr_state.nh_read; 449 dst = (unsigned char *) &fr->fr_state.header + fr->fr_state.nh_read; 450 nr = fr->fr_read(fr->fr_stream, dst, ntoread); 451 if (nr <= 0) 452 RETURN_ERROR(nr); 453 fr->fr_state.nh_read += nr; 454 if (fr->fr_state.nh_read == sizeof(fr->fr_state.header)) 455 { 456 LSQ_DEBUG("read in frame %s", hft_to_string(fr->fr_state.header.hfh_type)); 457 return prepare_for_payload(fr); 458 } 459 else 460 return 0; 461} 462 463 464static int 465skip_payload (struct lsquic_frame_reader *fr) 466{ 467 struct skip_state *ss = &fr->fr_state.by_type.skip_state; 468 size_t ntoread = fr->fr_state.payload_length - ss->n_skipped; 469 unsigned char buf[0x100]; 470 if (ntoread > sizeof(buf)) 471 ntoread = sizeof(buf); 472 ssize_t nr = fr->fr_read(fr->fr_stream, buf, ntoread); 473 if (nr <= 0) 474 RETURN_ERROR(nr); 475 ss->n_skipped += nr; 476 if (ss->n_skipped == fr->fr_state.payload_length) 477 reset_state(fr); 478 return 0; 479} 480 481 482static int 483skip_headers_padding (struct lsquic_frame_reader *fr) 484{ 485 unsigned char buf[0x100]; 486 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 487 unsigned pay_and_pad_length = fr->fr_state.payload_length - hs->pesw_size; 488 unsigned ntoread = pay_and_pad_length - hs->nread; 489 assert(ntoread <= sizeof(buf)); 490 if (ntoread > sizeof(buf)) 491 ntoread = sizeof(buf); 492 ssize_t nr = fr->fr_read(fr->fr_stream, buf, ntoread); 493 if (nr <= 0) 494 RETURN_ERROR(nr); 495 hs->nread += nr; 496 if (hs->nread == pay_and_pad_length) 497 reset_state(fr); 498 return 0; 499} 500 501 502struct header_writer_ctx 503{ 504 struct uncompressed_headers *uh; 505 struct lsquic_mm *mm; 506 char *buf; 507 char *cookie_val; 508 unsigned cookie_sz, cookie_nalloc; 509 unsigned max_headers_sz, 510 headers_sz, 511 w_off; 512 enum { 513 HWC_EXPECT_COLON = (1 << 0), 514 HWC_SEEN_HOST = (1 << 1), 515 } hwc_flags; 516 enum pseudo_header pseh_mask; 517 char *pseh_bufs[N_PSEH]; 518 lshpack_strlen_t name_len, 519 val_len; 520}; 521 522 523#define HWC_PSEH_LEN(hwc, ph) ((int) strlen((hwc)->pseh_bufs[ph])) 524 525#define HWC_PSEH_VAL(hwc, ph) ((hwc)->pseh_bufs[ph]) 526 527static int 528hwc_uh_write (struct header_writer_ctx *hwc, const void *buf, size_t sz) 529{ 530 struct uncompressed_headers *uh; 531 532 if (hwc->w_off + sz > hwc->headers_sz) 533 { 534 if (hwc->headers_sz * 2 >= hwc->w_off + sz) 535 hwc->headers_sz *= 2; 536 else 537 hwc->headers_sz = hwc->w_off + sz; 538 uh = realloc(hwc->uh, sizeof(*hwc->uh) + hwc->headers_sz); 539 if (!uh) 540 return -1; 541 hwc->uh = uh; 542 } 543 memcpy(hwc->uh->uh_headers + hwc->w_off, buf, sz); 544 hwc->w_off += sz; 545 return 0; 546} 547 548 549static enum frame_reader_error 550init_hwc (struct header_writer_ctx *hwc, struct lsquic_mm *mm, 551 unsigned max_headers_sz, unsigned headers_block_sz) 552{ 553 memset(hwc, 0, sizeof(*hwc)); 554 hwc->hwc_flags = HWC_EXPECT_COLON; 555 hwc->max_headers_sz = max_headers_sz; 556 hwc->headers_sz = headers_block_sz * 4; /* A guess */ 557 hwc->uh = malloc(sizeof(*hwc->uh) + hwc->headers_sz); 558 if (!hwc->uh) 559 return FR_ERR_NOMEM; 560 hwc->mm = mm; 561 hwc->buf = lsquic_mm_get_16k(mm); 562 if (!hwc->buf) 563 return FR_ERR_NOMEM; 564 return 0; 565} 566 567 568static void 569deinit_hwc (struct header_writer_ctx *hwc) 570{ 571 unsigned i; 572 for (i = 0; i < sizeof(hwc->pseh_bufs) / sizeof(hwc->pseh_bufs[0]); ++i) 573 if (hwc->pseh_bufs[i]) 574 free(hwc->pseh_bufs[i]); 575 if (hwc->cookie_val) 576 free(hwc->cookie_val); 577 free(hwc->uh); 578 if (hwc->buf) 579 lsquic_mm_put_16k(hwc->mm, hwc->buf); 580} 581 582 583static enum frame_reader_error 584save_pseudo_header (const struct lsquic_frame_reader *fr, 585 struct header_writer_ctx *hwc, enum pseudo_header ph) 586{ 587 if (0 == (hwc->pseh_mask & BIT(ph))) 588 { 589 assert(!hwc->pseh_bufs[ph]); 590 hwc->pseh_bufs[ph] = malloc(hwc->val_len + 1); 591 if (!hwc->pseh_bufs[ph]) 592 return FR_ERR_NOMEM; 593 hwc->pseh_mask |= BIT(ph); 594 memcpy(hwc->pseh_bufs[ph], hwc->buf + hwc->name_len, hwc->val_len); 595 hwc->pseh_bufs[ph][hwc->val_len] = '\0'; 596 return 0; 597 } 598 else 599 { 600 LSQ_INFO("header %u is already present", ph); 601 return FR_ERR_DUPLICATE_PSEH; 602 } 603} 604 605 606static enum frame_reader_error 607add_pseudo_header_to_uh (const struct lsquic_frame_reader *fr, 608 struct header_writer_ctx *hwc) 609{ 610 if (!(hwc->hwc_flags & HWC_EXPECT_COLON)) 611 { 612 LSQ_INFO("unexpected colon"); 613 return FR_ERR_MISPLACED_PSEH; 614 } 615 616 switch (hwc->name_len) 617 { 618 case 5: 619 if (0 == memcmp(hwc->buf, ":path", 5)) 620 return save_pseudo_header(fr, hwc, PSEH_PATH); 621 break; 622 case 7: 623 switch (hwc->buf[2]) 624 { 625 case 'c': 626 if (0 == memcmp(hwc->buf, ":scheme", 7)) 627 return save_pseudo_header(fr, hwc, PSEH_SCHEME); 628 break; 629 case 'e': 630 if (0 == memcmp(hwc->buf, ":method", 7)) 631 return save_pseudo_header(fr, hwc, PSEH_METHOD); 632 break; 633 case 't': 634 if (0 == memcmp(hwc->buf, ":status", 7)) 635 return save_pseudo_header(fr, hwc, PSEH_STATUS); 636 break; 637 } 638 break; 639 case 10: 640 if (0 == memcmp(hwc->buf, ":authority", 10)) 641 return save_pseudo_header(fr, hwc, PSEH_AUTHORITY); 642 break; 643 } 644 645 LSQ_INFO("unknown pseudo-header `%.*s'", hwc->name_len, hwc->buf); 646 return FR_ERR_UNKNOWN_PSEH; 647} 648 649 650#define HTTP_CODE_LEN 3 651 652static const char * 653code_str_to_reason (const char code_str[HTTP_CODE_LEN]) 654{ 655 /* RFC 7231, Section 6: */ 656 static const char *const http_reason_phrases[] = 657 { 658 #define HTTP_REASON_CODE(code, reason) [code - 100] = reason 659 HTTP_REASON_CODE(100, "Continue"), 660 HTTP_REASON_CODE(101, "Switching Protocols"), 661 HTTP_REASON_CODE(200, "OK"), 662 HTTP_REASON_CODE(201, "Created"), 663 HTTP_REASON_CODE(202, "Accepted"), 664 HTTP_REASON_CODE(203, "Non-Authoritative Information"), 665 HTTP_REASON_CODE(204, "No Content"), 666 HTTP_REASON_CODE(205, "Reset Content"), 667 HTTP_REASON_CODE(206, "Partial Content"), 668 HTTP_REASON_CODE(300, "Multiple Choices"), 669 HTTP_REASON_CODE(301, "Moved Permanently"), 670 HTTP_REASON_CODE(302, "Found"), 671 HTTP_REASON_CODE(303, "See Other"), 672 HTTP_REASON_CODE(304, "Not Modified"), 673 HTTP_REASON_CODE(305, "Use Proxy"), 674 HTTP_REASON_CODE(307, "Temporary Redirect"), 675 HTTP_REASON_CODE(400, "Bad Request"), 676 HTTP_REASON_CODE(401, "Unauthorized"), 677 HTTP_REASON_CODE(402, "Payment Required"), 678 HTTP_REASON_CODE(403, "Forbidden"), 679 HTTP_REASON_CODE(404, "Not Found"), 680 HTTP_REASON_CODE(405, "Method Not Allowed"), 681 HTTP_REASON_CODE(406, "Not Acceptable"), 682 HTTP_REASON_CODE(407, "Proxy Authentication Required"), 683 HTTP_REASON_CODE(408, "Request Timeout"), 684 HTTP_REASON_CODE(409, "Conflict"), 685 HTTP_REASON_CODE(410, "Gone"), 686 HTTP_REASON_CODE(411, "Length Required"), 687 HTTP_REASON_CODE(412, "Precondition Failed"), 688 HTTP_REASON_CODE(413, "Payload Too Large"), 689 HTTP_REASON_CODE(414, "URI Too Long"), 690 HTTP_REASON_CODE(415, "Unsupported Media Type"), 691 HTTP_REASON_CODE(416, "Range Not Satisfiable"), 692 HTTP_REASON_CODE(417, "Expectation Failed"), 693 HTTP_REASON_CODE(426, "Upgrade Required"), 694 HTTP_REASON_CODE(500, "Internal Server Error"), 695 HTTP_REASON_CODE(501, "Not Implemented"), 696 HTTP_REASON_CODE(502, "Bad Gateway"), 697 HTTP_REASON_CODE(503, "Service Unavailable"), 698 HTTP_REASON_CODE(504, "Gateway Timeout"), 699 HTTP_REASON_CODE(505, "HTTP Version Not Supported"), 700 #undef HTTP_REASON_CODE 701 }; 702 703 long code; 704 char code_buf[HTTP_CODE_LEN + 1]; 705 706 memcpy(code_buf, code_str, HTTP_CODE_LEN); 707 code_buf[HTTP_CODE_LEN] = '\0'; 708 code = strtol(code_buf, NULL, 10) - 100; 709 if (code > 0 && code < (long) (sizeof(http_reason_phrases) / 710 sizeof(http_reason_phrases[0]))) 711 return http_reason_phrases[code]; 712 else 713 return NULL; 714} 715 716 717static enum frame_reader_error 718convert_response_pseudo_headers (const struct lsquic_frame_reader *fr, 719 struct header_writer_ctx *hwc) 720{ 721 if ((hwc->pseh_mask & REQUIRED_SERVER_PSEH) != REQUIRED_SERVER_PSEH) 722 { 723 LSQ_INFO("not all response pseudo-headers are specified"); 724 return FR_ERR_INCOMPL_RESP_PSEH; 725 } 726 if (hwc->pseh_mask & ALL_REQUEST_PSEH) 727 { 728 LSQ_INFO("response pseudo-headers contain request-only headers"); 729 return FR_ERR_UNNEC_REQ_PSEH; 730 } 731 732 const char *code_str, *reason; 733 int code_len; 734 735 code_str = HWC_PSEH_VAL(hwc, PSEH_STATUS); 736 code_len = HWC_PSEH_LEN(hwc, PSEH_STATUS); 737 738#define HWC_UH_WRITE(h, buf, sz) do { \ 739 if (0 != hwc_uh_write(h, buf, sz)) \ 740 return FR_ERR_NOMEM; \ 741} while (0) 742 743 HWC_UH_WRITE(hwc, "HTTP/1.1 ", 9); 744 HWC_UH_WRITE(hwc, code_str, code_len); 745 if (HTTP_CODE_LEN == code_len && (reason = code_str_to_reason(code_str))) 746 { 747 HWC_UH_WRITE(hwc, " ", 1); 748 HWC_UH_WRITE(hwc, reason, strlen(reason)); 749 HWC_UH_WRITE(hwc, "\r\n", 2); 750 } 751 else 752 HWC_UH_WRITE(hwc, " \r\n", 3); 753 if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz) 754 { 755 LSQ_INFO("headers too large"); 756 return FR_ERR_HEADERS_TOO_LARGE; 757 } 758 return 0; 759 760#undef HWC_UH_WRITE 761} 762 763 764static enum frame_reader_error 765convert_request_pseudo_headers (const struct lsquic_frame_reader *fr, 766 struct header_writer_ctx *hwc) 767{ 768 if ((hwc->pseh_mask & REQUIRED_REQUEST_PSEH) != REQUIRED_REQUEST_PSEH) 769 { 770 LSQ_INFO("not all request pseudo-headers are specified"); 771 return FR_ERR_INCOMPL_REQ_PSEH; 772 } 773 if (hwc->pseh_mask & ALL_SERVER_PSEH) 774 { 775 LSQ_INFO("request pseudo-headers contain response-only headers"); 776 return FR_ERR_UNNEC_RESP_PSEH; 777 } 778 779#define HWC_UH_WRITE(h, buf, sz) do { \ 780 if (0 != hwc_uh_write(h, buf, sz)) \ 781 return FR_ERR_NOMEM; \ 782} while (0) 783 784 HWC_UH_WRITE(hwc, HWC_PSEH_VAL(hwc, PSEH_METHOD), HWC_PSEH_LEN(hwc, PSEH_METHOD)); 785 HWC_UH_WRITE(hwc, " ", 1); 786 HWC_UH_WRITE(hwc, HWC_PSEH_VAL(hwc, PSEH_PATH), HWC_PSEH_LEN(hwc, PSEH_PATH)); 787 HWC_UH_WRITE(hwc, " HTTP/1.1\r\n", 11); 788 789 if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz) 790 { 791 LSQ_INFO("headers too large"); 792 return FR_ERR_HEADERS_TOO_LARGE; 793 } 794 795 return 0; 796 797#undef HWC_UH_WRITE 798} 799 800 801static enum frame_reader_error 802convert_pseudo_headers (const struct lsquic_frame_reader *fr, 803 struct header_writer_ctx *hwc) 804{ 805 /* We are *reading* the message. Thus, a server expects a request, and a 806 * client expects a response. Unless we receive a push promise from the 807 * server, in which case this should also be a request. 808 */ 809 if ((fr->fr_flags & FRF_SERVER) || 810 READER_PUSH_PROMISE == fr->fr_state.reader_type) 811 return convert_request_pseudo_headers(fr, hwc); 812 else 813 return convert_response_pseudo_headers(fr, hwc); 814} 815 816 817static enum frame_reader_error 818save_cookie (struct header_writer_ctx *hwc) 819{ 820 char *cookie_val; 821 822 if (0 == hwc->cookie_sz) 823 { 824 hwc->cookie_nalloc = hwc->cookie_sz = hwc->val_len; 825 cookie_val = malloc(hwc->cookie_nalloc); 826 if (!cookie_val) 827 return FR_ERR_NOMEM; 828 hwc->cookie_val = cookie_val; 829 memcpy(hwc->cookie_val, hwc->buf + hwc->name_len, hwc->val_len); 830 } 831 else 832 { 833 hwc->cookie_sz += hwc->val_len + 2 /* "; " */; 834 if (hwc->cookie_sz > hwc->cookie_nalloc) 835 { 836 hwc->cookie_nalloc = hwc->cookie_nalloc * 2 + hwc->val_len + 2; 837 cookie_val = realloc(hwc->cookie_val, hwc->cookie_nalloc); 838 if (!cookie_val) 839 return FR_ERR_NOMEM; 840 hwc->cookie_val = cookie_val; 841 } 842 memcpy(hwc->cookie_val + hwc->cookie_sz - hwc->val_len - 2, "; ", 2); 843 memcpy(hwc->cookie_val + hwc->cookie_sz - hwc->val_len, 844 hwc->buf + hwc->name_len, hwc->val_len); 845 } 846 847 return 0; 848} 849 850 851static enum frame_reader_error 852add_real_header_to_uh (const struct lsquic_frame_reader *fr, 853 struct header_writer_ctx *hwc) 854{ 855 enum frame_reader_error err; 856 unsigned i; 857 int n_upper; 858 859 if (hwc->hwc_flags & HWC_EXPECT_COLON) 860 { 861 if (0 != (err = convert_pseudo_headers(fr, hwc))) 862 return err; 863 hwc->hwc_flags &= ~HWC_EXPECT_COLON; 864 } 865 866 if (4 == hwc->name_len && 0 == memcmp(hwc->buf, "host", 4)) 867 hwc->hwc_flags |= HWC_SEEN_HOST; 868 869 n_upper = 0; 870 for (i = 0; i < hwc->name_len; ++i) 871 n_upper += isupper(hwc->buf[i]); 872 if (n_upper > 0) 873 { 874 LSQ_INFO("Header name `%.*s' contains uppercase letters", 875 hwc->name_len, hwc->buf); 876 return FR_ERR_UPPERCASE_HEADER; 877 } 878 879 if (6 == hwc->name_len && memcmp(hwc->buf, "cookie", 6) == 0) 880 { 881 return save_cookie(hwc); 882 } 883 884#define HWC_UH_WRITE(h, buf, sz) do { \ 885 if (0 != hwc_uh_write(h, buf, sz)) \ 886 return FR_ERR_NOMEM; \ 887} while (0) 888 889 HWC_UH_WRITE(hwc, hwc->buf, hwc->name_len); 890 HWC_UH_WRITE(hwc, ": ", 2); 891 HWC_UH_WRITE(hwc, hwc->buf + hwc->name_len, hwc->val_len); 892 HWC_UH_WRITE(hwc, "\r\n", 2); 893 894 if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz) 895 { 896 LSQ_INFO("headers too large"); 897 return FR_ERR_HEADERS_TOO_LARGE; 898 } 899 900 return 0; 901 902#undef HWC_UH_WRITE 903} 904 905 906static enum frame_reader_error 907add_header_to_uh (const struct lsquic_frame_reader *fr, 908 struct header_writer_ctx *hwc) 909{ 910 LSQ_DEBUG("Got header '%.*s': '%.*s'", hwc->name_len, hwc->buf, 911 hwc->val_len, hwc->buf + hwc->name_len); 912 if (':' == hwc->buf[0]) 913 return add_pseudo_header_to_uh(fr, hwc); 914 else 915 return add_real_header_to_uh(fr, hwc); 916} 917 918 919static int 920decode_and_pass_payload (struct lsquic_frame_reader *fr) 921{ 922 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 923 const unsigned char *comp, *end; 924 enum frame_reader_error err; 925 int s; 926 struct header_writer_ctx hwc; 927 928 err = init_hwc(&hwc, fr->fr_mm, fr->fr_max_headers_sz, fr->fr_header_block_sz); 929 if (0 != err) 930 goto stream_error; 931 932 comp = fr->fr_header_block; 933 end = comp + fr->fr_header_block_sz; 934 935 while (comp < end) 936 { 937 s = lshpack_dec_decode(fr->fr_hdec, &comp, end, 938 hwc.buf, hwc.buf + 16 * 1024, 939 &hwc.name_len, &hwc.val_len); 940 if (s == 0) 941 { 942 err = add_header_to_uh(fr, &hwc); 943 if (err == 0) 944 continue; 945 } 946 else 947 err = FR_ERR_DECOMPRESS; 948 goto stream_error; 949 } 950 assert(comp == end); 951 952 if (hwc.hwc_flags & HWC_EXPECT_COLON) 953 { 954 err = convert_pseudo_headers(fr, &hwc); 955 if (0 != err) 956 goto stream_error; 957 hwc.hwc_flags &= ~HWC_EXPECT_COLON; 958 } 959 960 961#define HWC_UH_WRITE(h, buf, sz) do { \ 962 err = hwc_uh_write(h, buf, sz); \ 963 if (0 != err) \ 964 goto stream_error; \ 965} while (0) 966 967 if ((hwc.pseh_mask & BIT(PSEH_AUTHORITY)) && 968 0 == (hwc.hwc_flags & HWC_SEEN_HOST)) 969 { 970 LSQ_DEBUG("Setting 'Host: %.*s'", HWC_PSEH_LEN(&hwc, PSEH_AUTHORITY), 971 HWC_PSEH_VAL(&hwc, PSEH_AUTHORITY)); 972 HWC_UH_WRITE(&hwc, "Host: ", 6); 973 HWC_UH_WRITE(&hwc, HWC_PSEH_VAL(&hwc, PSEH_AUTHORITY), HWC_PSEH_LEN(&hwc, PSEH_AUTHORITY)); 974 HWC_UH_WRITE(&hwc, "\r\n", 2); 975 } 976 977 if (hwc.cookie_val) 978 { 979 LSQ_DEBUG("Setting 'Cookie: %.*s'", hwc.cookie_sz, hwc.cookie_val); 980 HWC_UH_WRITE(&hwc, "Cookie: ", 8); 981 HWC_UH_WRITE(&hwc, hwc.cookie_val, hwc.cookie_sz); 982 HWC_UH_WRITE(&hwc, "\r\n", 2); 983 } 984 985 HWC_UH_WRITE(&hwc, "\r\n", 2 + 1 /* NUL byte */); 986 hwc.w_off -= 1; /* Do not count NUL byte */ 987 988 if (hwc.max_headers_sz && hwc.w_off > hwc.max_headers_sz) 989 { 990 LSQ_INFO("headers too large"); 991 err = FR_ERR_HEADERS_TOO_LARGE; 992 goto stream_error; 993 } 994 995 memcpy(&hwc.uh->uh_stream_id, fr->fr_state.header.hfh_stream_id, 996 sizeof(hwc.uh->uh_stream_id)); 997 hwc.uh->uh_stream_id = ntohl(hwc.uh->uh_stream_id); 998 hwc.uh->uh_size = hwc.w_off; 999 hwc.uh->uh_oth_stream_id = hs->oth_stream_id; 1000 hwc.uh->uh_off = 0; 1001 if (HTTP_FRAME_HEADERS == fr->fr_state.by_type.headers_state.frame_type) 1002 { 1003 hwc.uh->uh_weight = hs->weight; 1004 hwc.uh->uh_exclusive = hs->exclusive; 1005 hwc.uh->uh_flags = 0; 1006 } 1007 else 1008 { 1009 assert(HTTP_FRAME_PUSH_PROMISE == 1010 fr->fr_state.by_type.headers_state.frame_type); 1011 hwc.uh->uh_weight = 0; /* Zero unused value */ 1012 hwc.uh->uh_exclusive = 0; /* Zero unused value */ 1013 hwc.uh->uh_flags = UH_PP; 1014 } 1015 if (fr->fr_state.header.hfh_flags & HFHF_END_STREAM) 1016 hwc.uh->uh_flags |= UH_FIN; 1017 1018 EV_LOG_HTTP_HEADERS_IN(LSQUIC_LOG_CONN_ID, fr->fr_flags & FRF_SERVER, 1019 hwc.uh); 1020 if (HTTP_FRAME_HEADERS == fr->fr_state.by_type.headers_state.frame_type) 1021 fr->fr_callbacks->frc_on_headers(fr->fr_cb_ctx, hwc.uh); 1022 else 1023 fr->fr_callbacks->frc_on_push_promise(fr->fr_cb_ctx, hwc.uh); 1024 1025 hwc.uh = NULL; 1026 1027 deinit_hwc(&hwc); 1028 1029 return 0; 1030 1031 stream_error: 1032 LSQ_INFO("%s: stream error %u", __func__, err); 1033 deinit_hwc(&hwc); 1034 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, fr_get_stream_id(fr), err); 1035 return 0; 1036 1037#undef HWC_UH_WRITE 1038} 1039 1040 1041static int 1042read_headers_block_fragment (struct lsquic_frame_reader *fr) 1043{ 1044 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 1045 ssize_t nr; 1046 unsigned payload_length = fr->fr_state.payload_length - hs->pesw_size - 1047 hs->pad_length; 1048 if (!fr->fr_header_block) 1049 { 1050 fr->fr_header_block_sz = payload_length; 1051 fr->fr_header_block = malloc(payload_length); 1052 if (!fr->fr_header_block) 1053 return -1; 1054 } 1055 nr = fr->fr_read(fr->fr_stream, fr->fr_header_block + hs->nread, 1056 fr->fr_header_block_sz - hs->nread); 1057 if (nr <= 0) 1058 { 1059 free(fr->fr_header_block); 1060 fr->fr_header_block = NULL; 1061 RETURN_ERROR(nr); 1062 } 1063 hs->nread += nr; 1064 if (hs->nread == payload_length && 1065 (fr->fr_state.header.hfh_flags & HFHF_END_HEADERS)) 1066 { 1067 int rv = decode_and_pass_payload(fr); 1068 free(fr->fr_header_block); 1069 fr->fr_header_block = NULL; 1070 return rv; 1071 } 1072 else 1073 return 0; 1074} 1075 1076 1077static int 1078read_headers_block_fragment_and_padding (struct lsquic_frame_reader *fr) 1079{ 1080 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 1081 unsigned payload_length = fr->fr_state.payload_length - hs->pesw_size; 1082 int rv; 1083 if (hs->nread < payload_length - hs->pad_length) 1084 rv = read_headers_block_fragment(fr); 1085 else if (payload_length) 1086 rv = skip_headers_padding(fr); 1087 else 1088 { /* Edge case where PESW takes up the whole frame */ 1089 fr->fr_header_block_sz = 0; 1090 fr->fr_header_block = NULL; 1091 rv = 0; 1092 } 1093 if (0 == rv && hs->nread == payload_length) 1094 reset_state(fr); 1095 return rv; 1096} 1097 1098 1099static int 1100read_headers_pesw (struct lsquic_frame_reader *fr) 1101{ 1102 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 1103 ssize_t nr = fr->fr_read(fr->fr_stream, hs->pesw + hs->pesw_nread, 1104 hs->pesw_size - hs->pesw_nread); 1105 if (nr <= 0) 1106 RETURN_ERROR(nr); 1107 hs->pesw_nread += nr; 1108 if (hs->pesw_nread == hs->pesw_size) 1109 { 1110 unsigned char *p = hs->pesw; 1111 if (fr->fr_state.header.hfh_flags & HFHF_PADDED) 1112 hs->pad_length = *p++; 1113 if (fr->fr_state.header.hfh_flags & HFHF_PRIORITY) 1114 { 1115 hs->exclusive = p[0] >> 7; 1116 p[0] &= ~0x80; /* Note that we are modifying pesw buffer. */ 1117 memcpy(&hs->oth_stream_id, p, sizeof(hs->oth_stream_id)); 1118 hs->oth_stream_id = ntohl(hs->oth_stream_id); 1119 p += 4; 1120 hs->weight = 1 + *p++; 1121 } 1122 assert(p - hs->pesw == hs->pesw_size); 1123 1124 if (hs->pesw_size + hs->pad_length > fr->fr_state.payload_length) 1125 { 1126 LSQ_INFO("Invalid headers frame: pesw length and padding length " 1127 "are larger than the payload length"); 1128 errno = EBADMSG; 1129 return -1; 1130 } 1131 } 1132 return 0; 1133} 1134 1135 1136static int 1137read_headers (struct lsquic_frame_reader *fr) 1138{ 1139 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 1140 if (hs->pesw_nread < hs->pesw_size) 1141 return read_headers_pesw(fr); 1142 else 1143 return read_headers_block_fragment_and_padding(fr); 1144} 1145 1146 1147static int 1148read_push_promise_pesw (struct lsquic_frame_reader *fr) 1149{ 1150 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 1151 ssize_t nr = fr->fr_read(fr->fr_stream, hs->pesw + hs->pesw_nread, 1152 hs->pesw_size - hs->pesw_nread); 1153 if (nr <= 0) 1154 RETURN_ERROR(nr); 1155 hs->pesw_nread += nr; 1156 if (hs->pesw_nread == hs->pesw_size) 1157 { 1158 unsigned char *p = hs->pesw; 1159 if (fr->fr_state.header.hfh_flags & HFHF_PADDED) 1160 hs->pad_length = *p++; 1161 p[0] &= ~0x80; /* Clear reserved bit. Note: modifying pesw buffer. */ 1162 memcpy(&hs->oth_stream_id, p, sizeof(hs->oth_stream_id)); 1163 hs->oth_stream_id = ntohl(hs->oth_stream_id); 1164 p += 4; 1165 assert(p - hs->pesw == hs->pesw_size); 1166 if (hs->pesw_size + hs->pad_length > fr->fr_state.payload_length) 1167 { 1168 LSQ_INFO("Invalid PUSH_PROMISE frame: pesw length and padding length " 1169 "are larger than the payload length"); 1170 errno = EBADMSG; 1171 return -1; 1172 } 1173 } 1174 return 0; 1175} 1176 1177 1178static int 1179read_push_promise (struct lsquic_frame_reader *fr) 1180{ 1181 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 1182 if (hs->pesw_nread < hs->pesw_size) 1183 return read_push_promise_pesw(fr); 1184 else 1185 return read_headers_block_fragment_and_padding(fr); 1186} 1187 1188 1189static int 1190read_contin (struct lsquic_frame_reader *fr) 1191{ 1192 struct headers_state *hs = &fr->fr_state.by_type.headers_state; 1193 unsigned ntoread; 1194 ssize_t nr; 1195 1196 ntoread = fr->fr_state.payload_length - hs->nread; 1197 nr = fr->fr_read(fr->fr_stream, 1198 fr->fr_header_block + fr->fr_header_block_sz - ntoread, 1199 ntoread); 1200 if (nr <= 0) 1201 RETURN_ERROR(nr); 1202 hs->nread += nr; 1203 if (hs->nread == fr->fr_state.payload_length) 1204 { 1205 if (fr->fr_state.header.hfh_flags & HFHF_END_HEADERS) 1206 { 1207 int rv = decode_and_pass_payload(fr); 1208 free(fr->fr_header_block); 1209 fr->fr_header_block = NULL; 1210 reset_state(fr); 1211 return rv; 1212 } 1213 else 1214 { 1215 reset_state(fr); 1216 return 0; 1217 } 1218 } 1219 else 1220 return 0; 1221} 1222 1223 1224static int 1225read_settings (struct lsquic_frame_reader *fr) 1226{ 1227 struct settings_state *ss = &fr->fr_state.by_type.settings_state; 1228 unsigned ntoread; 1229 ssize_t nr; 1230 uint32_t setting_value; 1231 uint16_t setting_id; 1232 1233 ntoread = sizeof(ss->set_buf) - ss->nread; 1234 nr = fr->fr_read(fr->fr_stream, ss->set_buf + ss->nread, ntoread); 1235 if (nr <= 0) 1236 RETURN_ERROR(nr); 1237 ss->nread += nr; 1238 if (ss->nread == sizeof(ss->set_buf)) 1239 { 1240 memcpy(&setting_id, ss->set_buf, 2); 1241 memcpy(&setting_value, ss->set_buf + 2, 4); 1242 setting_id = ntohs(setting_id); 1243 setting_value = ntohl(setting_value); 1244 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "read HTTP SETTING %s=%"PRIu32, 1245 lsquic_http_setting_id2str(setting_id), setting_value); 1246 fr->fr_callbacks->frc_on_settings(fr->fr_cb_ctx, setting_id, 1247 setting_value); 1248 1249 fr->fr_state.payload_length -= sizeof(ss->set_buf); 1250 if (0 == fr->fr_state.payload_length) 1251 reset_state(fr); 1252 else 1253 ss->nread = 0; 1254 } 1255 return 0; 1256} 1257 1258 1259static int 1260read_priority (struct lsquic_frame_reader *fr) 1261{ 1262 struct priority_state *ps = &fr->fr_state.by_type.priority_state; 1263 unsigned ntoread; 1264 ssize_t nr; 1265 uint32_t stream_id, dep_stream_id; 1266 int exclusive; 1267 1268 ntoread = sizeof(ps->u.prio_buf) - ps->nread; 1269 nr = fr->fr_read(fr->fr_stream, ps->u.prio_buf + ps->nread, ntoread); 1270 if (nr <= 0) 1271 RETURN_ERROR(nr); 1272 ps->nread += nr; 1273 if (ps->nread == sizeof(ps->u.prio_buf)) 1274 { 1275 memcpy(&dep_stream_id, ps->u.prio_frame.hpf_stream_id, 4); 1276 dep_stream_id = ntohl(dep_stream_id); 1277 exclusive = dep_stream_id >> 31; 1278 dep_stream_id &= ~(1UL << 31); 1279 stream_id = fr_get_stream_id(fr); 1280 if (stream_id == dep_stream_id) 1281 fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, 1282 FR_ERR_SELF_DEP_STREAM); 1283 else 1284 { 1285 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "read PRIORITY frame; " 1286 "stream: %"PRIu32", dep stream %"PRIu32", exclusive: %d, " 1287 "weight: %u", stream_id, dep_stream_id, exclusive, 1288 ps->u.prio_frame.hpf_weight + 1); 1289 fr->fr_callbacks->frc_on_priority(fr->fr_cb_ctx, stream_id, 1290 exclusive, dep_stream_id, ps->u.prio_frame.hpf_weight + 1); 1291 } 1292 reset_state(fr); 1293 } 1294 return 0; 1295} 1296 1297 1298static int 1299read_payload (struct lsquic_frame_reader *fr) 1300{ 1301 switch (fr->fr_state.reader_type) 1302 { 1303 case READER_HEADERS: 1304 return read_headers(fr); 1305 case READER_PUSH_PROMISE: 1306 return read_push_promise(fr); 1307 case READER_CONTIN: 1308 return read_contin(fr); 1309 case READER_SETTINGS: 1310 return read_settings(fr); 1311 case READER_PRIORITY: 1312 return read_priority(fr); 1313 default: 1314 assert(READER_SKIP == fr->fr_state.reader_type); 1315 return skip_payload(fr); 1316 } 1317} 1318 1319 1320int 1321lsquic_frame_reader_read (struct lsquic_frame_reader *fr) 1322{ 1323 if (fr->fr_state.nh_read < sizeof(fr->fr_state.header)) 1324 return read_http_frame_header(fr); 1325 else 1326 return read_payload(fr); 1327} 1328 1329 1330size_t 1331lsquic_frame_reader_mem_used (const struct lsquic_frame_reader *fr) 1332{ 1333 size_t size; 1334 size = sizeof(*fr); 1335 if (fr->fr_header_block) 1336 size += fr->fr_header_block_sz; 1337 return size; 1338} 1339