OLD | NEW |
---|---|
(Empty) | |
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 #include "net/quic/crypto/crypto_framer.h" | |
6 | |
7 #include "net/quic/quic_data_reader.h" | |
8 #include "net/quic/quic_data_writer.h" | |
9 #include "net/quic/quic_protocol.h" | |
10 | |
11 using base::StringPiece; | |
12 | |
13 namespace net { | |
14 | |
15 CryptoFramer::CryptoFramer() | |
16 : visitor_(NULL) { | |
17 Clear(); | |
18 } | |
19 | |
20 CryptoFramer::~CryptoFramer() {} | |
21 | |
22 bool CryptoFramer::ProcessInput(StringPiece input) { | |
23 DCHECK_EQ(QUIC_NO_ERROR, error_); | |
24 if (error_ != QUIC_NO_ERROR) { | |
25 return false; | |
26 } | |
jar (doing other things)
2012/10/14 23:04:38
I can live with (and think the network stack may h
Ryan Hamilton
2012/10/15 21:22:08
This is required Server-side style. We have the s
| |
27 // Add this data to the buffer. | |
28 buffer_.append(input.data(), input.length()); | |
29 reader_.reset(new QuicDataReader(buffer_.data(), buffer_.length())); | |
30 | |
31 switch (state_) { | |
32 case STATE_READING_TAG: | |
33 if (reader_->BytesRemaining() < sizeof(uint32)) { | |
jar (doing other things)
2012/10/14 23:04:38
nit: better would be sizeof(message_tag_)
Ryan Hamilton
2012/10/15 21:22:08
As per my C++ readability review, these sizeofs wi
| |
34 break; | |
jar (doing other things)
2012/10/14 23:04:38
Should this check for BytesRemaining == 0, and ret
Ryan Hamilton
2012/10/15 21:22:08
I don't understand what this check would be doing?
| |
35 } | |
36 reader_->ReadUInt32(&message_tag_); | |
37 state_ = STATE_READING_NUM_ENTRIES; | |
38 case STATE_READING_NUM_ENTRIES: | |
39 if (reader_->BytesRemaining() < sizeof(uint16)) { | |
jar (doing other things)
2012/10/14 23:04:38
nit: sizeof(num_entries_)
| |
40 break; | |
41 } | |
42 reader_->ReadUInt16(&num_entries_); | |
43 if (num_entries_ > kMaxEntries) { | |
44 error_ = QUIC_CRYPTO_TOO_MANY_ENTRIES; | |
45 return false; | |
46 } | |
47 state_ = STATE_READING_KEY_TAGS; | |
48 case STATE_READING_KEY_TAGS: | |
49 if (reader_->BytesRemaining() < num_entries_ * sizeof(uint32)) { | |
50 break; | |
51 } | |
52 for (int i = 0; i < num_entries_; ++i) { | |
53 CryptoTag tag; | |
54 reader_->ReadUInt32(&tag); | |
55 if (i > 0 && tag <= tags_.back()) { | |
56 error_ = QUIC_CRYPTO_TAGS_OUT_OF_ORDER; | |
57 return false; | |
58 } | |
59 tags_.push_back(tag); | |
60 } | |
61 state_ = STATE_READING_LENGTHS; | |
62 case STATE_READING_LENGTHS: | |
63 if (reader_->BytesRemaining() < num_entries_ * sizeof(uint16)) { | |
jar (doing other things)
2012/10/14 23:04:38
nit: it is always suggested that we use sizeof(var
| |
64 break; | |
65 } | |
66 values_len_ = 0; | |
67 for (int i = 0; i < num_entries_; ++i) { | |
68 uint16 len; | |
69 reader_->ReadUInt16(&len); | |
70 tag_length_map_[tags_[i]] = len; | |
71 values_len_ += len; | |
72 if (len == 0 && i != num_entries_ - 1) { | |
73 error_ = QUIC_CRYPTO_INVALID_VALUE_LENGTH; | |
74 return false; | |
75 } | |
76 } | |
77 state_ = STATE_READING_VALUES; | |
78 case STATE_READING_VALUES: | |
79 if (reader_->BytesRemaining() < values_len_) { | |
80 break; | |
81 } | |
82 for (int i = 0; i < num_entries_; ++i) { | |
83 StringPiece value; | |
84 reader_->ReadStringPiece(&value, tag_length_map_[tags_[i]]); | |
85 tag_value_map_[tags_[i]] = value; | |
jar (doing other things)
2012/10/14 23:04:38
Since StringPiece has a length, why do we want to
Ryan Hamilton
2012/10/15 21:22:08
I'm not sure the best way to make use of that. (
| |
86 } | |
87 CryptoHandshakeMessage message; | |
88 message.tag = message_tag_; | |
89 message.tag_value_map.swap(tag_value_map_); | |
90 visitor_->OnHandshakeMessage(message); | |
91 Clear(); | |
92 state_ = STATE_READING_TAG; | |
93 break; | |
94 } | |
95 // Save any left over data | |
96 buffer_ = reader_->PeekRemainingPayload().as_string(); | |
jar (doing other things)
2012/10/14 23:04:38
Is it valuable to preserve the reader_ here? It a
Ryan Hamilton
2012/10/15 21:22:08
Changed to a local variable.
| |
97 return true; | |
98 } | |
99 | |
100 bool CryptoFramer::ConstructHandshakeMessage( | |
101 const CryptoHandshakeMessage& message, | |
102 QuicData** packet) { | |
103 size_t len = sizeof(uint32); // message tag | |
jar (doing other things)
2012/10/14 23:04:38
nit: Comments are sentences with Capital letters s
| |
104 len += sizeof(uint16); // number of map entries | |
jar (doing other things)
2012/10/14 23:04:38
nit: declare/init as close to use as possible. Mo
Ryan Hamilton
2012/10/15 21:22:08
Done.
| |
105 if (message.tag_value_map.size() > kMaxEntries) { | |
106 return false; | |
107 } | |
108 CryptoTagValueMap::const_iterator it = message.tag_value_map.begin(); | |
109 while (it != message.tag_value_map.end()) { | |
110 len += sizeof(uint32); // tag | |
111 len += sizeof(uint16); // value len | |
jar (doing other things)
2012/10/14 23:04:38
nit: how about using members, rather than types in
| |
112 len += it->second.length(); // value | |
113 if (it->second.length() == 0) { | |
114 return false; | |
115 } | |
116 ++it; | |
117 } | |
118 if (message.tag_value_map.size() % 2 == 1) { | |
119 len += sizeof(uint16); // padding | |
120 } | |
121 | |
122 QuicDataWriter writer(len); | |
123 CHECK(writer.WriteUInt32(message.tag)); | |
124 CHECK(writer.WriteUInt16(message.tag_value_map.size())); | |
125 // Tags | |
126 for (it = message.tag_value_map.begin(); | |
127 it != message.tag_value_map.end(); ++it) { | |
128 CHECK(writer.WriteUInt32(it->first)); | |
129 } | |
130 // Lengths | |
131 for (it = message.tag_value_map.begin(); | |
132 it != message.tag_value_map.end(); ++it) { | |
133 CHECK(writer.WriteUInt16(it->second.length())); | |
134 } | |
135 // Possible padding | |
136 if (message.tag_value_map.size() % 2 == 1) { | |
137 CHECK(writer.WriteUInt16(0xABAB)); | |
138 } | |
139 // Values | |
140 for (it = message.tag_value_map.begin(); | |
141 it != message.tag_value_map.end(); ++it) { | |
142 CHECK(writer.WriteBytes(it->second.data(), it->second.length())); | |
143 } | |
144 *packet = new QuicData(writer.take(), len, true); | |
145 return true; | |
146 } | |
147 | |
148 void CryptoFramer::Clear() { | |
149 tag_value_map_.clear(); | |
150 tag_length_map_.clear(); | |
151 tags_.clear(); | |
152 error_ = QUIC_NO_ERROR; | |
153 state_ = STATE_READING_TAG; | |
jar (doing other things)
2012/10/14 23:04:38
Why is reader_ not discarded here? ...but perhaps
| |
154 } | |
155 | |
156 } // namespace net | |
OLD | NEW |