Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: net/quic/crypto/crypto_framer.cc

Issue 14816006: Land Recent QUIC changes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added missing NET_PRIVATE_EXPORT to QuicWallTime Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/quic/crypto/crypto_framer.h ('k') | net/quic/crypto/crypto_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/quic/crypto/crypto_framer.h" 5 #include "net/quic/crypto/crypto_framer.h"
6 6
7 #include "net/quic/crypto/crypto_handshake.h" 7 #include "net/quic/crypto/crypto_handshake.h"
8 #include "net/quic/quic_data_reader.h" 8 #include "net/quic/quic_data_reader.h"
9 #include "net/quic/quic_data_writer.h" 9 #include "net/quic/quic_data_writer.h"
10 10
11 using base::StringPiece; 11 using base::StringPiece;
12 using std::make_pair; 12 using std::make_pair;
13 using std::pair; 13 using std::pair;
14 using std::vector; 14 using std::vector;
15 15
16 namespace net { 16 namespace net {
17 17
18 namespace { 18 namespace {
19 19
20 const size_t kCryptoTagSize = sizeof(uint32); 20 const size_t kQuicTagSize = sizeof(uint32);
21 const size_t kCryptoEndOffsetSize = sizeof(uint32); 21 const size_t kCryptoEndOffsetSize = sizeof(uint32);
22 const size_t kNumEntriesSize = sizeof(uint16); 22 const size_t kNumEntriesSize = sizeof(uint16);
23 const size_t kValueLenSize = sizeof(uint16); 23 const size_t kValueLenSize = sizeof(uint16);
24 24
25 // OneShotVisitor is a framer visitor that records a single handshake message. 25 // OneShotVisitor is a framer visitor that records a single handshake message.
26 class OneShotVisitor : public CryptoFramerVisitorInterface { 26 class OneShotVisitor : public CryptoFramerVisitorInterface {
27 public: 27 public:
28 explicit OneShotVisitor(CryptoHandshakeMessage* out) 28 explicit OneShotVisitor(CryptoHandshakeMessage* out)
29 : out_(out), 29 : out_(out),
30 error_(false) { 30 error_(false) {
31 } 31 }
32 32
33 virtual void OnError(CryptoFramer* framer) OVERRIDE { 33 virtual void OnError(CryptoFramer* framer) OVERRIDE { error_ = true; }
34 error_ = true;
35 }
36 34
37 virtual void OnHandshakeMessage( 35 virtual void OnHandshakeMessage(
38 const CryptoHandshakeMessage& message) OVERRIDE { 36 const CryptoHandshakeMessage& message) OVERRIDE {
39 *out_ = message; 37 *out_ = message;
40 } 38 }
41 39
42 bool error() const { 40 bool error() const { return error_; }
43 return error_;
44 }
45 41
46 private: 42 private:
47 CryptoHandshakeMessage* const out_; 43 CryptoHandshakeMessage* const out_;
48 bool error_; 44 bool error_;
49 }; 45 };
50 46
51 } // namespace 47 } // namespace
52 48
53 CryptoFramer::CryptoFramer() 49 CryptoFramer::CryptoFramer()
54 : visitor_(NULL), 50 : visitor_(NULL),
55 num_entries_(0), 51 num_entries_(0),
56 values_len_(0) { 52 values_len_(0) {
57 Clear(); 53 Clear();
58 } 54 }
59 55
60 CryptoFramer::~CryptoFramer() {} 56 CryptoFramer::~CryptoFramer() {}
61 57
62 // static 58 // static
63 CryptoHandshakeMessage* CryptoFramer::ParseMessage(StringPiece in) { 59 CryptoHandshakeMessage* CryptoFramer::ParseMessage(StringPiece in) {
64 scoped_ptr<CryptoHandshakeMessage> msg(new CryptoHandshakeMessage); 60 scoped_ptr<CryptoHandshakeMessage> msg(new CryptoHandshakeMessage);
65 OneShotVisitor visitor(msg.get()); 61 OneShotVisitor visitor(msg.get());
66 CryptoFramer framer; 62 CryptoFramer framer;
67 63
68 framer.set_visitor(&visitor); 64 framer.set_visitor(&visitor);
69 if (!framer.ProcessInput(in) || 65 if (!framer.ProcessInput(in) || visitor.error() ||
70 visitor.error() ||
71 framer.InputBytesRemaining()) { 66 framer.InputBytesRemaining()) {
72 return NULL; 67 return NULL;
73 } 68 }
74 69
75 return msg.release(); 70 return msg.release();
76 } 71 }
77 72
78 bool CryptoFramer::ProcessInput(StringPiece input) { 73 bool CryptoFramer::ProcessInput(StringPiece input) {
79 DCHECK_EQ(QUIC_NO_ERROR, error_); 74 DCHECK_EQ(QUIC_NO_ERROR, error_);
80 if (error_ != QUIC_NO_ERROR) { 75 if (error_ != QUIC_NO_ERROR) {
81 return false; 76 return false;
82 } 77 }
83 // Add this data to the buffer. 78 // Add this data to the buffer.
84 buffer_.append(input.data(), input.length()); 79 buffer_.append(input.data(), input.length());
85 QuicDataReader reader(buffer_.data(), buffer_.length()); 80 QuicDataReader reader(buffer_.data(), buffer_.length());
86 81
87 switch (state_) { 82 switch (state_) {
88 case STATE_READING_TAG: 83 case STATE_READING_TAG:
89 if (reader.BytesRemaining() < kCryptoTagSize) { 84 if (reader.BytesRemaining() < kQuicTagSize) {
90 break; 85 break;
91 } 86 }
92 CryptoTag message_tag; 87 QuicTag message_tag;
93 reader.ReadUInt32(&message_tag); 88 reader.ReadUInt32(&message_tag);
94 message_.set_tag(message_tag); 89 message_.set_tag(message_tag);
95 state_ = STATE_READING_NUM_ENTRIES; 90 state_ = STATE_READING_NUM_ENTRIES;
96 case STATE_READING_NUM_ENTRIES: 91 case STATE_READING_NUM_ENTRIES:
97 if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16)) { 92 if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16)) {
98 break; 93 break;
99 } 94 }
100 reader.ReadUInt16(&num_entries_); 95 reader.ReadUInt16(&num_entries_);
101 if (num_entries_ > kMaxEntries) { 96 if (num_entries_ > kMaxEntries) {
102 error_ = QUIC_CRYPTO_TOO_MANY_ENTRIES; 97 error_ = QUIC_CRYPTO_TOO_MANY_ENTRIES;
103 return false; 98 return false;
104 } 99 }
105 uint16 padding; 100 uint16 padding;
106 reader.ReadUInt16(&padding); 101 reader.ReadUInt16(&padding);
107 102
108 tags_and_lengths_.reserve(num_entries_); 103 tags_and_lengths_.reserve(num_entries_);
109 state_ = STATE_READING_TAGS_AND_LENGTHS; 104 state_ = STATE_READING_TAGS_AND_LENGTHS;
110 values_len_ = 0; 105 values_len_ = 0;
111 case STATE_READING_TAGS_AND_LENGTHS: { 106 case STATE_READING_TAGS_AND_LENGTHS: {
112 if (reader.BytesRemaining() < num_entries_ * (kCryptoTagSize + 107 if (reader.BytesRemaining() <
113 kCryptoEndOffsetSize)) { 108 num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) {
114 break; 109 break;
115 } 110 }
116 111
117 uint32 last_end_offset = 0; 112 uint32 last_end_offset = 0;
118 for (unsigned i = 0; i < num_entries_; ++i) { 113 for (unsigned i = 0; i < num_entries_; ++i) {
119 CryptoTag tag; 114 QuicTag tag;
120 reader.ReadUInt32(&tag); 115 reader.ReadUInt32(&tag);
121 if (i > 0 && tag <= tags_and_lengths_[i-1].first) { 116 if (i > 0 && tag <= tags_and_lengths_[i-1].first) {
122 if (tag == tags_and_lengths_[i-1].first) { 117 if (tag == tags_and_lengths_[i-1].first) {
123 error_ = QUIC_CRYPTO_DUPLICATE_TAG; 118 error_ = QUIC_CRYPTO_DUPLICATE_TAG;
124 } else { 119 } else {
125 error_ = QUIC_CRYPTO_TAGS_OUT_OF_ORDER; 120 error_ = QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
126 } 121 }
127 return false; 122 return false;
128 } 123 }
129 124
130 uint32 end_offset; 125 uint32 end_offset;
131 reader.ReadUInt32(&end_offset); 126 reader.ReadUInt32(&end_offset);
132 127
133 if (end_offset < last_end_offset) { 128 if (end_offset < last_end_offset) {
134 error_ = QUIC_CRYPTO_TAGS_OUT_OF_ORDER; 129 error_ = QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
135 return false; 130 return false;
136 } 131 }
137 tags_and_lengths_.push_back( 132 tags_and_lengths_.push_back(
138 make_pair(tag, static_cast<size_t>(end_offset - last_end_offset))); 133 make_pair(tag, static_cast<size_t>(end_offset - last_end_offset)));
139 last_end_offset = end_offset; 134 last_end_offset = end_offset;
140 } 135 }
141 values_len_ = last_end_offset; 136 values_len_ = last_end_offset;
142 state_ = STATE_READING_VALUES; 137 state_ = STATE_READING_VALUES;
143 } 138 }
144 case STATE_READING_VALUES: 139 case STATE_READING_VALUES:
145 if (reader.BytesRemaining() < values_len_) { 140 if (reader.BytesRemaining() < values_len_) {
146 break; 141 break;
147 } 142 }
148 for (vector<pair<CryptoTag, size_t> >::const_iterator 143 for (vector<pair<QuicTag, size_t> >::const_iterator
149 it = tags_and_lengths_.begin(); it != tags_and_lengths_.end(); 144 it = tags_and_lengths_.begin(); it != tags_and_lengths_.end();
150 it++) { 145 it++) {
151 StringPiece value; 146 StringPiece value;
152 reader.ReadStringPiece(&value, it->second); 147 reader.ReadStringPiece(&value, it->second);
153 message_.SetStringPiece(it->first, value); 148 message_.SetStringPiece(it->first, value);
154 } 149 }
155 visitor_->OnHandshakeMessage(message_); 150 visitor_->OnHandshakeMessage(message_);
156 Clear(); 151 Clear();
157 state_ = STATE_READING_TAG; 152 state_ = STATE_READING_TAG;
158 break; 153 break;
159 } 154 }
160 // Save any remaining data. 155 // Save any remaining data.
161 buffer_ = reader.PeekRemainingPayload().as_string(); 156 buffer_ = reader.PeekRemainingPayload().as_string();
162 return true; 157 return true;
163 } 158 }
164 159
165 // static 160 // static
166 QuicData* CryptoFramer::ConstructHandshakeMessage( 161 QuicData* CryptoFramer::ConstructHandshakeMessage(
167 const CryptoHandshakeMessage& message) { 162 const CryptoHandshakeMessage& message) {
168 if (message.tag_value_map().size() > kMaxEntries) { 163 if (message.tag_value_map().size() > kMaxEntries) {
169 return NULL; 164 return NULL;
170 } 165 }
171 size_t len = kCryptoTagSize; // message tag 166 size_t len = kQuicTagSize; // message tag
172 len += sizeof(uint16); // number of map entries 167 len += sizeof(uint16); // number of map entries
173 len += sizeof(uint16); // padding. 168 len += sizeof(uint16); // padding.
174 CryptoTagValueMap::const_iterator it = message.tag_value_map().begin(); 169 QuicTagValueMap::const_iterator it = message.tag_value_map().begin();
175 while (it != message.tag_value_map().end()) { 170 while (it != message.tag_value_map().end()) {
176 len += kCryptoTagSize; // tag 171 len += kQuicTagSize; // tag
177 len += kCryptoEndOffsetSize; // end offset 172 len += kCryptoEndOffsetSize; // end offset
178 len += it->second.length(); // value 173 len += it->second.length(); // value
179 ++it; 174 ++it;
180 } 175 }
181 176
182 QuicDataWriter writer(len); 177 QuicDataWriter writer(len);
183 if (!writer.WriteUInt32(message.tag())) { 178 if (!writer.WriteUInt32(message.tag())) {
184 DCHECK(false) << "Failed to write message tag."; 179 DCHECK(false) << "Failed to write message tag.";
185 return NULL; 180 return NULL;
186 } 181 }
187 if (!writer.WriteUInt16(message.tag_value_map().size())) { 182 if (!writer.WriteUInt16(message.tag_value_map().size())) {
188 DCHECK(false) << "Failed to write size."; 183 DCHECK(false) << "Failed to write size.";
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 } 215 }
221 216
222 void CryptoFramer::Clear() { 217 void CryptoFramer::Clear() {
223 message_.Clear(); 218 message_.Clear();
224 tags_and_lengths_.clear(); 219 tags_and_lengths_.clear();
225 error_ = QUIC_NO_ERROR; 220 error_ = QUIC_NO_ERROR;
226 state_ = STATE_READING_TAG; 221 state_ = STATE_READING_TAG;
227 } 222 }
228 223
229 } // namespace net 224 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/crypto_framer.h ('k') | net/quic/crypto/crypto_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698