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/quic_data_reader.h" | 7 #include "net/quic/quic_data_reader.h" |
8 #include "net/quic/quic_data_writer.h" | 8 #include "net/quic/quic_data_writer.h" |
9 #include "net/quic/quic_protocol.h" | 9 #include "net/quic/quic_protocol.h" |
10 | 10 |
11 using base::StringPiece; | 11 using base::StringPiece; |
12 | 12 |
13 namespace net { | 13 namespace net { |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 const size_t kCryptoTagSize = sizeof(uint32); | 17 const size_t kCryptoTagSize = sizeof(uint32); |
18 const size_t kNumEntriesSize = sizeof(uint16); | 18 const size_t kNumEntriesSize = sizeof(uint16); |
19 const size_t kValueLenSize = sizeof(uint16); | 19 const size_t kValueLenSize = sizeof(uint16); |
20 | 20 |
| 21 // OneShotVisitor is a framer visitor that records a single handshake message. |
| 22 class OneShotVisitor : public CryptoFramerVisitorInterface { |
| 23 public: |
| 24 explicit OneShotVisitor(CryptoHandshakeMessage* out) |
| 25 : out_(out), |
| 26 error_(false) { |
| 27 } |
| 28 |
| 29 void OnError(CryptoFramer* framer) { |
| 30 error_ = true; |
| 31 } |
| 32 |
| 33 void OnHandshakeMessage(const CryptoHandshakeMessage& message) { |
| 34 *out_ = message; |
| 35 } |
| 36 |
| 37 bool error() const { |
| 38 return error_; |
| 39 } |
| 40 |
| 41 private: |
| 42 CryptoHandshakeMessage* const out_; |
| 43 bool error_; |
| 44 }; |
| 45 |
21 } // namespace | 46 } // namespace |
22 | 47 |
23 CryptoFramer::CryptoFramer() | 48 CryptoFramer::CryptoFramer() |
24 : visitor_(NULL), | 49 : visitor_(NULL), |
25 message_tag_(0), | 50 message_tag_(0), |
26 num_entries_(0), | 51 num_entries_(0), |
27 values_len_(0) { | 52 values_len_(0) { |
28 Clear(); | 53 Clear(); |
29 } | 54 } |
30 | 55 |
31 CryptoFramer::~CryptoFramer() {} | 56 CryptoFramer::~CryptoFramer() {} |
32 | 57 |
| 58 // static |
| 59 CryptoHandshakeMessage* CryptoFramer::ParseMessage(StringPiece in) { |
| 60 scoped_ptr<CryptoHandshakeMessage> msg(new CryptoHandshakeMessage); |
| 61 OneShotVisitor visitor(msg.get()); |
| 62 CryptoFramer framer; |
| 63 |
| 64 framer.set_visitor(&visitor); |
| 65 if (!framer.ProcessInput(in) || |
| 66 visitor.error() || |
| 67 framer.InputBytesRemaining()) { |
| 68 return NULL; |
| 69 } |
| 70 |
| 71 return msg.release(); |
| 72 } |
| 73 |
33 bool CryptoFramer::ProcessInput(StringPiece input) { | 74 bool CryptoFramer::ProcessInput(StringPiece input) { |
34 DCHECK_EQ(QUIC_NO_ERROR, error_); | 75 DCHECK_EQ(QUIC_NO_ERROR, error_); |
35 if (error_ != QUIC_NO_ERROR) { | 76 if (error_ != QUIC_NO_ERROR) { |
36 return false; | 77 return false; |
37 } | 78 } |
38 // Add this data to the buffer. | 79 // Add this data to the buffer. |
39 buffer_.append(input.data(), input.length()); | 80 buffer_.append(input.data(), input.length()); |
40 QuicDataReader reader(buffer_.data(), buffer_.length()); | 81 QuicDataReader reader(buffer_.data(), buffer_.length()); |
41 | 82 |
42 switch (state_) { | 83 switch (state_) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 visitor_->OnHandshakeMessage(message); | 153 visitor_->OnHandshakeMessage(message); |
113 Clear(); | 154 Clear(); |
114 state_ = STATE_READING_TAG; | 155 state_ = STATE_READING_TAG; |
115 break; | 156 break; |
116 } | 157 } |
117 // Save any remaining data. | 158 // Save any remaining data. |
118 buffer_ = reader.PeekRemainingPayload().as_string(); | 159 buffer_ = reader.PeekRemainingPayload().as_string(); |
119 return true; | 160 return true; |
120 } | 161 } |
121 | 162 |
| 163 // static |
122 QuicData* CryptoFramer::ConstructHandshakeMessage( | 164 QuicData* CryptoFramer::ConstructHandshakeMessage( |
123 const CryptoHandshakeMessage& message) { | 165 const CryptoHandshakeMessage& message) { |
124 if (message.tag_value_map.size() > kMaxEntries) { | 166 if (message.tag_value_map.size() > kMaxEntries) { |
125 return NULL; | 167 return NULL; |
126 } | 168 } |
127 size_t len = sizeof(uint32); // message tag | 169 size_t len = sizeof(uint32); // message tag |
128 len += sizeof(uint16); // number of map entries | 170 len += sizeof(uint16); // number of map entries |
129 CryptoTagValueMap::const_iterator it = message.tag_value_map.begin(); | 171 CryptoTagValueMap::const_iterator it = message.tag_value_map.begin(); |
130 while (it != message.tag_value_map.end()) { | 172 while (it != message.tag_value_map.end()) { |
131 len += sizeof(uint32); // tag | 173 len += sizeof(uint32); // tag |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 | 224 |
183 void CryptoFramer::Clear() { | 225 void CryptoFramer::Clear() { |
184 tag_value_map_.clear(); | 226 tag_value_map_.clear(); |
185 tag_length_map_.clear(); | 227 tag_length_map_.clear(); |
186 tags_.clear(); | 228 tags_.clear(); |
187 error_ = QUIC_NO_ERROR; | 229 error_ = QUIC_NO_ERROR; |
188 state_ = STATE_READING_TAG; | 230 state_ = STATE_READING_TAG; |
189 } | 231 } |
190 | 232 |
191 } // namespace net | 233 } // namespace net |
OLD | NEW |