1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't 6 // constantly adding and subtracting header sizes; this is ugly and error- 7 // prone. 8 9 #include "net/spdy/spdy_framer.h" 10 11 #include "base/lazy_instance.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/metrics/stats_counters.h" 14 #include "base/third_party/valgrind/memcheck.h" 15 #include "net/spdy/spdy_frame_builder.h" 16 #include "net/spdy/spdy_frame_reader.h" 17 #include "net/spdy/spdy_bitmasks.h" 18 #include "third_party/zlib/zlib.h" 19 20 using std::vector; 21 22 namespace net { 23 24 namespace { 25 26 // Compute the id of our dictionary so that we know we're using the 27 // right one when asked for it. 28 uLong CalculateDictionaryId(const char* dictionary, 29 const size_t dictionary_size) { 30 uLong initial_value = adler32(0L, Z_NULL, 0); 31 return adler32(initial_value, 32 reinterpret_cast<const Bytef*>(dictionary), 33 dictionary_size); 34 } 35 36 struct DictionaryIds { 37 DictionaryIds() 38 : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)), 39 v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize)) 40 {} 41 const uLong v2_dictionary_id; 42 const uLong v3_dictionary_id; 43 }; 44 45 // Adler ID for the SPDY header compressor dictionaries. Note that they are 46 // initialized lazily to avoid static initializers. 47 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; 48 49 // Used to indicate no flags in a SPDY flags field. 50 const uint8 kNoFlags = 0; 51 52 } // namespace 53 54 const SpdyStreamId SpdyFramer::kInvalidStream = -1; 55 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; 56 // The size of the control frame buffer. Must be >= the minimum size of the 57 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for 58 // calculation details. 59 const size_t SpdyFramer::kControlFrameBufferSize = 18; 60 61 #ifdef DEBUG_SPDY_STATE_CHANGES 62 #define CHANGE_STATE(newstate) \ 63 do { \ 64 LOG(INFO) << "Changing state from: " \ 65 << StateToString(state_) \ 66 << " to " << StateToString(newstate) << "\n"; \ 67 DCHECK(state_ != SPDY_ERROR); \ 68 DCHECK_EQ(previous_state_, state_); \ 69 previous_state_ = state_; \ 70 state_ = newstate; \ 71 } while (false) 72 #else 73 #define CHANGE_STATE(newstate) \ 74 do { \ 75 DCHECK(state_ != SPDY_ERROR); \ 76 DCHECK_EQ(previous_state_, state_); \ 77 previous_state_ = state_; \ 78 state_ = newstate; \ 79 } while (false) 80 #endif 81 82 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version, 83 uint32 wire) { 84 if (version < 3) { 85 ConvertFlagsAndIdForSpdy2(&wire); 86 } 87 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff); 88 } 89 90 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) 91 : flags_(flags), id_(id & 0x00ffffff) { 92 DCHECK_GT(1u << 24, id) << "SPDY setting ID too large."; 93 } 94 95 uint32 SettingsFlagsAndId::GetWireFormat(int version) const { 96 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24); 97 if (version < 3) { 98 ConvertFlagsAndIdForSpdy2(&wire); 99 } 100 return wire; 101 } 102 103 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field. 104 // This method is used to preserve buggy behavior and works on both 105 // little-endian and big-endian hosts. 106 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 107 // as well as vice versa). 108 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) { 109 uint8* wire_array = reinterpret_cast<uint8*>(val); 110 std::swap(wire_array[0], wire_array[3]); 111 std::swap(wire_array[1], wire_array[2]); 112 } 113 114 SpdyCredential::SpdyCredential() : slot(0) {} 115 SpdyCredential::~SpdyCredential() {} 116 117 SpdyFramer::SpdyFramer(SpdyMajorVersion version) 118 : current_frame_buffer_(new char[kControlFrameBufferSize]), 119 enable_compression_(true), 120 visitor_(NULL), 121 debug_visitor_(NULL), 122 display_protocol_("SPDY"), 123 spdy_version_(version), 124 syn_frame_processed_(false), 125 probable_http_response_(false) { 126 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION); 127 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION); 128 Reset(); 129 } 130 131 SpdyFramer::~SpdyFramer() { 132 if (header_compressor_.get()) { 133 deflateEnd(header_compressor_.get()); 134 } 135 if (header_decompressor_.get()) { 136 inflateEnd(header_decompressor_.get()); 137 } 138 } 139 140 void SpdyFramer::Reset() { 141 state_ = SPDY_RESET; 142 previous_state_ = SPDY_RESET; 143 error_code_ = SPDY_NO_ERROR; 144 remaining_data_length_ = 0; 145 remaining_control_header_ = 0; 146 current_frame_buffer_length_ = 0; 147 current_frame_type_ = DATA; 148 current_frame_flags_ = 0; 149 current_frame_length_ = 0; 150 current_frame_stream_id_ = kInvalidStream; 151 settings_scratch_.Reset(); 152 } 153 154 size_t SpdyFramer::GetDataFrameMinimumSize() const { 155 // Size, in bytes, of the data frame header. Future versions of SPDY 156 // will likely vary this, so we allow for the flexibility of a function call 157 // for this value as opposed to a constant. 158 return 8; 159 } 160 161 // Size, in bytes, of the control frame header. 162 size_t SpdyFramer::GetControlFrameHeaderSize() const { 163 switch (protocol_version()) { 164 case SPDY2: 165 case SPDY3: 166 case SPDY4: 167 return 8; 168 } 169 LOG(DFATAL) << "Unhandled SPDY version."; 170 return 0; 171 } 172 173 size_t SpdyFramer::GetSynStreamMinimumSize() const { 174 // Size, in bytes, of a SYN_STREAM frame not including the variable-length 175 // name-value block. 176 if (spdy_version_ < 4) { 177 // Calculated as: 178 // control frame header + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot) 179 return GetControlFrameHeaderSize() + 10; 180 } else { 181 // Calculated as: 182 // frame prefix + 4 (associated stream ID) + 1 (priority) + 1 (slot) 183 return GetControlFrameHeaderSize() + 6; 184 } 185 } 186 187 size_t SpdyFramer::GetSynReplyMinimumSize() const { 188 // Size, in bytes, of a SYN_REPLY frame not including the variable-length 189 // name-value block. 190 size_t size = GetControlFrameHeaderSize(); 191 if (spdy_version_ < 4) { 192 // Calculated as: 193 // control frame header + 4 (stream IDs) 194 size += 4; 195 } 196 197 // In SPDY 2, there were 2 unused bytes before payload. 198 if (protocol_version() < 3) { 199 size += 2; 200 } 201 202 return size; 203 } 204 205 size_t SpdyFramer::GetRstStreamSize() const { 206 // Size, in bytes, of a RST_STREAM frame. 207 if (spdy_version_ < 4) { 208 // Calculated as: 209 // control frame header + 4 (stream id) + 4 (status code) 210 return GetControlFrameHeaderSize() + 8; 211 } else { 212 // Calculated as: 213 // frame prefix + 4 (status code) 214 return GetControlFrameHeaderSize() + 4; 215 } 216 } 217 218 size_t SpdyFramer::GetSettingsMinimumSize() const { 219 // Size, in bytes, of a SETTINGS frame not including the IDs and values 220 // from the variable-length value block. Calculated as: 221 // control frame header + 4 (number of ID/value pairs) 222 return GetControlFrameHeaderSize() + 4; 223 } 224 225 size_t SpdyFramer::GetPingSize() const { 226 // Size, in bytes, of this PING frame. Calculated as: 227 // control frame header + 4 (id) 228 return GetControlFrameHeaderSize() + 4; 229 } 230 231 size_t SpdyFramer::GetGoAwaySize() const { 232 // Size, in bytes, of this GOAWAY frame. Calculated as: 233 // control frame header + 4 (last good stream id) 234 size_t size = GetControlFrameHeaderSize() + 4; 235 236 // SPDY 3+ GOAWAY frames also contain a status. 237 if (protocol_version() >= 3) { 238 size += 4; 239 } 240 241 return size; 242 } 243 244 size_t SpdyFramer::GetHeadersMinimumSize() const { 245 // Size, in bytes, of a HEADERS frame not including the variable-length 246 // name-value block. 247 size_t size = GetControlFrameHeaderSize(); 248 if (spdy_version_ < 4) { 249 // Calculated as: 250 // control frame header + 4 (stream IDs) 251 size += 4; 252 } 253 254 // In SPDY 2, there were 2 unused bytes before payload. 255 if (protocol_version() < 3) { 256 size += 2; 257 } 258 259 return size; 260 } 261 262 size_t SpdyFramer::GetWindowUpdateSize() const { 263 // Size, in bytes, of a WINDOW_UPDATE frame. 264 if (spdy_version_ < 4) { 265 // Calculated as: 266 // control frame header + 4 (stream id) + 4 (delta) 267 return GetControlFrameHeaderSize() + 8; 268 } else { 269 // Calculated as: 270 // frame prefix + 4 (delta) 271 return GetControlFrameHeaderSize() + 4; 272 } 273 } 274 275 size_t SpdyFramer::GetCredentialMinimumSize() const { 276 // Size, in bytes, of a CREDENTIAL frame sans variable-length certificate list 277 // and proof. Calculated as: 278 // control frame header + 2 (slot) 279 return GetControlFrameHeaderSize() + 2; 280 } 281 282 size_t SpdyFramer::GetBlockedSize() const { 283 DCHECK_LE(4, protocol_version()); 284 // Size, in bytes, of a BLOCKED frame. 285 // The BLOCKED frame has no payload beyond the control frame header. 286 return GetControlFrameHeaderSize(); 287 } 288 289 size_t SpdyFramer::GetPushPromiseMinimumSize() const { 290 DCHECK_LE(4, protocol_version()); 291 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block. 292 // Calculated as frame prefix + 4 (promised stream id). 293 return GetControlFrameHeaderSize() + 4; 294 } 295 296 size_t SpdyFramer::GetFrameMinimumSize() const { 297 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); 298 } 299 300 size_t SpdyFramer::GetFrameMaximumSize() const { 301 return (protocol_version() < 4) ? 0xffffff : 0xffff; 302 } 303 304 size_t SpdyFramer::GetDataFrameMaximumPayload() const { 305 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); 306 } 307 308 const char* SpdyFramer::StateToString(int state) { 309 switch (state) { 310 case SPDY_ERROR: 311 return "ERROR"; 312 case SPDY_AUTO_RESET: 313 return "AUTO_RESET"; 314 case SPDY_RESET: 315 return "RESET"; 316 case SPDY_READING_COMMON_HEADER: 317 return "READING_COMMON_HEADER"; 318 case SPDY_CONTROL_FRAME_PAYLOAD: 319 return "CONTROL_FRAME_PAYLOAD"; 320 case SPDY_IGNORE_REMAINING_PAYLOAD: 321 return "IGNORE_REMAINING_PAYLOAD"; 322 case SPDY_FORWARD_STREAM_FRAME: 323 return "FORWARD_STREAM_FRAME"; 324 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: 325 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; 326 case SPDY_CONTROL_FRAME_HEADER_BLOCK: 327 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; 328 case SPDY_CREDENTIAL_FRAME_PAYLOAD: 329 return "SPDY_CREDENTIAL_FRAME_PAYLOAD"; 330 case SPDY_SETTINGS_FRAME_PAYLOAD: 331 return "SPDY_SETTINGS_FRAME_PAYLOAD"; 332 } 333 return "UNKNOWN_STATE"; 334 } 335 336 void SpdyFramer::set_error(SpdyError error) { 337 DCHECK(visitor_); 338 error_code_ = error; 339 CHANGE_STATE(SPDY_ERROR); 340 visitor_->OnError(this); 341 } 342 343 const char* SpdyFramer::ErrorCodeToString(int error_code) { 344 switch (error_code) { 345 case SPDY_NO_ERROR: 346 return "NO_ERROR"; 347 case SPDY_INVALID_CONTROL_FRAME: 348 return "INVALID_CONTROL_FRAME"; 349 case SPDY_CONTROL_PAYLOAD_TOO_LARGE: 350 return "CONTROL_PAYLOAD_TOO_LARGE"; 351 case SPDY_ZLIB_INIT_FAILURE: 352 return "ZLIB_INIT_FAILURE"; 353 case SPDY_UNSUPPORTED_VERSION: 354 return "UNSUPPORTED_VERSION"; 355 case SPDY_DECOMPRESS_FAILURE: 356 return "DECOMPRESS_FAILURE"; 357 case SPDY_COMPRESS_FAILURE: 358 return "COMPRESS_FAILURE"; 359 case SPDY_INVALID_DATA_FRAME_FLAGS: 360 return "SPDY_INVALID_DATA_FRAME_FLAGS"; 361 case SPDY_INVALID_CONTROL_FRAME_FLAGS: 362 return "SPDY_INVALID_CONTROL_FRAME_FLAGS"; 363 } 364 return "UNKNOWN_ERROR"; 365 } 366 367 const char* SpdyFramer::StatusCodeToString(int status_code) { 368 switch (status_code) { 369 case RST_STREAM_INVALID: 370 return "INVALID"; 371 case RST_STREAM_PROTOCOL_ERROR: 372 return "PROTOCOL_ERROR"; 373 case RST_STREAM_INVALID_STREAM: 374 return "INVALID_STREAM"; 375 case RST_STREAM_REFUSED_STREAM: 376 return "REFUSED_STREAM"; 377 case RST_STREAM_UNSUPPORTED_VERSION: 378 return "UNSUPPORTED_VERSION"; 379 case RST_STREAM_CANCEL: 380 return "CANCEL"; 381 case RST_STREAM_INTERNAL_ERROR: 382 return "INTERNAL_ERROR"; 383 case RST_STREAM_FLOW_CONTROL_ERROR: 384 return "FLOW_CONTROL_ERROR"; 385 case RST_STREAM_STREAM_IN_USE: 386 return "STREAM_IN_USE"; 387 case RST_STREAM_STREAM_ALREADY_CLOSED: 388 return "STREAM_ALREADY_CLOSED"; 389 case RST_STREAM_INVALID_CREDENTIALS: 390 return "INVALID_CREDENTIALS"; 391 case RST_STREAM_FRAME_TOO_LARGE: 392 return "FRAME_TOO_LARGE"; 393 } 394 return "UNKNOWN_STATUS"; 395 } 396 397 const char* SpdyFramer::FrameTypeToString(SpdyFrameType type) { 398 switch (type) { 399 case DATA: 400 return "DATA"; 401 case SYN_STREAM: 402 return "SYN_STREAM"; 403 case SYN_REPLY: 404 return "SYN_REPLY"; 405 case RST_STREAM: 406 return "RST_STREAM"; 407 case SETTINGS: 408 return "SETTINGS"; 409 case NOOP: 410 return "NOOP"; 411 case PING: 412 return "PING"; 413 case GOAWAY: 414 return "GOAWAY"; 415 case HEADERS: 416 return "HEADERS"; 417 case WINDOW_UPDATE: 418 return "WINDOW_UPDATE"; 419 case CREDENTIAL: 420 return "CREDENTIAL"; 421 case BLOCKED: 422 return "BLOCKED"; 423 case PUSH_PROMISE: 424 return "PUSH_PROMISE"; 425 } 426 return "UNKNOWN_CONTROL_TYPE"; 427 } 428 429 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { 430 DCHECK(visitor_); 431 DCHECK(data); 432 433 size_t original_len = len; 434 do { 435 previous_state_ = state_; 436 switch (state_) { 437 case SPDY_ERROR: 438 goto bottom; 439 440 case SPDY_AUTO_RESET: 441 case SPDY_RESET: 442 Reset(); 443 if (len > 0) { 444 CHANGE_STATE(SPDY_READING_COMMON_HEADER); 445 } 446 break; 447 448 case SPDY_READING_COMMON_HEADER: { 449 size_t bytes_read = ProcessCommonHeader(data, len); 450 len -= bytes_read; 451 data += bytes_read; 452 break; 453 } 454 455 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: { 456 // Control frames that contain header blocks 457 // (SYN_STREAM, SYN_REPLY, HEADERS, PUSH_PROMISE) 458 // take a different path through the state machine - they 459 // will go: 460 // 1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK 461 // 2. SPDY_CONTROL_FRAME_HEADER_BLOCK 462 // 463 // SETTINGS frames take a slightly modified route: 464 // 1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK 465 // 2. SPDY_SETTINGS_FRAME_PAYLOAD 466 // 467 // All other control frames will use the alternate route directly to 468 // SPDY_CONTROL_FRAME_PAYLOAD 469 int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len); 470 len -= bytes_read; 471 data += bytes_read; 472 break; 473 } 474 475 case SPDY_SETTINGS_FRAME_PAYLOAD: { 476 int bytes_read = ProcessSettingsFramePayload(data, len); 477 len -= bytes_read; 478 data += bytes_read; 479 break; 480 } 481 482 case SPDY_CONTROL_FRAME_HEADER_BLOCK: { 483 int bytes_read = ProcessControlFrameHeaderBlock(data, len); 484 len -= bytes_read; 485 data += bytes_read; 486 break; 487 } 488 489 case SPDY_CREDENTIAL_FRAME_PAYLOAD: { 490 size_t bytes_read = ProcessCredentialFramePayload(data, len); 491 len -= bytes_read; 492 data += bytes_read; 493 break; 494 } 495 496 case SPDY_CONTROL_FRAME_PAYLOAD: { 497 size_t bytes_read = ProcessControlFramePayload(data, len); 498 len -= bytes_read; 499 data += bytes_read; 500 break; 501 } 502 503 case SPDY_IGNORE_REMAINING_PAYLOAD: 504 // control frame has too-large payload 505 // intentional fallthrough 506 case SPDY_FORWARD_STREAM_FRAME: { 507 size_t bytes_read = ProcessDataFramePayload(data, len); 508 len -= bytes_read; 509 data += bytes_read; 510 break; 511 } 512 default: 513 LOG(DFATAL) << "Invalid value for " << display_protocol_ 514 << " framer state: " << state_; 515 // This ensures that we don't infinite-loop if state_ gets an 516 // invalid value somehow, such as due to a SpdyFramer getting deleted 517 // from a callback it calls. 518 goto bottom; 519 } 520 } while (state_ != previous_state_); 521 bottom: 522 DCHECK(len == 0 || state_ == SPDY_ERROR); 523 if (current_frame_buffer_length_ == 0 && 524 remaining_data_length_ == 0 && 525 remaining_control_header_ == 0) { 526 DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR) 527 << "State: " << StateToString(state_); 528 } 529 530 return original_len - len; 531 } 532 533 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { 534 // This should only be called when we're in the SPDY_READING_COMMON_HEADER 535 // state. 536 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); 537 538 size_t original_len = len; 539 540 // Update current frame buffer as needed. 541 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) { 542 size_t bytes_desired = 543 GetControlFrameHeaderSize() - current_frame_buffer_length_; 544 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); 545 } 546 547 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) { 548 // Not enough information to do anything meaningful. 549 return original_len - len; 550 } 551 552 // Using a scoped_ptr here since we may need to create a new SpdyFrameReader 553 // when processing DATA frames below. 554 scoped_ptr<SpdyFrameReader> reader( 555 new SpdyFrameReader(current_frame_buffer_.get(), 556 current_frame_buffer_length_)); 557 558 uint16 version = 0; 559 bool is_control_frame = false; 560 561 uint16 control_frame_type_field = DATA; 562 // ProcessControlFrameHeader() will set current_frame_type_ to the 563 // correct value if this is a valid control frame. 564 current_frame_type_ = DATA; 565 if (protocol_version() < 4) { 566 bool successful_read = reader->ReadUInt16(&version); 567 DCHECK(successful_read); 568 is_control_frame = (version & kControlFlagMask) != 0; 569 version &= ~kControlFlagMask; // Only valid for control frames. 570 571 if (is_control_frame) { 572 // We check control_frame_type_field's validity in 573 // ProcessControlFrameHeader(). 574 successful_read = reader->ReadUInt16(&control_frame_type_field); 575 } else { 576 reader->Rewind(); 577 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); 578 } 579 DCHECK(successful_read); 580 581 successful_read = reader->ReadUInt8(¤t_frame_flags_); 582 DCHECK(successful_read); 583 584 uint32 length_field = 0; 585 successful_read = reader->ReadUInt24(&length_field); 586 DCHECK(successful_read); 587 remaining_data_length_ = length_field; 588 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); 589 } else { 590 version = protocol_version(); 591 uint16 length_field = 0; 592 bool successful_read = reader->ReadUInt16(&length_field); 593 DCHECK(successful_read); 594 current_frame_length_ = length_field; 595 596 uint8 control_frame_type_field_uint8 = DATA; 597 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); 598 DCHECK(successful_read); 599 // We check control_frame_type_field's validity in 600 // ProcessControlFrameHeader(). 601 control_frame_type_field = control_frame_type_field_uint8; 602 is_control_frame = (control_frame_type_field != DATA); 603 604 successful_read = reader->ReadUInt8(¤t_frame_flags_); 605 DCHECK(successful_read); 606 607 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); 608 DCHECK(successful_read); 609 610 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); 611 } 612 DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize() 613 : GetDataFrameMinimumSize(), 614 reader->GetBytesConsumed()); 615 DCHECK_EQ(current_frame_length_, 616 remaining_data_length_ + reader->GetBytesConsumed()); 617 618 // This is just a sanity check for help debugging early frame errors. 619 if (remaining_data_length_ > 1000000u) { 620 // The strncmp for 5 is safe because we only hit this point if we 621 // have kMinCommonHeader (8) bytes 622 if (!syn_frame_processed_ && 623 strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) { 624 LOG(WARNING) << "Unexpected HTTP response to " << display_protocol_ 625 << " request"; 626 probable_http_response_ = true; 627 } else { 628 LOG(WARNING) << "Unexpectedly large frame. " << display_protocol_ 629 << " session is likely corrupt."; 630 } 631 } 632 633 // if we're here, then we have the common header all received. 634 if (!is_control_frame) { 635 if (current_frame_flags_ & ~DATA_FLAG_FIN) { 636 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 637 } else { 638 visitor_->OnDataFrameHeader(current_frame_stream_id_, 639 remaining_data_length_, 640 current_frame_flags_ & DATA_FLAG_FIN); 641 if (remaining_data_length_ > 0) { 642 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); 643 } else { 644 // Empty data frame. 645 if (current_frame_flags_ & DATA_FLAG_FIN) { 646 visitor_->OnStreamFrameData( 647 current_frame_stream_id_, NULL, 0, true); 648 } 649 CHANGE_STATE(SPDY_AUTO_RESET); 650 } 651 } 652 } else if (version != spdy_version_) { 653 // We check version before we check validity: version can never be 654 // 'invalid', it can only be unsupported. 655 DLOG(INFO) << "Unsupported SPDY version " << version 656 << " (expected " << spdy_version_ << ")"; 657 set_error(SPDY_UNSUPPORTED_VERSION); 658 } else { 659 ProcessControlFrameHeader(control_frame_type_field); 660 } 661 662 return original_len - len; 663 } 664 665 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { 666 DCHECK_EQ(SPDY_NO_ERROR, error_code_); 667 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); 668 669 if (control_frame_type_field < FIRST_CONTROL_TYPE || 670 control_frame_type_field > LAST_CONTROL_TYPE) { 671 set_error(SPDY_INVALID_CONTROL_FRAME); 672 return; 673 } 674 675 current_frame_type_ = static_cast<SpdyFrameType>(control_frame_type_field); 676 677 if (current_frame_type_ == NOOP) { 678 DLOG(INFO) << "NOOP control frame found. Ignoring."; 679 CHANGE_STATE(SPDY_AUTO_RESET); 680 return; 681 } 682 683 // Do some sanity checking on the control frame sizes and flags. 684 switch (current_frame_type_) { 685 case SYN_STREAM: 686 if (current_frame_length_ < GetSynStreamMinimumSize()) { 687 set_error(SPDY_INVALID_CONTROL_FRAME); 688 } else if (current_frame_flags_ & 689 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { 690 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 691 } 692 break; 693 case SYN_REPLY: 694 if (current_frame_length_ < GetSynReplyMinimumSize()) { 695 set_error(SPDY_INVALID_CONTROL_FRAME); 696 } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) { 697 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 698 } 699 break; 700 case RST_STREAM: 701 if (current_frame_length_ != GetRstStreamSize()) { 702 set_error(SPDY_INVALID_CONTROL_FRAME); 703 } else if (current_frame_flags_ != 0) { 704 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 705 } 706 break; 707 case SETTINGS: 708 // Make sure that we have an integral number of 8-byte key/value pairs, 709 // plus a 4-byte length field. 710 if (current_frame_length_ < GetSettingsMinimumSize() || 711 (current_frame_length_ - GetControlFrameHeaderSize()) % 8 != 4) { 712 DLOG(WARNING) << "Invalid length for SETTINGS frame: " 713 << current_frame_length_; 714 set_error(SPDY_INVALID_CONTROL_FRAME); 715 } else if (current_frame_flags_ & 716 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { 717 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 718 } 719 break; 720 case PING: 721 if (current_frame_length_ != GetPingSize()) { 722 set_error(SPDY_INVALID_CONTROL_FRAME); 723 } else if (current_frame_flags_ != 0) { 724 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 725 } 726 break; 727 case GOAWAY: 728 { 729 if (current_frame_length_ != GetGoAwaySize()) { 730 set_error(SPDY_INVALID_CONTROL_FRAME); 731 } else if (current_frame_flags_ != 0) { 732 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 733 } 734 break; 735 } 736 case HEADERS: 737 if (current_frame_length_ < GetHeadersMinimumSize()) { 738 set_error(SPDY_INVALID_CONTROL_FRAME); 739 } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) { 740 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 741 } 742 break; 743 case WINDOW_UPDATE: 744 if (current_frame_length_ != GetWindowUpdateSize()) { 745 set_error(SPDY_INVALID_CONTROL_FRAME); 746 } else if (current_frame_flags_ != 0) { 747 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 748 } 749 break; 750 case CREDENTIAL: 751 if (current_frame_length_ < GetCredentialMinimumSize()) { 752 set_error(SPDY_INVALID_CONTROL_FRAME); 753 } else if (current_frame_flags_ != 0) { 754 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 755 } 756 break; 757 case BLOCKED: 758 if (current_frame_length_ != GetBlockedSize()) { 759 set_error(SPDY_INVALID_CONTROL_FRAME); 760 } else if (current_frame_flags_ != 0) { 761 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 762 } 763 break; 764 case PUSH_PROMISE: 765 if (current_frame_length_ < GetPushPromiseMinimumSize()) { 766 set_error(SPDY_INVALID_CONTROL_FRAME); 767 } else if (current_frame_flags_ != 0) { 768 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 769 } 770 break; 771 default: 772 LOG(WARNING) << "Valid " << display_protocol_ 773 << " control frame with unhandled type: " 774 << current_frame_type_; 775 // This branch should be unreachable because of the frame type bounds 776 // check above. However, we DLOG(FATAL) here in an effort to painfully 777 // club the head of the developer who failed to keep this file in sync 778 // with spdy_protocol.h. 779 DLOG(FATAL); 780 set_error(SPDY_INVALID_CONTROL_FRAME); 781 break; 782 } 783 784 if (state_ == SPDY_ERROR) { 785 return; 786 } 787 788 if (current_frame_length_ > GetControlFrameBufferMaxSize()) { 789 DLOG(WARNING) << "Received control frame with way too big of a payload: " 790 << current_frame_length_; 791 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 792 return; 793 } 794 795 if (current_frame_type_ == CREDENTIAL) { 796 CHANGE_STATE(SPDY_CREDENTIAL_FRAME_PAYLOAD); 797 return; 798 } 799 800 // Determine the frame size without variable-length data. 801 int32 frame_size_without_variable_data; 802 switch (current_frame_type_) { 803 case SYN_STREAM: 804 syn_frame_processed_ = true; 805 frame_size_without_variable_data = GetSynStreamMinimumSize(); 806 break; 807 case SYN_REPLY: 808 syn_frame_processed_ = true; 809 frame_size_without_variable_data = GetSynReplyMinimumSize(); 810 break; 811 case SETTINGS: 812 frame_size_without_variable_data = GetSettingsMinimumSize(); 813 break; 814 case HEADERS: 815 frame_size_without_variable_data = GetHeadersMinimumSize(); 816 break; 817 case PUSH_PROMISE: 818 frame_size_without_variable_data = GetPushPromiseMinimumSize(); 819 break; 820 default: 821 frame_size_without_variable_data = -1; 822 break; 823 } 824 825 if ((frame_size_without_variable_data == -1) && 826 (current_frame_length_ > kControlFrameBufferSize)) { 827 // We should already be in an error state. Double-check. 828 DCHECK_EQ(SPDY_ERROR, state_); 829 if (state_ != SPDY_ERROR) { 830 LOG(DFATAL) << display_protocol_ 831 << " control frame buffer too small for fixed-length frame."; 832 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 833 } 834 return; 835 } 836 837 if (frame_size_without_variable_data > 0) { 838 // We have a control frame with a header block. We need to parse the 839 // remainder of the control frame's header before we can parse the header 840 // block. The start of the header block varies with the control type. 841 DCHECK_GE(frame_size_without_variable_data, 842 static_cast<int32>(current_frame_buffer_length_)); 843 remaining_control_header_ = frame_size_without_variable_data - 844 current_frame_buffer_length_; 845 846 CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK); 847 return; 848 } 849 850 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD); 851 } 852 853 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len, 854 size_t max_bytes) { 855 size_t bytes_to_read = std::min(*len, max_bytes); 856 if (bytes_to_read > 0) { 857 DCHECK_GE(kControlFrameBufferSize, 858 current_frame_buffer_length_ + bytes_to_read); 859 memcpy(current_frame_buffer_.get() + current_frame_buffer_length_, 860 *data, 861 bytes_to_read); 862 current_frame_buffer_length_ += bytes_to_read; 863 *data += bytes_to_read; 864 *len -= bytes_to_read; 865 } 866 return bytes_to_read; 867 } 868 869 size_t SpdyFramer::GetSerializedLength(const int spdy_version, 870 const SpdyHeaderBlock* headers) { 871 const size_t num_name_value_pairs_size 872 = (spdy_version < 3) ? sizeof(uint16) : sizeof(uint32); 873 const size_t length_of_name_size = num_name_value_pairs_size; 874 const size_t length_of_value_size = num_name_value_pairs_size; 875 876 size_t total_length = num_name_value_pairs_size; 877 for (SpdyHeaderBlock::const_iterator it = headers->begin(); 878 it != headers->end(); 879 ++it) { 880 // We add space for the length of the name and the length of the value as 881 // well as the length of the name and the length of the value. 882 total_length += length_of_name_size + it->first.size() + 883 length_of_value_size + it->second.size(); 884 } 885 return total_length; 886 } 887 888 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame, 889 const int spdy_version, 890 const SpdyHeaderBlock* headers) { 891 if (spdy_version < 3) { 892 frame->WriteUInt16(headers->size()); // Number of headers. 893 } else { 894 frame->WriteUInt32(headers->size()); // Number of headers. 895 } 896 SpdyHeaderBlock::const_iterator it; 897 for (it = headers->begin(); it != headers->end(); ++it) { 898 if (spdy_version < 3) { 899 frame->WriteString(it->first); 900 frame->WriteString(it->second); 901 } else { 902 frame->WriteStringPiece32(it->first); 903 frame->WriteStringPiece32(it->second); 904 } 905 } 906 } 907 908 // TODO(phajdan.jr): Clean up after we no longer need 909 // to workaround http://crbug.com/139744. 910 #if !defined(USE_SYSTEM_ZLIB) 911 912 // These constants are used by zlib to differentiate between normal data and 913 // cookie data. Cookie data is handled specially by zlib when compressing. 914 enum ZDataClass { 915 // kZStandardData is compressed normally, save that it will never match 916 // against any other class of data in the window. 917 kZStandardData = Z_CLASS_STANDARD, 918 // kZCookieData is compressed in its own Huffman blocks and only matches in 919 // its entirety and only against other kZCookieData blocks. Any matches must 920 // be preceeded by a kZStandardData byte, or a semicolon to prevent matching 921 // a suffix. It's assumed that kZCookieData ends in a semicolon to prevent 922 // prefix matches. 923 kZCookieData = Z_CLASS_COOKIE, 924 // kZHuffmanOnlyData is only Huffman compressed - no matches are performed 925 // against the window. 926 kZHuffmanOnlyData = Z_CLASS_HUFFMAN_ONLY, 927 }; 928 929 // WriteZ writes |data| to the deflate context |out|. WriteZ will flush as 930 // needed when switching between classes of data. 931 static void WriteZ(const base::StringPiece& data, 932 ZDataClass clas, 933 z_stream* out) { 934 int rv; 935 936 // If we are switching from standard to non-standard data then we need to end 937 // the current Huffman context to avoid it leaking between them. 938 if (out->clas == kZStandardData && 939 clas != kZStandardData) { 940 out->avail_in = 0; 941 rv = deflate(out, Z_PARTIAL_FLUSH); 942 DCHECK_EQ(Z_OK, rv); 943 DCHECK_EQ(0u, out->avail_in); 944 DCHECK_LT(0u, out->avail_out); 945 } 946 947 out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data())); 948 out->avail_in = data.size(); 949 out->clas = clas; 950 if (clas == kZStandardData) { 951 rv = deflate(out, Z_NO_FLUSH); 952 } else { 953 rv = deflate(out, Z_PARTIAL_FLUSH); 954 } 955 if (!data.empty()) { 956 // If we didn't provide any data then zlib will return Z_BUF_ERROR. 957 DCHECK_EQ(Z_OK, rv); 958 } 959 DCHECK_EQ(0u, out->avail_in); 960 DCHECK_LT(0u, out->avail_out); 961 } 962 963 // WriteLengthZ writes |n| as a |length|-byte, big-endian number to |out|. 964 static void WriteLengthZ(size_t n, 965 unsigned length, 966 ZDataClass clas, 967 z_stream* out) { 968 char buf[4]; 969 DCHECK_LE(length, sizeof(buf)); 970 for (unsigned i = 1; i <= length; i++) { 971 buf[length - i] = n; 972 n >>= 8; 973 } 974 WriteZ(base::StringPiece(buf, length), clas, out); 975 } 976 977 // WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a 978 // manner that resists the length of the compressed data from compromising 979 // cookie data. 980 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers, 981 z_stream* z) const { 982 unsigned length_length = 4; 983 if (spdy_version_ < 3) 984 length_length = 2; 985 986 WriteLengthZ(headers->size(), length_length, kZStandardData, z); 987 988 std::map<std::string, std::string>::const_iterator it; 989 for (it = headers->begin(); it != headers->end(); ++it) { 990 WriteLengthZ(it->first.size(), length_length, kZStandardData, z); 991 WriteZ(it->first, kZStandardData, z); 992 993 if (it->first == "cookie") { 994 // We require the cookie values (save for the last) to end with a 995 // semicolon and (save for the first) to start with a space. This is 996 // typically the format that we are given them in but we reserialize them 997 // to be sure. 998 999 std::vector<base::StringPiece> cookie_values; 1000 size_t cookie_length = 0; 1001 base::StringPiece cookie_data(it->second); 1002 1003 for (;;) { 1004 while (!cookie_data.empty() && 1005 (cookie_data[0] == ' ' || cookie_data[0] == '\t')) { 1006 cookie_data.remove_prefix(1); 1007 } 1008 if (cookie_data.empty()) 1009 break; 1010 1011 size_t i; 1012 for (i = 0; i < cookie_data.size(); i++) { 1013 if (cookie_data[i] == ';') 1014 break; 1015 } 1016 if (i < cookie_data.size()) { 1017 cookie_values.push_back(cookie_data.substr(0, i)); 1018 cookie_length += i + 2 /* semicolon and space */; 1019 cookie_data.remove_prefix(i + 1); 1020 } else { 1021 cookie_values.push_back(cookie_data); 1022 cookie_length += cookie_data.size(); 1023 cookie_data.remove_prefix(i); 1024 } 1025 } 1026 1027 WriteLengthZ(cookie_length, length_length, kZStandardData, z); 1028 for (size_t i = 0; i < cookie_values.size(); i++) { 1029 std::string cookie; 1030 // Since zlib will only back-reference complete cookies, a cookie that 1031 // is currently last (and so doesn't have a trailing semicolon) won't 1032 // match if it's later in a non-final position. The same is true of 1033 // the first cookie. 1034 if (i == 0 && cookie_values.size() == 1) { 1035 cookie = cookie_values[i].as_string(); 1036 } else if (i == 0) { 1037 cookie = cookie_values[i].as_string() + ";"; 1038 } else if (i < cookie_values.size() - 1) { 1039 cookie = " " + cookie_values[i].as_string() + ";"; 1040 } else { 1041 cookie = " " + cookie_values[i].as_string(); 1042 } 1043 WriteZ(cookie, kZCookieData, z); 1044 } 1045 } else if (it->first == "accept" || 1046 it->first == "accept-charset" || 1047 it->first == "accept-encoding" || 1048 it->first == "accept-language" || 1049 it->first == "host" || 1050 it->first == "version" || 1051 it->first == "method" || 1052 it->first == "scheme" || 1053 it->first == ":host" || 1054 it->first == ":version" || 1055 it->first == ":method" || 1056 it->first == ":scheme" || 1057 it->first == "user-agent") { 1058 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); 1059 WriteZ(it->second, kZStandardData, z); 1060 } else { 1061 // Non-whitelisted headers are Huffman compressed in their own block, but 1062 // don't match against the window. 1063 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); 1064 WriteZ(it->second, kZHuffmanOnlyData, z); 1065 } 1066 } 1067 1068 z->avail_in = 0; 1069 int rv = deflate(z, Z_SYNC_FLUSH); 1070 DCHECK_EQ(Z_OK, rv); 1071 z->clas = kZStandardData; 1072 } 1073 #endif // !defined(USE_SYSTEM_ZLIB) 1074 1075 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data, 1076 size_t len) { 1077 DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_); 1078 size_t original_len = len; 1079 1080 if (remaining_control_header_ > 0) { 1081 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, 1082 remaining_control_header_); 1083 remaining_control_header_ -= bytes_read; 1084 remaining_data_length_ -= bytes_read; 1085 } 1086 1087 if (remaining_control_header_ == 0) { 1088 SpdyFrameReader reader(current_frame_buffer_.get(), 1089 current_frame_buffer_length_); 1090 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. 1091 1092 switch (current_frame_type_) { 1093 case SYN_STREAM: 1094 { 1095 bool successful_read = true; 1096 if (spdy_version_ < 4) { 1097 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1098 DCHECK(successful_read); 1099 } 1100 if (current_frame_stream_id_ == 0) { 1101 set_error(SPDY_INVALID_CONTROL_FRAME); 1102 break; 1103 } 1104 1105 SpdyStreamId associated_to_stream_id = kInvalidStream; 1106 successful_read = reader.ReadUInt31(&associated_to_stream_id); 1107 DCHECK(successful_read); 1108 1109 SpdyPriority priority = 0; 1110 successful_read = reader.ReadUInt8(&priority); 1111 DCHECK(successful_read); 1112 if (protocol_version() < 3) { 1113 priority = priority >> 6; 1114 } else { 1115 priority = priority >> 5; 1116 } 1117 1118 uint8 slot = 0; 1119 if (protocol_version() < 3) { 1120 // SPDY 2 had an unused byte here. Seek past it. 1121 reader.Seek(1); 1122 } else { 1123 successful_read = reader.ReadUInt8(&slot); 1124 DCHECK(successful_read); 1125 } 1126 1127 DCHECK(reader.IsDoneReading()); 1128 if (debug_visitor_) { 1129 debug_visitor_->OnReceiveCompressedFrame( 1130 current_frame_stream_id_, 1131 current_frame_type_, 1132 current_frame_length_); 1133 } 1134 visitor_->OnSynStream( 1135 current_frame_stream_id_, 1136 associated_to_stream_id, 1137 priority, 1138 slot, 1139 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, 1140 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); 1141 } 1142 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1143 break; 1144 case SETTINGS: 1145 visitor_->OnSettings(current_frame_flags_ & 1146 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS); 1147 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD); 1148 break; 1149 case SYN_REPLY: 1150 case HEADERS: 1151 // SYN_REPLY and HEADERS are the same, save for the visitor call. 1152 { 1153 bool successful_read = true; 1154 if (spdy_version_ < 4) { 1155 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1156 DCHECK(successful_read); 1157 } 1158 if (current_frame_stream_id_ == 0) { 1159 set_error(SPDY_INVALID_CONTROL_FRAME); 1160 break; 1161 } 1162 if (protocol_version() < 3) { 1163 // SPDY 2 had two unused bytes here. Seek past them. 1164 reader.Seek(2); 1165 } 1166 DCHECK(reader.IsDoneReading()); 1167 if (debug_visitor_) { 1168 debug_visitor_->OnReceiveCompressedFrame( 1169 current_frame_stream_id_, 1170 current_frame_type_, 1171 current_frame_length_); 1172 } 1173 if (current_frame_type_ == SYN_REPLY) { 1174 visitor_->OnSynReply( 1175 current_frame_stream_id_, 1176 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); 1177 } else { 1178 visitor_->OnHeaders( 1179 current_frame_stream_id_, 1180 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); 1181 } 1182 } 1183 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1184 break; 1185 case PUSH_PROMISE: 1186 { 1187 DCHECK_LE(4, protocol_version()); 1188 if (current_frame_stream_id_ == 0) { 1189 set_error(SPDY_INVALID_CONTROL_FRAME); 1190 break; 1191 } 1192 SpdyStreamId promised_stream_id = kInvalidStream; 1193 bool successful_read = reader.ReadUInt31(&promised_stream_id); 1194 DCHECK(successful_read); 1195 DCHECK(reader.IsDoneReading()); 1196 if (promised_stream_id == 0) { 1197 set_error(SPDY_INVALID_CONTROL_FRAME); 1198 break; 1199 } 1200 if (debug_visitor_) { 1201 debug_visitor_->OnReceiveCompressedFrame( 1202 current_frame_stream_id_, 1203 current_frame_type_, 1204 current_frame_length_); 1205 } 1206 visitor_->OnPushPromise(current_frame_stream_id_, promised_stream_id); 1207 } 1208 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1209 break; 1210 default: 1211 DCHECK(false); 1212 } 1213 } 1214 return original_len - len; 1215 } 1216 1217 // Does not buffer the control payload. Instead, either passes directly to the 1218 // visitor or decompresses and then passes directly to the visitor, via 1219 // IncrementallyDeliverControlFrameHeaderData() or 1220 // IncrementallyDecompressControlFrameHeaderData() respectively. 1221 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, 1222 size_t data_len) { 1223 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); 1224 1225 bool processed_successfully = true; 1226 if (current_frame_type_ != SYN_STREAM && 1227 current_frame_type_ != SYN_REPLY && 1228 current_frame_type_ != HEADERS && 1229 current_frame_type_ != PUSH_PROMISE) { 1230 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; 1231 } 1232 size_t process_bytes = std::min(data_len, remaining_data_length_); 1233 if (process_bytes > 0) { 1234 if (enable_compression_) { 1235 processed_successfully = IncrementallyDecompressControlFrameHeaderData( 1236 current_frame_stream_id_, data, process_bytes); 1237 } else { 1238 processed_successfully = IncrementallyDeliverControlFrameHeaderData( 1239 current_frame_stream_id_, data, process_bytes); 1240 } 1241 1242 remaining_data_length_ -= process_bytes; 1243 } 1244 1245 // Handle the case that there is no futher data in this frame. 1246 if (remaining_data_length_ == 0 && processed_successfully) { 1247 // The complete header block has been delivered. We send a zero-length 1248 // OnControlFrameHeaderData() to indicate this. 1249 visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0); 1250 1251 // If this is a FIN, tell the caller. 1252 if (current_frame_flags_ & CONTROL_FLAG_FIN) { 1253 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); 1254 } 1255 1256 CHANGE_STATE(SPDY_AUTO_RESET); 1257 } 1258 1259 // Handle error. 1260 if (!processed_successfully) { 1261 return data_len; 1262 } 1263 1264 // Return amount processed. 1265 return process_bytes; 1266 } 1267 1268 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, 1269 size_t data_len) { 1270 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); 1271 DCHECK_EQ(SETTINGS, current_frame_type_); 1272 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); 1273 size_t processed_bytes = 0; 1274 1275 // Loop over our incoming data. 1276 while (unprocessed_bytes > 0) { 1277 // Process up to one setting at a time. 1278 size_t processing = std::min( 1279 unprocessed_bytes, 1280 static_cast<size_t>(8 - settings_scratch_.setting_buf_len)); 1281 1282 // Check if we have a complete setting in our input. 1283 if (processing == 8) { 1284 // Parse the setting directly out of the input without buffering. 1285 if (!ProcessSetting(data + processed_bytes)) { 1286 set_error(SPDY_INVALID_CONTROL_FRAME); 1287 return processed_bytes; 1288 } 1289 } else { 1290 // Continue updating settings_scratch_.setting_buf. 1291 memcpy(settings_scratch_.setting_buf + settings_scratch_.setting_buf_len, 1292 data + processed_bytes, 1293 processing); 1294 settings_scratch_.setting_buf_len += processing; 1295 1296 // Check if we have a complete setting buffered. 1297 if (settings_scratch_.setting_buf_len == 8) { 1298 if (!ProcessSetting(settings_scratch_.setting_buf)) { 1299 set_error(SPDY_INVALID_CONTROL_FRAME); 1300 return processed_bytes; 1301 } 1302 // Reset settings_scratch_.setting_buf for our next setting. 1303 settings_scratch_.setting_buf_len = 0; 1304 } 1305 } 1306 1307 // Iterate. 1308 unprocessed_bytes -= processing; 1309 processed_bytes += processing; 1310 } 1311 1312 // Check if we're done handling this SETTINGS frame. 1313 remaining_data_length_ -= processed_bytes; 1314 if (remaining_data_length_ == 0) { 1315 CHANGE_STATE(SPDY_AUTO_RESET); 1316 } 1317 1318 return processed_bytes; 1319 } 1320 1321 bool SpdyFramer::ProcessSetting(const char* data) { 1322 // Extract fields. 1323 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. 1324 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); 1325 SettingsFlagsAndId id_and_flags = 1326 SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire); 1327 uint8 flags = id_and_flags.flags(); 1328 uint32 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); 1329 1330 // Validate id. 1331 switch (id_and_flags.id()) { 1332 case SETTINGS_UPLOAD_BANDWIDTH: 1333 case SETTINGS_DOWNLOAD_BANDWIDTH: 1334 case SETTINGS_ROUND_TRIP_TIME: 1335 case SETTINGS_MAX_CONCURRENT_STREAMS: 1336 case SETTINGS_CURRENT_CWND: 1337 case SETTINGS_DOWNLOAD_RETRANS_RATE: 1338 case SETTINGS_INITIAL_WINDOW_SIZE: 1339 // Valid values. 1340 break; 1341 default: 1342 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_and_flags.id(); 1343 return false; 1344 } 1345 SpdySettingsIds id = static_cast<SpdySettingsIds>(id_and_flags.id()); 1346 1347 // Detect duplciates. 1348 if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) { 1349 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id 1350 << " in " << display_protocol_ << " SETTINGS frame " 1351 << "(last settikng id was " 1352 << settings_scratch_.last_setting_id << ")."; 1353 return false; 1354 } 1355 settings_scratch_.last_setting_id = id; 1356 1357 // Validate flags. 1358 uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED; 1359 if ((flags & ~(kFlagsMask)) != 0) { 1360 DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": " 1361 << flags; 1362 return false; 1363 } 1364 1365 // Validation succeeded. Pass on to visitor. 1366 visitor_->OnSetting(id, flags, value); 1367 return true; 1368 } 1369 1370 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { 1371 size_t original_len = len; 1372 size_t bytes_read = 1373 UpdateCurrentFrameBuffer(&data, &len, remaining_data_length_); 1374 remaining_data_length_ -= bytes_read; 1375 if (remaining_data_length_ == 0) { 1376 SpdyFrameReader reader(current_frame_buffer_.get(), 1377 current_frame_buffer_length_); 1378 reader.Seek(GetControlFrameHeaderSize()); // Skip frame header. 1379 1380 // Use frame-specific handlers. 1381 switch (current_frame_type_) { 1382 case RST_STREAM: { 1383 bool successful_read = true; 1384 if (spdy_version_ < 4) { 1385 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1386 DCHECK(successful_read); 1387 } 1388 SpdyRstStreamStatus status = RST_STREAM_INVALID; 1389 uint32 status_raw = status; 1390 successful_read = reader.ReadUInt32(&status_raw); 1391 DCHECK(successful_read); 1392 if (status_raw > RST_STREAM_INVALID && 1393 status_raw < RST_STREAM_NUM_STATUS_CODES) { 1394 status = static_cast<SpdyRstStreamStatus>(status_raw); 1395 } else { 1396 // TODO(hkhalil): Probably best to OnError here, depending on 1397 // our interpretation of the spec. Keeping with existing liberal 1398 // behavior for now. 1399 } 1400 DCHECK(reader.IsDoneReading()); 1401 visitor_->OnRstStream(current_frame_stream_id_, status); 1402 } 1403 break; 1404 case PING: { 1405 SpdyPingId id = 0; 1406 bool successful_read = reader.ReadUInt32(&id); 1407 DCHECK(successful_read); 1408 DCHECK(reader.IsDoneReading()); 1409 visitor_->OnPing(id); 1410 } 1411 break; 1412 case GOAWAY: { 1413 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1414 DCHECK(successful_read); 1415 SpdyGoAwayStatus status = GOAWAY_OK; 1416 if (spdy_version_ >= 3) { 1417 uint32 status_raw = GOAWAY_OK; 1418 successful_read = reader.ReadUInt32(&status_raw); 1419 DCHECK(successful_read); 1420 if (status_raw >= GOAWAY_OK && 1421 status_raw < static_cast<uint32>(GOAWAY_NUM_STATUS_CODES)) { 1422 status = static_cast<SpdyGoAwayStatus>(status_raw); 1423 } else { 1424 // TODO(hkhalil): Probably best to OnError here, depending on 1425 // our interpretation of the spec. Keeping with existing liberal 1426 // behavior for now. 1427 } 1428 } 1429 DCHECK(reader.IsDoneReading()); 1430 visitor_->OnGoAway(current_frame_stream_id_, status); 1431 } 1432 break; 1433 case WINDOW_UPDATE: { 1434 uint32 delta_window_size = 0; 1435 bool successful_read = true; 1436 if (spdy_version_ < 4) { 1437 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); 1438 DCHECK(successful_read); 1439 } 1440 successful_read = reader.ReadUInt32(&delta_window_size); 1441 DCHECK(successful_read); 1442 DCHECK(reader.IsDoneReading()); 1443 visitor_->OnWindowUpdate(current_frame_stream_id_, 1444 delta_window_size); 1445 } 1446 break; 1447 case BLOCKED: { 1448 DCHECK_LE(4, protocol_version()); 1449 DCHECK(reader.IsDoneReading()); 1450 visitor_->OnBlocked(current_frame_stream_id_); 1451 } 1452 break; 1453 default: 1454 // Unreachable. 1455 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; 1456 } 1457 1458 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); 1459 } 1460 return original_len - len; 1461 } 1462 1463 size_t SpdyFramer::ProcessCredentialFramePayload(const char* data, size_t len) { 1464 if (len > 0) { 1465 // Clamp to the actual remaining payload. 1466 if (len > remaining_data_length_) { 1467 len = remaining_data_length_; 1468 } 1469 bool processed_succesfully = visitor_->OnCredentialFrameData(data, len); 1470 remaining_data_length_ -= len; 1471 if (!processed_succesfully) { 1472 set_error(SPDY_CREDENTIAL_FRAME_CORRUPT); 1473 } else if (remaining_data_length_ == 0) { 1474 visitor_->OnCredentialFrameData(NULL, 0); 1475 CHANGE_STATE(SPDY_AUTO_RESET); 1476 } 1477 } 1478 return len; 1479 } 1480 1481 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { 1482 size_t original_len = len; 1483 1484 if (remaining_data_length_ > 0) { 1485 size_t amount_to_forward = std::min(remaining_data_length_, len); 1486 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) { 1487 // Only inform the visitor if there is data. 1488 if (amount_to_forward) { 1489 visitor_->OnStreamFrameData( 1490 current_frame_stream_id_, data, amount_to_forward, false); 1491 } 1492 } 1493 data += amount_to_forward; 1494 len -= amount_to_forward; 1495 remaining_data_length_ -= amount_to_forward; 1496 1497 // If the FIN flag is set, and there is no more data in this data 1498 // frame, inform the visitor of EOF via a 0-length data frame. 1499 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) { 1500 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); 1501 } 1502 } 1503 1504 if (remaining_data_length_ == 0) { 1505 CHANGE_STATE(SPDY_AUTO_RESET); 1506 } 1507 return original_len - len; 1508 } 1509 1510 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, 1511 size_t header_length, 1512 SpdyHeaderBlock* block) const { 1513 SpdyFrameReader reader(header_data, header_length); 1514 1515 // Read number of headers. 1516 uint32 num_headers; 1517 if (spdy_version_ < 3) { 1518 uint16 temp; 1519 if (!reader.ReadUInt16(&temp)) { 1520 DLOG(INFO) << "Unable to read number of headers."; 1521 return 0; 1522 } 1523 num_headers = temp; 1524 } else { 1525 if (!reader.ReadUInt32(&num_headers)) { 1526 DLOG(INFO) << "Unable to read number of headers."; 1527 return 0; 1528 } 1529 } 1530 1531 // Read each header. 1532 for (uint32 index = 0; index < num_headers; ++index) { 1533 base::StringPiece temp; 1534 1535 // Read header name. 1536 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp) 1537 : !reader.ReadStringPiece32(&temp)) { 1538 DLOG(INFO) << "Unable to read header name (" << index + 1 << " of " 1539 << num_headers << ")."; 1540 return 0; 1541 } 1542 std::string name = temp.as_string(); 1543 1544 // Read header value. 1545 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp) 1546 : !reader.ReadStringPiece32(&temp)) { 1547 DLOG(INFO) << "Unable to read header value (" << index + 1 << " of " 1548 << num_headers << ")."; 1549 return 0; 1550 } 1551 std::string value = temp.as_string(); 1552 1553 // Ensure no duplicates. 1554 if (block->find(name) != block->end()) { 1555 DLOG(INFO) << "Duplicate header '" << name << "' (" << index + 1 << " of " 1556 << num_headers << ")."; 1557 return 0; 1558 } 1559 1560 // Store header. 1561 (*block)[name] = value; 1562 } 1563 return reader.GetBytesConsumed(); 1564 } 1565 1566 /* static */ 1567 bool SpdyFramer::ParseCredentialData(const char* data, size_t len, 1568 SpdyCredential* credential) { 1569 DCHECK(credential); 1570 1571 SpdyFrameReader parser(data, len); 1572 base::StringPiece temp; 1573 if (!parser.ReadUInt16(&credential->slot)) { 1574 return false; 1575 } 1576 1577 if (!parser.ReadStringPiece32(&temp)) { 1578 return false; 1579 } 1580 credential->proof = temp.as_string(); 1581 1582 while (!parser.IsDoneReading()) { 1583 if (!parser.ReadStringPiece32(&temp)) { 1584 return false; 1585 } 1586 credential->certs.push_back(temp.as_string()); 1587 } 1588 return true; 1589 } 1590 1591 SpdyFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, 1592 const char* data, 1593 uint32 len, SpdyDataFlags flags) const { 1594 DCHECK_EQ(0, flags & (!DATA_FLAG_FIN)); 1595 1596 SpdyDataIR data_ir(stream_id, base::StringPiece(data, len)); 1597 data_ir.set_fin(flags & DATA_FLAG_FIN); 1598 return SerializeData(data_ir); 1599 } 1600 1601 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& data) const { 1602 const size_t kSize = GetDataFrameMinimumSize() + data.data().length(); 1603 1604 SpdyDataFlags flags = DATA_FLAG_NONE; 1605 if (data.fin()) { 1606 flags = DATA_FLAG_FIN; 1607 } 1608 1609 SpdyFrameBuilder builder(kSize); 1610 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); 1611 builder.WriteBytes(data.data().data(), data.data().length()); 1612 DCHECK_EQ(kSize, builder.length()); 1613 return builder.take(); 1614 } 1615 1616 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader( 1617 const SpdyDataIR& data) const { 1618 const size_t kSize = GetDataFrameMinimumSize(); 1619 1620 SpdyDataFlags flags = DATA_FLAG_NONE; 1621 if (data.fin()) { 1622 flags = DATA_FLAG_FIN; 1623 } 1624 1625 SpdyFrameBuilder builder(kSize); 1626 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); 1627 if (protocol_version() < 4) { 1628 builder.OverwriteLength(*this, data.data().length()); 1629 } else { 1630 builder.OverwriteLength(*this, data.data().length() + kSize); 1631 } 1632 DCHECK_EQ(kSize, builder.length()); 1633 return builder.take(); 1634 } 1635 1636 SpdyFrame* SpdyFramer::CreateSynStream( 1637 SpdyStreamId stream_id, 1638 SpdyStreamId associated_stream_id, 1639 SpdyPriority priority, 1640 uint8 credential_slot, 1641 SpdyControlFlags flags, 1642 bool compressed, 1643 const SpdyHeaderBlock* headers) { 1644 DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN & ~CONTROL_FLAG_UNIDIRECTIONAL); 1645 DCHECK_EQ(enable_compression_, compressed); 1646 1647 SpdySynStreamIR syn_stream(stream_id); 1648 syn_stream.set_associated_to_stream_id(associated_stream_id); 1649 syn_stream.set_priority(priority); 1650 syn_stream.set_slot(credential_slot); 1651 syn_stream.set_fin((flags & CONTROL_FLAG_FIN) != 0); 1652 syn_stream.set_unidirectional((flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0); 1653 // TODO(hkhalil): Avoid copy here. 1654 *(syn_stream.GetMutableNameValueBlock()) = *headers; 1655 1656 return SerializeSynStream(syn_stream); 1657 } 1658 1659 SpdySerializedFrame* SpdyFramer::SerializeSynStream( 1660 const SpdySynStreamIR& syn_stream) { 1661 uint8 flags = 0; 1662 if (syn_stream.fin()) { 1663 flags |= CONTROL_FLAG_FIN; 1664 } 1665 if (syn_stream.unidirectional()) { 1666 flags |= CONTROL_FLAG_UNIDIRECTIONAL; 1667 } 1668 1669 // The size of this frame, including variable-length name-value block. 1670 const size_t size = GetSynStreamMinimumSize() 1671 + GetSerializedLength(syn_stream.name_value_block()); 1672 1673 SpdyFrameBuilder builder(size); 1674 if (spdy_version_ < 4) { 1675 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); 1676 builder.WriteUInt32(syn_stream.stream_id()); 1677 } else { 1678 builder.WriteFramePrefix(*this, 1679 SYN_STREAM, 1680 flags, 1681 syn_stream.stream_id()); 1682 } 1683 builder.WriteUInt32(syn_stream.associated_to_stream_id()); 1684 uint8 priority = syn_stream.priority(); 1685 if (priority > GetLowestPriority()) { 1686 DLOG(DFATAL) << "Priority out-of-bounds."; 1687 priority = GetLowestPriority(); 1688 } 1689 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); 1690 builder.WriteUInt8(syn_stream.slot()); 1691 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); 1692 SerializeNameValueBlock(&builder, syn_stream); 1693 1694 if (debug_visitor_) { 1695 const size_t payload_len = GetSerializedLength( 1696 protocol_version(), &(syn_stream.name_value_block())); 1697 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(), 1698 SYN_STREAM, 1699 payload_len, 1700 builder.length()); 1701 } 1702 1703 return builder.take(); 1704 } 1705 1706 SpdyFrame* SpdyFramer::CreateSynReply( 1707 SpdyStreamId stream_id, 1708 SpdyControlFlags flags, 1709 bool compressed, 1710 const SpdyHeaderBlock* headers) { 1711 DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN); 1712 DCHECK_EQ(enable_compression_, compressed); 1713 1714 SpdySynReplyIR syn_reply(stream_id); 1715 syn_reply.set_fin(flags & CONTROL_FLAG_FIN); 1716 // TODO(hkhalil): Avoid copy here. 1717 *(syn_reply.GetMutableNameValueBlock()) = *headers; 1718 1719 return SerializeSynReply(syn_reply); 1720 } 1721 1722 SpdySerializedFrame* SpdyFramer::SerializeSynReply( 1723 const SpdySynReplyIR& syn_reply) { 1724 uint8 flags = 0; 1725 if (syn_reply.fin()) { 1726 flags |= CONTROL_FLAG_FIN; 1727 } 1728 1729 // The size of this frame, including variable-length name-value block. 1730 size_t size = GetSynReplyMinimumSize() 1731 + GetSerializedLength(syn_reply.name_value_block()); 1732 1733 SpdyFrameBuilder builder(size); 1734 if (spdy_version_ < 4) { 1735 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); 1736 builder.WriteUInt32(syn_reply.stream_id()); 1737 } else { 1738 builder.WriteFramePrefix(*this, 1739 SYN_REPLY, 1740 flags, 1741 syn_reply.stream_id()); 1742 } 1743 if (protocol_version() < 3) { 1744 builder.WriteUInt16(0); // Unused. 1745 } 1746 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); 1747 SerializeNameValueBlock(&builder, syn_reply); 1748 1749 if (debug_visitor_) { 1750 const size_t payload_len = GetSerializedLength( 1751 protocol_version(), &(syn_reply.name_value_block())); 1752 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(), 1753 SYN_REPLY, 1754 payload_len, 1755 builder.length()); 1756 } 1757 1758 return builder.take(); 1759 } 1760 1761 SpdyFrame* SpdyFramer::CreateRstStream( 1762 SpdyStreamId stream_id, 1763 SpdyRstStreamStatus status) const { 1764 SpdyRstStreamIR rst_stream(stream_id, status); 1765 return SerializeRstStream(rst_stream); 1766 } 1767 1768 SpdySerializedFrame* SpdyFramer::SerializeRstStream( 1769 const SpdyRstStreamIR& rst_stream) const { 1770 SpdyFrameBuilder builder(GetRstStreamSize()); 1771 if (spdy_version_ < 4) { 1772 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); 1773 builder.WriteUInt32(rst_stream.stream_id()); 1774 } else { 1775 builder.WriteFramePrefix(*this, 1776 RST_STREAM, 1777 0, 1778 rst_stream.stream_id()); 1779 } 1780 builder.WriteUInt32(rst_stream.status()); 1781 DCHECK_EQ(GetRstStreamSize(), builder.length()); 1782 return builder.take(); 1783 } 1784 1785 SpdyFrame* SpdyFramer::CreateSettings( 1786 const SettingsMap& values) const { 1787 SpdySettingsIR settings; 1788 for (SettingsMap::const_iterator it = values.begin(); 1789 it != values.end(); 1790 ++it) { 1791 settings.AddSetting(it->first, 1792 (it->second.first & SETTINGS_FLAG_PLEASE_PERSIST) != 0, 1793 (it->second.first & SETTINGS_FLAG_PERSISTED) != 0, 1794 it->second.second); 1795 } 1796 return SerializeSettings(settings); 1797 } 1798 1799 SpdySerializedFrame* SpdyFramer::SerializeSettings( 1800 const SpdySettingsIR& settings) const { 1801 uint8 flags = 0; 1802 if (settings.clear_settings()) { 1803 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; 1804 } 1805 const SpdySettingsIR::ValueMap* values = &(settings.values()); 1806 1807 // Size, in bytes, of this SETTINGS frame. 1808 const size_t size = GetSettingsMinimumSize() + (values->size() * 8); 1809 1810 SpdyFrameBuilder builder(size); 1811 if (spdy_version_ < 4) { 1812 builder.WriteControlFrameHeader(*this, SETTINGS, flags); 1813 } else { 1814 builder.WriteFramePrefix(*this, SETTINGS, flags, 0); 1815 } 1816 builder.WriteUInt32(values->size()); 1817 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); 1818 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); 1819 it != values->end(); 1820 ++it) { 1821 uint8 setting_flags = 0; 1822 if (it->second.persist_value) { 1823 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; 1824 } 1825 if (it->second.persisted) { 1826 setting_flags |= SETTINGS_FLAG_PERSISTED; 1827 } 1828 SettingsFlagsAndId flags_and_id(setting_flags, it->first); 1829 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); 1830 builder.WriteBytes(&id_and_flags_wire, 4); 1831 builder.WriteUInt32(it->second.value); 1832 } 1833 DCHECK_EQ(size, builder.length()); 1834 return builder.take(); 1835 } 1836 1837 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const { 1838 DCHECK_LE(4, protocol_version()); 1839 SpdyFrameBuilder builder(GetBlockedSize()); 1840 builder.WriteFramePrefix(*this, BLOCKED, kNoFlags, blocked.stream_id()); 1841 return builder.take(); 1842 } 1843 1844 SpdyFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const { 1845 SpdyPingIR ping(unique_id); 1846 return SerializePing(ping); 1847 } 1848 1849 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { 1850 SpdyFrameBuilder builder(GetPingSize()); 1851 if (spdy_version_ < 4) { 1852 builder.WriteControlFrameHeader(*this, PING, kNoFlags); 1853 } else { 1854 builder.WriteFramePrefix(*this, PING, 0, 0); 1855 } 1856 builder.WriteUInt32(ping.id()); 1857 DCHECK_EQ(GetPingSize(), builder.length()); 1858 return builder.take(); 1859 } 1860 1861 SpdyFrame* SpdyFramer::CreateGoAway( 1862 SpdyStreamId last_accepted_stream_id, 1863 SpdyGoAwayStatus status) const { 1864 SpdyGoAwayIR goaway(last_accepted_stream_id, status); 1865 return SerializeGoAway(goaway); 1866 } 1867 1868 SpdySerializedFrame* SpdyFramer::SerializeGoAway( 1869 const SpdyGoAwayIR& goaway) const { 1870 SpdyFrameBuilder builder(GetGoAwaySize()); 1871 if (spdy_version_ < 4) { 1872 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); 1873 } else { 1874 builder.WriteFramePrefix(*this, GOAWAY, 0, 0); 1875 } 1876 builder.WriteUInt32(goaway.last_good_stream_id()); 1877 if (protocol_version() >= 3) { 1878 builder.WriteUInt32(goaway.status()); 1879 } 1880 DCHECK_EQ(GetGoAwaySize(), builder.length()); 1881 return builder.take(); 1882 } 1883 1884 SpdyFrame* SpdyFramer::CreateHeaders( 1885 SpdyStreamId stream_id, 1886 SpdyControlFlags flags, 1887 bool compressed, 1888 const SpdyHeaderBlock* header_block) { 1889 // Basically the same as CreateSynReply(). 1890 DCHECK_EQ(0, flags & (!CONTROL_FLAG_FIN)); 1891 DCHECK_EQ(enable_compression_, compressed); 1892 1893 SpdyHeadersIR headers(stream_id); 1894 headers.set_fin(flags & CONTROL_FLAG_FIN); 1895 // TODO(hkhalil): Avoid copy here. 1896 *(headers.GetMutableNameValueBlock()) = *header_block; 1897 1898 return SerializeHeaders(headers); 1899 } 1900 1901 SpdySerializedFrame* SpdyFramer::SerializeHeaders( 1902 const SpdyHeadersIR& headers) { 1903 uint8 flags = 0; 1904 if (headers.fin()) { 1905 flags |= CONTROL_FLAG_FIN; 1906 } 1907 1908 // The size of this frame, including variable-length name-value block. 1909 size_t size = GetHeadersMinimumSize() 1910 + GetSerializedLength(headers.name_value_block()); 1911 1912 SpdyFrameBuilder builder(size); 1913 if (spdy_version_ < 4) { 1914 builder.WriteControlFrameHeader(*this, HEADERS, flags); 1915 builder.WriteUInt32(headers.stream_id()); 1916 } else { 1917 builder.WriteFramePrefix(*this, 1918 HEADERS, 1919 flags, 1920 headers.stream_id()); 1921 } 1922 if (protocol_version() < 3) { 1923 builder.WriteUInt16(0); // Unused. 1924 } 1925 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); 1926 1927 SerializeNameValueBlock(&builder, headers); 1928 1929 if (debug_visitor_) { 1930 const size_t payload_len = GetSerializedLength( 1931 protocol_version(), &(headers.name_value_block())); 1932 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), 1933 HEADERS, 1934 payload_len, 1935 builder.length()); 1936 } 1937 1938 return builder.take(); 1939 } 1940 1941 SpdyFrame* SpdyFramer::CreateWindowUpdate( 1942 SpdyStreamId stream_id, 1943 uint32 delta_window_size) const { 1944 SpdyWindowUpdateIR window_update(stream_id, delta_window_size); 1945 return SerializeWindowUpdate(window_update); 1946 } 1947 1948 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( 1949 const SpdyWindowUpdateIR& window_update) const { 1950 SpdyFrameBuilder builder(GetWindowUpdateSize()); 1951 if (spdy_version_ < 4) { 1952 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); 1953 builder.WriteUInt32(window_update.stream_id()); 1954 } else { 1955 builder.WriteFramePrefix(*this, 1956 WINDOW_UPDATE, 1957 kNoFlags, 1958 window_update.stream_id()); 1959 } 1960 builder.WriteUInt32(window_update.delta()); 1961 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); 1962 return builder.take(); 1963 } 1964 1965 // TODO(hkhalil): Gut with SpdyCredential removal. 1966 SpdyFrame* SpdyFramer::CreateCredentialFrame( 1967 const SpdyCredential& credential) const { 1968 SpdyCredentialIR credential_ir(credential.slot); 1969 credential_ir.set_proof(credential.proof); 1970 for (std::vector<std::string>::const_iterator cert = credential.certs.begin(); 1971 cert != credential.certs.end(); 1972 ++cert) { 1973 credential_ir.AddCertificate(*cert); 1974 } 1975 return SerializeCredential(credential_ir); 1976 } 1977 1978 SpdySerializedFrame* SpdyFramer::SerializeCredential( 1979 const SpdyCredentialIR& credential) const { 1980 size_t size = GetCredentialMinimumSize(); 1981 size += 4 + credential.proof().length(); // Room for proof. 1982 for (SpdyCredentialIR::CertificateList::const_iterator it = 1983 credential.certificates()->begin(); 1984 it != credential.certificates()->end(); 1985 ++it) { 1986 size += 4 + it->length(); // Room for certificate. 1987 } 1988 1989 SpdyFrameBuilder builder(size); 1990 if (spdy_version_ < 4) { 1991 builder.WriteControlFrameHeader(*this, CREDENTIAL, kNoFlags); 1992 } else { 1993 builder.WriteFramePrefix(*this, CREDENTIAL, kNoFlags, 0); 1994 } 1995 builder.WriteUInt16(credential.slot()); 1996 DCHECK_EQ(GetCredentialMinimumSize(), builder.length()); 1997 builder.WriteStringPiece32(credential.proof()); 1998 for (SpdyCredentialIR::CertificateList::const_iterator it = 1999 credential.certificates()->begin(); 2000 it != credential.certificates()->end(); 2001 ++it) { 2002 builder.WriteStringPiece32(*it); 2003 } 2004 DCHECK_EQ(size, builder.length()); 2005 return builder.take(); 2006 } 2007 2008 SpdyFrame* SpdyFramer::CreatePushPromise( 2009 SpdyStreamId stream_id, 2010 SpdyStreamId promised_stream_id, 2011 const SpdyHeaderBlock* header_block) { 2012 SpdyPushPromiseIR push_promise(stream_id, promised_stream_id); 2013 // TODO(hkhalil): Avoid copy here. 2014 *(push_promise.GetMutableNameValueBlock()) = *header_block; 2015 2016 return SerializePushPromise(push_promise); 2017 } 2018 2019 SpdyFrame* SpdyFramer::SerializePushPromise( 2020 const SpdyPushPromiseIR& push_promise) { 2021 DCHECK_LE(4, protocol_version()); 2022 // The size of this frame, including variable-length name-value block. 2023 size_t size = GetPushPromiseMinimumSize() 2024 + GetSerializedLength(push_promise.name_value_block()); 2025 2026 SpdyFrameBuilder builder(size); 2027 builder.WriteFramePrefix(*this, PUSH_PROMISE, kNoFlags, 2028 push_promise.stream_id()); 2029 builder.WriteUInt32(push_promise.promised_stream_id()); 2030 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); 2031 2032 SerializeNameValueBlock(&builder, push_promise); 2033 2034 if (debug_visitor_) { 2035 const size_t payload_len = GetSerializedLength( 2036 protocol_version(), &(push_promise.name_value_block())); 2037 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), 2038 PUSH_PROMISE, payload_len, builder.length()); 2039 } 2040 2041 return builder.take(); 2042 } 2043 2044 namespace { 2045 2046 class FrameSerializationVisitor : public SpdyFrameVisitor { 2047 public: 2048 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} 2049 virtual ~FrameSerializationVisitor() {} 2050 2051 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); } 2052 2053 virtual void VisitData(const SpdyDataIR& data) OVERRIDE { 2054 frame_.reset(framer_->SerializeData(data)); 2055 } 2056 virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) OVERRIDE { 2057 frame_.reset(framer_->SerializeSynStream(syn_stream)); 2058 } 2059 virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) OVERRIDE { 2060 frame_.reset(framer_->SerializeSynReply(syn_reply)); 2061 } 2062 virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) OVERRIDE { 2063 frame_.reset(framer_->SerializeRstStream(rst_stream)); 2064 } 2065 virtual void VisitSettings(const SpdySettingsIR& settings) OVERRIDE { 2066 frame_.reset(framer_->SerializeSettings(settings)); 2067 } 2068 virtual void VisitPing(const SpdyPingIR& ping) OVERRIDE { 2069 frame_.reset(framer_->SerializePing(ping)); 2070 } 2071 virtual void VisitGoAway(const SpdyGoAwayIR& goaway) OVERRIDE { 2072 frame_.reset(framer_->SerializeGoAway(goaway)); 2073 } 2074 virtual void VisitHeaders(const SpdyHeadersIR& headers) OVERRIDE { 2075 frame_.reset(framer_->SerializeHeaders(headers)); 2076 } 2077 virtual void VisitWindowUpdate( 2078 const SpdyWindowUpdateIR& window_update) OVERRIDE { 2079 frame_.reset(framer_->SerializeWindowUpdate(window_update)); 2080 } 2081 virtual void VisitCredential(const SpdyCredentialIR& credential) OVERRIDE { 2082 frame_.reset(framer_->SerializeCredential(credential)); 2083 } 2084 virtual void VisitBlocked(const SpdyBlockedIR& blocked) OVERRIDE { 2085 frame_.reset(framer_->SerializeBlocked(blocked)); 2086 } 2087 virtual void VisitPushPromise( 2088 const SpdyPushPromiseIR& push_promise) OVERRIDE { 2089 frame_.reset(framer_->SerializePushPromise(push_promise)); 2090 } 2091 2092 private: 2093 SpdyFramer* framer_; 2094 scoped_ptr<SpdySerializedFrame> frame_; 2095 }; 2096 2097 } // namespace 2098 2099 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { 2100 FrameSerializationVisitor visitor(this); 2101 frame.Visit(&visitor); 2102 return visitor.ReleaseSerializedFrame(); 2103 } 2104 2105 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) { 2106 const size_t uncompressed_length = 2107 GetSerializedLength(protocol_version(), &headers); 2108 if (!enable_compression_) { 2109 return uncompressed_length; 2110 } 2111 z_stream* compressor = GetHeaderCompressor(); 2112 // Since we'll be performing lots of flushes when compressing the data, 2113 // zlib's lower bounds may be insufficient. 2114 return 2 * deflateBound(compressor, uncompressed_length); 2115 } 2116 2117 // The following compression setting are based on Brian Olson's analysis. See 2118 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792 2119 // for more details. 2120 #if defined(USE_SYSTEM_ZLIB) 2121 // System zlib is not expected to have workaround for http://crbug.com/139744, 2122 // so disable compression in that case. 2123 // TODO(phajdan.jr): Remove the special case when it's no longer necessary. 2124 static const int kCompressorLevel = 0; 2125 #else // !defined(USE_SYSTEM_ZLIB) 2126 static const int kCompressorLevel = 9; 2127 #endif // !defined(USE_SYSTEM_ZLIB) 2128 static const int kCompressorWindowSizeInBits = 11; 2129 static const int kCompressorMemLevel = 1; 2130 2131 z_stream* SpdyFramer::GetHeaderCompressor() { 2132 if (header_compressor_.get()) 2133 return header_compressor_.get(); // Already initialized. 2134 2135 header_compressor_.reset(new z_stream); 2136 memset(header_compressor_.get(), 0, sizeof(z_stream)); 2137 2138 int success = deflateInit2(header_compressor_.get(), 2139 kCompressorLevel, 2140 Z_DEFLATED, 2141 kCompressorWindowSizeInBits, 2142 kCompressorMemLevel, 2143 Z_DEFAULT_STRATEGY); 2144 if (success == Z_OK) { 2145 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary 2146 : kV3Dictionary; 2147 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize 2148 : kV3DictionarySize; 2149 success = deflateSetDictionary(header_compressor_.get(), 2150 reinterpret_cast<const Bytef*>(dictionary), 2151 dictionary_size); 2152 } 2153 if (success != Z_OK) { 2154 LOG(WARNING) << "deflateSetDictionary failure: " << success; 2155 header_compressor_.reset(NULL); 2156 return NULL; 2157 } 2158 return header_compressor_.get(); 2159 } 2160 2161 z_stream* SpdyFramer::GetHeaderDecompressor() { 2162 if (header_decompressor_.get()) 2163 return header_decompressor_.get(); // Already initialized. 2164 2165 header_decompressor_.reset(new z_stream); 2166 memset(header_decompressor_.get(), 0, sizeof(z_stream)); 2167 2168 int success = inflateInit(header_decompressor_.get()); 2169 if (success != Z_OK) { 2170 LOG(WARNING) << "inflateInit failure: " << success; 2171 header_decompressor_.reset(NULL); 2172 return NULL; 2173 } 2174 return header_decompressor_.get(); 2175 } 2176 2177 // Incrementally decompress the control frame's header block, feeding the 2178 // result to the visitor in chunks. Continue this until the visitor 2179 // indicates that it cannot process any more data, or (more commonly) we 2180 // run out of data to deliver. 2181 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( 2182 SpdyStreamId stream_id, 2183 const char* data, 2184 size_t len) { 2185 // Get a decompressor or set error. 2186 z_stream* decomp = GetHeaderDecompressor(); 2187 if (decomp == NULL) { 2188 LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers."; 2189 set_error(SPDY_DECOMPRESS_FAILURE); 2190 return false; 2191 } 2192 2193 bool processed_successfully = true; 2194 char buffer[kHeaderDataChunkMaxSize]; 2195 2196 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data)); 2197 decomp->avail_in = len; 2198 // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we 2199 // signal an error back in ProcessControlFrameBeforeHeaderBlock. So if we've 2200 // reached this method successfully, stream_id should be nonzero. 2201 DCHECK_LT(0u, stream_id); 2202 while (decomp->avail_in > 0 && processed_successfully) { 2203 decomp->next_out = reinterpret_cast<Bytef*>(buffer); 2204 decomp->avail_out = arraysize(buffer); 2205 2206 int rv = inflate(decomp, Z_SYNC_FLUSH); 2207 if (rv == Z_NEED_DICT) { 2208 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary 2209 : kV3Dictionary; 2210 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize 2211 : kV3DictionarySize; 2212 const DictionaryIds& ids = g_dictionary_ids.Get(); 2213 const uLong dictionary_id = (spdy_version_ < 3) ? ids.v2_dictionary_id 2214 : ids.v3_dictionary_id; 2215 // Need to try again with the right dictionary. 2216 if (decomp->adler == dictionary_id) { 2217 rv = inflateSetDictionary(decomp, 2218 reinterpret_cast<const Bytef*>(dictionary), 2219 dictionary_size); 2220 if (rv == Z_OK) 2221 rv = inflate(decomp, Z_SYNC_FLUSH); 2222 } 2223 } 2224 2225 // Inflate will generate a Z_BUF_ERROR if it runs out of input 2226 // without producing any output. The input is consumed and 2227 // buffered internally by zlib so we can detect this condition by 2228 // checking if avail_in is 0 after the call to inflate. 2229 bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0)); 2230 if ((rv == Z_OK) || input_exhausted) { 2231 size_t decompressed_len = arraysize(buffer) - decomp->avail_out; 2232 if (decompressed_len > 0) { 2233 processed_successfully = visitor_->OnControlFrameHeaderData( 2234 stream_id, buffer, decompressed_len); 2235 } 2236 if (!processed_successfully) { 2237 // Assume that the problem was the header block was too large for the 2238 // visitor. 2239 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 2240 } 2241 } else { 2242 DLOG(WARNING) << "inflate failure: " << rv << " " << len; 2243 set_error(SPDY_DECOMPRESS_FAILURE); 2244 processed_successfully = false; 2245 } 2246 } 2247 return processed_successfully; 2248 } 2249 2250 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( 2251 SpdyStreamId stream_id, const char* data, size_t len) { 2252 bool read_successfully = true; 2253 while (read_successfully && len > 0) { 2254 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); 2255 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data, 2256 bytes_to_deliver); 2257 data += bytes_to_deliver; 2258 len -= bytes_to_deliver; 2259 if (!read_successfully) { 2260 // Assume that the problem was the header block was too large for the 2261 // visitor. 2262 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 2263 } 2264 } 2265 return read_successfully; 2266 } 2267 2268 void SpdyFramer::SerializeNameValueBlockWithoutCompression( 2269 SpdyFrameBuilder* builder, 2270 const SpdyNameValueBlock& name_value_block) const { 2271 // Serialize number of headers. 2272 if (protocol_version() < 3) { 2273 builder->WriteUInt16(name_value_block.size()); 2274 } else { 2275 builder->WriteUInt32(name_value_block.size()); 2276 } 2277 2278 // Serialize each header. 2279 for (SpdyHeaderBlock::const_iterator it = name_value_block.begin(); 2280 it != name_value_block.end(); 2281 ++it) { 2282 if (protocol_version() < 3) { 2283 builder->WriteString(it->first); 2284 builder->WriteString(it->second); 2285 } else { 2286 builder->WriteStringPiece32(it->first); 2287 builder->WriteStringPiece32(it->second); 2288 } 2289 } 2290 } 2291 2292 void SpdyFramer::SerializeNameValueBlock( 2293 SpdyFrameBuilder* builder, 2294 const SpdyFrameWithNameValueBlockIR& frame) { 2295 if (!enable_compression_) { 2296 return SerializeNameValueBlockWithoutCompression(builder, 2297 frame.name_value_block()); 2298 } 2299 2300 // First build an uncompressed version to be fed into the compressor. 2301 const size_t uncompressed_len = GetSerializedLength( 2302 protocol_version(), &(frame.name_value_block())); 2303 SpdyFrameBuilder uncompressed_builder(uncompressed_len); 2304 SerializeNameValueBlockWithoutCompression(&uncompressed_builder, 2305 frame.name_value_block()); 2306 scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take()); 2307 2308 z_stream* compressor = GetHeaderCompressor(); 2309 if (!compressor) { 2310 LOG(DFATAL) << "Could not obtain compressor."; 2311 return; 2312 } 2313 2314 base::StatsCounter compressed_frames("spdy.CompressedFrames"); 2315 base::StatsCounter pre_compress_bytes("spdy.PreCompressSize"); 2316 base::StatsCounter post_compress_bytes("spdy.PostCompressSize"); 2317 2318 // Create an output frame. 2319 // Since we'll be performing lots of flushes when compressing the data, 2320 // zlib's lower bounds may be insufficient. 2321 // 2322 // TODO(akalin): Avoid the duplicate calculation with 2323 // GetSerializedLength(const SpdyHeaderBlock&). 2324 const int compressed_max_size = 2325 2 * deflateBound(compressor, uncompressed_len); 2326 2327 // TODO(phajdan.jr): Clean up after we no longer need 2328 // to workaround http://crbug.com/139744. 2329 #if defined(USE_SYSTEM_ZLIB) 2330 compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload->data()); 2331 compressor->avail_in = uncompressed_len; 2332 #endif // defined(USE_SYSTEM_ZLIB) 2333 compressor->next_out = reinterpret_cast<Bytef*>( 2334 builder->GetWritableBuffer(compressed_max_size)); 2335 compressor->avail_out = compressed_max_size; 2336 2337 // TODO(phajdan.jr): Clean up after we no longer need 2338 // to workaround http://crbug.com/139744. 2339 #if defined(USE_SYSTEM_ZLIB) 2340 int rv = deflate(compressor, Z_SYNC_FLUSH); 2341 if (rv != Z_OK) { // How can we know that it compressed everything? 2342 // This shouldn't happen, right? 2343 LOG(WARNING) << "deflate failure: " << rv; 2344 // TODO(akalin): Upstream this return. 2345 return; 2346 } 2347 #else 2348 WriteHeaderBlockToZ(&frame.name_value_block(), compressor); 2349 #endif // defined(USE_SYSTEM_ZLIB) 2350 2351 int compressed_size = compressed_max_size - compressor->avail_out; 2352 builder->Seek(compressed_size); 2353 builder->RewriteLength(*this); 2354 2355 pre_compress_bytes.Add(uncompressed_len); 2356 post_compress_bytes.Add(compressed_size); 2357 2358 compressed_frames.Increment(); 2359 } 2360 2361 } // namespace net 2362