| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/spdy/spdy_framer.h" | 5 #include "net/spdy/spdy_framer.h" |
| 6 | 6 |
| 7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/metrics/stats_counters.h" | 9 #include "base/metrics/stats_counters.h" |
| 10 #include "base/third_party/valgrind/memcheck.h" | 10 #include "base/third_party/valgrind/memcheck.h" |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 case PING: | 490 case PING: |
| 491 return "PING"; | 491 return "PING"; |
| 492 case GOAWAY: | 492 case GOAWAY: |
| 493 return "GOAWAY"; | 493 return "GOAWAY"; |
| 494 case HEADERS: | 494 case HEADERS: |
| 495 return "HEADERS"; | 495 return "HEADERS"; |
| 496 case WINDOW_UPDATE: | 496 case WINDOW_UPDATE: |
| 497 return "WINDOW_UPDATE"; | 497 return "WINDOW_UPDATE"; |
| 498 case CREDENTIAL: | 498 case CREDENTIAL: |
| 499 return "CREDENTIAL"; | 499 return "CREDENTIAL"; |
| 500 case BLOCKED: | |
| 501 return "BLOCKED"; | |
| 502 case PUSH_PROMISE: | 500 case PUSH_PROMISE: |
| 503 return "PUSH_PROMISE"; | 501 return "PUSH_PROMISE"; |
| 504 case CONTINUATION: | 502 case CONTINUATION: |
| 505 return "CONTINUATION"; | 503 return "CONTINUATION"; |
| 504 case PRIORITY: |
| 505 return "PRIORITY"; |
| 506 case ALTSVC: | 506 case ALTSVC: |
| 507 return "ALTSVC"; | 507 return "ALTSVC"; |
| 508 case PRIORITY: | 508 case BLOCKED: |
| 509 return "PRIORITY"; | 509 return "BLOCKED"; |
| 510 } | 510 } |
| 511 return "UNKNOWN_CONTROL_TYPE"; | 511 return "UNKNOWN_CONTROL_TYPE"; |
| 512 } | 512 } |
| 513 | 513 |
| 514 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { | 514 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { |
| 515 DCHECK(visitor_); | 515 DCHECK(visitor_); |
| 516 DCHECK(data); | 516 DCHECK(data); |
| 517 | 517 |
| 518 size_t original_len = len; | 518 size_t original_len = len; |
| 519 do { | 519 do { |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 } | 830 } |
| 831 | 831 |
| 832 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { | 832 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { |
| 833 DCHECK_EQ(SPDY_NO_ERROR, error_code_); | 833 DCHECK_EQ(SPDY_NO_ERROR, error_code_); |
| 834 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); | 834 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); |
| 835 | 835 |
| 836 // TODO(mlavan): Either remove credential frames from the code entirely, | 836 // TODO(mlavan): Either remove credential frames from the code entirely, |
| 837 // or add them to parsing + serialization methods for SPDY3. | 837 // or add them to parsing + serialization methods for SPDY3. |
| 838 // Early detection of deprecated frames that we ignore. | 838 // Early detection of deprecated frames that we ignore. |
| 839 if (protocol_version() <= SPDY3) { | 839 if (protocol_version() <= SPDY3) { |
| 840 | |
| 841 if (control_frame_type_field == CREDENTIAL) { | 840 if (control_frame_type_field == CREDENTIAL) { |
| 842 current_frame_type_ = CREDENTIAL; | 841 current_frame_type_ = CREDENTIAL; |
| 843 DCHECK_EQ(SPDY3, protocol_version()); | 842 DCHECK_EQ(SPDY3, protocol_version()); |
| 844 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; | 843 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; |
| 845 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | 844 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 846 return; | 845 return; |
| 847 } | 846 } |
| 848 } | 847 } |
| 849 | 848 |
| 850 if (!SpdyConstants::IsValidFrameType(protocol_version(), | 849 if (!SpdyConstants::IsValidFrameType(protocol_version(), |
| 851 control_frame_type_field)) { | 850 control_frame_type_field)) { |
| 852 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field | 851 if (protocol_version() <= SPDY3) { |
| 853 << " (protocol version: " << protocol_version() << ")"; | 852 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field |
| 854 set_error(SPDY_INVALID_CONTROL_FRAME); | 853 << " (protocol version: " << protocol_version() << ")"; |
| 855 return; | 854 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 855 return; |
| 856 } else { |
| 857 // In HTTP2 we ignore unknown frame types for extensibility, as long as |
| 858 // the rest of the control frame header is valid. |
| 859 // We rely on the visitor to check validity of current_frame_stream_id_. |
| 860 bool valid_stream = visitor_->OnUnknownFrame(current_frame_stream_id_, |
| 861 control_frame_type_field); |
| 862 if (valid_stream) { |
| 863 DVLOG(1) << "Ignoring unknown frame type."; |
| 864 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 865 } else { |
| 866 // Report an invalid frame error and close the stream if the |
| 867 // stream_id is not valid. |
| 868 DLOG(WARNING) << "Unknown control frame type " |
| 869 << control_frame_type_field |
| 870 << " received on invalid stream " |
| 871 << current_frame_stream_id_; |
| 872 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 873 } |
| 874 return; |
| 875 } |
| 856 } | 876 } |
| 857 | 877 |
| 858 current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(), | 878 current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(), |
| 859 control_frame_type_field); | 879 control_frame_type_field); |
| 860 | 880 |
| 861 // Do some sanity checking on the control frame sizes and flags. | 881 // Do some sanity checking on the control frame sizes and flags. |
| 862 switch (current_frame_type_) { | 882 switch (current_frame_type_) { |
| 863 case SYN_STREAM: | 883 case SYN_STREAM: |
| 864 if (current_frame_length_ < GetSynStreamMinimumSize()) { | 884 if (current_frame_length_ < GetSynStreamMinimumSize()) { |
| 865 set_error(SPDY_INVALID_CONTROL_FRAME); | 885 set_error(SPDY_INVALID_CONTROL_FRAME); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 case WINDOW_UPDATE: | 983 case WINDOW_UPDATE: |
| 964 if (current_frame_length_ != GetWindowUpdateSize()) { | 984 if (current_frame_length_ != GetWindowUpdateSize()) { |
| 965 set_error(SPDY_INVALID_CONTROL_FRAME); | 985 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 966 } else if (current_frame_flags_ != 0) { | 986 } else if (current_frame_flags_ != 0) { |
| 967 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 987 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 968 } | 988 } |
| 969 break; | 989 break; |
| 970 case BLOCKED: | 990 case BLOCKED: |
| 971 if (current_frame_length_ != GetBlockedSize() || | 991 if (current_frame_length_ != GetBlockedSize() || |
| 972 protocol_version() <= SPDY3) { | 992 protocol_version() <= SPDY3) { |
| 973 // TODO(mlavan): BLOCKED frames are no longer part of SPDY4. | |
| 974 set_error(SPDY_INVALID_CONTROL_FRAME); | 993 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 975 } else if (current_frame_flags_ != 0) { | 994 } else if (current_frame_flags_ != 0) { |
| 976 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 995 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 977 } | 996 } |
| 978 break; | 997 break; |
| 979 case PUSH_PROMISE: | 998 case PUSH_PROMISE: |
| 980 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 999 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
| 981 set_error(SPDY_INVALID_CONTROL_FRAME); | 1000 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 982 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { | 1001 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { |
| 983 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 1002 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| (...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1725 flags = id_and_flags.flags(); | 1744 flags = id_and_flags.flags(); |
| 1726 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); | 1745 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); |
| 1727 } else { | 1746 } else { |
| 1728 id_field = ntohs(*(reinterpret_cast<const uint16*>(data))); | 1747 id_field = ntohs(*(reinterpret_cast<const uint16*>(data))); |
| 1729 value = ntohl(*(reinterpret_cast<const uint32*>(data + 2))); | 1748 value = ntohl(*(reinterpret_cast<const uint32*>(data + 2))); |
| 1730 } | 1749 } |
| 1731 | 1750 |
| 1732 // Validate id. | 1751 // Validate id. |
| 1733 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { | 1752 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { |
| 1734 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; | 1753 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; |
| 1735 return false; | 1754 if (protocol_version() <= SPDY3) { |
| 1755 return false; |
| 1756 } else { |
| 1757 // In HTTP2 we ignore unknown settings for extensibility. |
| 1758 return true; |
| 1759 } |
| 1736 } | 1760 } |
| 1737 id = SpdyConstants::ParseSettingId(protocol_version(), id_field); | 1761 id = SpdyConstants::ParseSettingId(protocol_version(), id_field); |
| 1738 | 1762 |
| 1739 if (protocol_version() <= SPDY3) { | 1763 if (protocol_version() <= SPDY3) { |
| 1740 // Detect duplicates. | 1764 // Detect duplicates. |
| 1741 if (id <= settings_scratch_.last_setting_id) { | 1765 if (id <= settings_scratch_.last_setting_id) { |
| 1742 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id | 1766 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id |
| 1743 << " in " << display_protocol_ << " SETTINGS frame " | 1767 << " in " << display_protocol_ << " SETTINGS frame " |
| 1744 << "(last setting id was " | 1768 << "(last setting id was " |
| 1745 << settings_scratch_.last_setting_id << ")."; | 1769 << settings_scratch_.last_setting_id << ")."; |
| (...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3220 builder->Seek(compressed_size); | 3244 builder->Seek(compressed_size); |
| 3221 builder->RewriteLength(*this); | 3245 builder->RewriteLength(*this); |
| 3222 | 3246 |
| 3223 pre_compress_bytes.Add(uncompressed_len); | 3247 pre_compress_bytes.Add(uncompressed_len); |
| 3224 post_compress_bytes.Add(compressed_size); | 3248 post_compress_bytes.Add(compressed_size); |
| 3225 | 3249 |
| 3226 compressed_frames.Increment(); | 3250 compressed_frames.Increment(); |
| 3227 } | 3251 } |
| 3228 | 3252 |
| 3229 } // namespace net | 3253 } // namespace net |
| OLD | NEW |