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/quic/crypto/crypto_framer.h" | 5 #include "net/quic/crypto/crypto_framer.h" |
6 | 6 |
7 #include "net/quic/crypto/crypto_protocol.h" | 7 #include "net/quic/crypto/crypto_protocol.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 |
(...skipping 26 matching lines...) Expand all Loading... |
37 | 37 |
38 CryptoHandshakeMessage* release() { return out_.release(); } | 38 CryptoHandshakeMessage* release() { return out_.release(); } |
39 | 39 |
40 private: | 40 private: |
41 scoped_ptr<CryptoHandshakeMessage> out_; | 41 scoped_ptr<CryptoHandshakeMessage> out_; |
42 bool error_; | 42 bool error_; |
43 }; | 43 }; |
44 | 44 |
45 } // namespace | 45 } // namespace |
46 | 46 |
47 CryptoFramer::CryptoFramer() | 47 CryptoFramer::CryptoFramer() : visitor_(NULL), num_entries_(0), values_len_(0) { |
48 : visitor_(NULL), | |
49 num_entries_(0), | |
50 values_len_(0) { | |
51 Clear(); | 48 Clear(); |
52 } | 49 } |
53 | 50 |
54 CryptoFramer::~CryptoFramer() {} | 51 CryptoFramer::~CryptoFramer() { |
| 52 } |
55 | 53 |
56 // static | 54 // static |
57 CryptoHandshakeMessage* CryptoFramer::ParseMessage(StringPiece in) { | 55 CryptoHandshakeMessage* CryptoFramer::ParseMessage(StringPiece in) { |
58 OneShotVisitor visitor; | 56 OneShotVisitor visitor; |
59 CryptoFramer framer; | 57 CryptoFramer framer; |
60 | 58 |
61 framer.set_visitor(&visitor); | 59 framer.set_visitor(&visitor); |
62 if (!framer.ProcessInput(in) || visitor.error() || | 60 if (!framer.ProcessInput(in) || visitor.error() || |
63 framer.InputBytesRemaining()) { | 61 framer.InputBytesRemaining()) { |
64 return NULL; | 62 return NULL; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 if (delta > overhead) { | 98 if (delta > overhead) { |
101 pad_length = delta - overhead; | 99 pad_length = delta - overhead; |
102 } | 100 } |
103 len += overhead + pad_length; | 101 len += overhead + pad_length; |
104 } | 102 } |
105 | 103 |
106 if (num_entries > kMaxEntries) { | 104 if (num_entries > kMaxEntries) { |
107 return NULL; | 105 return NULL; |
108 } | 106 } |
109 | 107 |
110 | |
111 QuicDataWriter writer(len); | 108 QuicDataWriter writer(len); |
112 if (!writer.WriteUInt32(message.tag())) { | 109 if (!writer.WriteUInt32(message.tag())) { |
113 DCHECK(false) << "Failed to write message tag."; | 110 DCHECK(false) << "Failed to write message tag."; |
114 return NULL; | 111 return NULL; |
115 } | 112 } |
116 if (!writer.WriteUInt16(num_entries)) { | 113 if (!writer.WriteUInt16(num_entries)) { |
117 DCHECK(false) << "Failed to write size."; | 114 DCHECK(false) << "Failed to write size."; |
118 return NULL; | 115 return NULL; |
119 } | 116 } |
120 if (!writer.WriteUInt16(0)) { | 117 if (!writer.WriteUInt16(0)) { |
121 DCHECK(false) << "Failed to write padding."; | 118 DCHECK(false) << "Failed to write padding."; |
122 return NULL; | 119 return NULL; |
123 } | 120 } |
124 | 121 |
125 uint32 end_offset = 0; | 122 uint32 end_offset = 0; |
126 // Tags and offsets | 123 // Tags and offsets |
127 for (QuicTagValueMap::const_iterator it = message.tag_value_map().begin(); | 124 for (QuicTagValueMap::const_iterator it = message.tag_value_map().begin(); |
128 it != message.tag_value_map().end(); ++it) { | 125 it != message.tag_value_map().end(); |
| 126 ++it) { |
129 if (it->first == kPAD && need_pad_tag) { | 127 if (it->first == kPAD && need_pad_tag) { |
130 // Existing PAD tags are only checked when padding needs to be added | 128 // Existing PAD tags are only checked when padding needs to be added |
131 // because parts of the code may need to reserialize received messages | 129 // because parts of the code may need to reserialize received messages |
132 // and those messages may, legitimately include padding. | 130 // and those messages may, legitimately include padding. |
133 DCHECK(false) << "Message needed padding but already contained a PAD tag"; | 131 DCHECK(false) << "Message needed padding but already contained a PAD tag"; |
134 return NULL; | 132 return NULL; |
135 } | 133 } |
136 | 134 |
137 if (it->first > kPAD && need_pad_tag) { | 135 if (it->first > kPAD && need_pad_tag) { |
138 need_pad_tag = false; | 136 need_pad_tag = false; |
(...skipping 14 matching lines...) Expand all Loading... |
153 } | 151 } |
154 | 152 |
155 if (need_pad_tag) { | 153 if (need_pad_tag) { |
156 if (!WritePadTag(&writer, pad_length, &end_offset)) { | 154 if (!WritePadTag(&writer, pad_length, &end_offset)) { |
157 return NULL; | 155 return NULL; |
158 } | 156 } |
159 } | 157 } |
160 | 158 |
161 // Values | 159 // Values |
162 for (QuicTagValueMap::const_iterator it = message.tag_value_map().begin(); | 160 for (QuicTagValueMap::const_iterator it = message.tag_value_map().begin(); |
163 it != message.tag_value_map().end(); ++it) { | 161 it != message.tag_value_map().end(); |
| 162 ++it) { |
164 if (it->first > kPAD && need_pad_value) { | 163 if (it->first > kPAD && need_pad_value) { |
165 need_pad_value = false; | 164 need_pad_value = false; |
166 if (!writer.WriteRepeatedByte('-', pad_length)) { | 165 if (!writer.WriteRepeatedByte('-', pad_length)) { |
167 DCHECK(false) << "Failed to write padding."; | 166 DCHECK(false) << "Failed to write padding."; |
168 return NULL; | 167 return NULL; |
169 } | 168 } |
170 } | 169 } |
171 | 170 |
172 if (!writer.WriteBytes(it->second.data(), it->second.length())) { | 171 if (!writer.WriteBytes(it->second.data(), it->second.length())) { |
173 DCHECK(false) << "Failed to write value."; | 172 DCHECK(false) << "Failed to write value."; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 return QUIC_CRYPTO_TOO_MANY_ENTRIES; | 214 return QUIC_CRYPTO_TOO_MANY_ENTRIES; |
216 } | 215 } |
217 uint16 padding; | 216 uint16 padding; |
218 reader.ReadUInt16(&padding); | 217 reader.ReadUInt16(&padding); |
219 | 218 |
220 tags_and_lengths_.reserve(num_entries_); | 219 tags_and_lengths_.reserve(num_entries_); |
221 state_ = STATE_READING_TAGS_AND_LENGTHS; | 220 state_ = STATE_READING_TAGS_AND_LENGTHS; |
222 values_len_ = 0; | 221 values_len_ = 0; |
223 case STATE_READING_TAGS_AND_LENGTHS: { | 222 case STATE_READING_TAGS_AND_LENGTHS: { |
224 if (reader.BytesRemaining() < | 223 if (reader.BytesRemaining() < |
225 num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) { | 224 num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) { |
226 break; | 225 break; |
227 } | 226 } |
228 | 227 |
229 uint32 last_end_offset = 0; | 228 uint32 last_end_offset = 0; |
230 for (unsigned i = 0; i < num_entries_; ++i) { | 229 for (unsigned i = 0; i < num_entries_; ++i) { |
231 QuicTag tag; | 230 QuicTag tag; |
232 reader.ReadUInt32(&tag); | 231 reader.ReadUInt32(&tag); |
233 if (i > 0 && tag <= tags_and_lengths_[i-1].first) { | 232 if (i > 0 && tag <= tags_and_lengths_[i - 1].first) { |
234 if (tag == tags_and_lengths_[i-1].first) { | 233 if (tag == tags_and_lengths_[i - 1].first) { |
235 return QUIC_CRYPTO_DUPLICATE_TAG; | 234 return QUIC_CRYPTO_DUPLICATE_TAG; |
236 } | 235 } |
237 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; | 236 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; |
238 } | 237 } |
239 | 238 |
240 uint32 end_offset; | 239 uint32 end_offset; |
241 reader.ReadUInt32(&end_offset); | 240 reader.ReadUInt32(&end_offset); |
242 | 241 |
243 if (end_offset < last_end_offset) { | 242 if (end_offset < last_end_offset) { |
244 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; | 243 return QUIC_CRYPTO_TAGS_OUT_OF_ORDER; |
245 } | 244 } |
246 tags_and_lengths_.push_back( | 245 tags_and_lengths_.push_back( |
247 make_pair(tag, static_cast<size_t>(end_offset - last_end_offset))); | 246 make_pair(tag, static_cast<size_t>(end_offset - last_end_offset))); |
248 last_end_offset = end_offset; | 247 last_end_offset = end_offset; |
249 } | 248 } |
250 values_len_ = last_end_offset; | 249 values_len_ = last_end_offset; |
251 state_ = STATE_READING_VALUES; | 250 state_ = STATE_READING_VALUES; |
252 } | 251 } |
253 case STATE_READING_VALUES: | 252 case STATE_READING_VALUES: |
254 if (reader.BytesRemaining() < values_len_) { | 253 if (reader.BytesRemaining() < values_len_) { |
255 break; | 254 break; |
256 } | 255 } |
257 for (vector<pair<QuicTag, size_t> >::const_iterator | 256 for (vector<pair<QuicTag, size_t> >::const_iterator it = |
258 it = tags_and_lengths_.begin(); it != tags_and_lengths_.end(); | 257 tags_and_lengths_.begin(); |
| 258 it != tags_and_lengths_.end(); |
259 it++) { | 259 it++) { |
260 StringPiece value; | 260 StringPiece value; |
261 reader.ReadStringPiece(&value, it->second); | 261 reader.ReadStringPiece(&value, it->second); |
262 message_.SetStringPiece(it->first, value); | 262 message_.SetStringPiece(it->first, value); |
263 } | 263 } |
264 visitor_->OnHandshakeMessage(message_); | 264 visitor_->OnHandshakeMessage(message_); |
265 Clear(); | 265 Clear(); |
266 state_ = STATE_READING_TAG; | 266 state_ = STATE_READING_TAG; |
267 break; | 267 break; |
268 } | 268 } |
(...skipping 12 matching lines...) Expand all Loading... |
281 } | 281 } |
282 *end_offset += pad_length; | 282 *end_offset += pad_length; |
283 if (!writer->WriteUInt32(*end_offset)) { | 283 if (!writer->WriteUInt32(*end_offset)) { |
284 DCHECK(false) << "Failed to write end offset."; | 284 DCHECK(false) << "Failed to write end offset."; |
285 return false; | 285 return false; |
286 } | 286 } |
287 return true; | 287 return true; |
288 } | 288 } |
289 | 289 |
290 } // namespace net | 290 } // namespace net |
OLD | NEW |