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

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

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 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
OLDNEW
(Empty)
1 // Copyright (c) 2013 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_handshake_message.h"
6
7 #include <memory>
8
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/stringprintf.h"
11 #include "net/quic/crypto/crypto_framer.h"
12 #include "net/quic/crypto/crypto_protocol.h"
13 #include "net/quic/crypto/crypto_utils.h"
14 #include "net/quic/quic_socket_address_coder.h"
15 #include "net/quic/quic_utils.h"
16
17 using base::StringPiece;
18 using base::StringPrintf;
19 using std::string;
20 using std::vector;
21
22 namespace net {
23
24 CryptoHandshakeMessage::CryptoHandshakeMessage() : tag_(0), minimum_size_(0) {}
25
26 CryptoHandshakeMessage::CryptoHandshakeMessage(
27 const CryptoHandshakeMessage& other)
28 : tag_(other.tag_),
29 tag_value_map_(other.tag_value_map_),
30 minimum_size_(other.minimum_size_) {
31 // Don't copy serialized_. unique_ptr doesn't have a copy constructor.
32 // The new object can lazily reconstruct serialized_.
33 }
34
35 CryptoHandshakeMessage::CryptoHandshakeMessage(CryptoHandshakeMessage&& other) =
36 default;
37
38 CryptoHandshakeMessage::~CryptoHandshakeMessage() {}
39
40 CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
41 const CryptoHandshakeMessage& other) {
42 tag_ = other.tag_;
43 tag_value_map_ = other.tag_value_map_;
44 // Don't copy serialized_. unique_ptr doesn't have an assignment operator.
45 // However, invalidate serialized_.
46 serialized_.reset();
47 minimum_size_ = other.minimum_size_;
48 return *this;
49 }
50
51 CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
52 CryptoHandshakeMessage&& other) = default;
53
54 void CryptoHandshakeMessage::Clear() {
55 tag_ = 0;
56 tag_value_map_.clear();
57 minimum_size_ = 0;
58 serialized_.reset();
59 }
60
61 const QuicData& CryptoHandshakeMessage::GetSerialized() const {
62 if (!serialized_.get()) {
63 serialized_.reset(CryptoFramer::ConstructHandshakeMessage(*this));
64 }
65 return *serialized_;
66 }
67
68 void CryptoHandshakeMessage::MarkDirty() {
69 serialized_.reset();
70 }
71
72 void CryptoHandshakeMessage::SetStringPiece(QuicTag tag, StringPiece value) {
73 tag_value_map_[tag] = value.as_string();
74 }
75
76 void CryptoHandshakeMessage::Erase(QuicTag tag) {
77 tag_value_map_.erase(tag);
78 }
79
80 QuicErrorCode CryptoHandshakeMessage::GetTaglist(QuicTag tag,
81 const QuicTag** out_tags,
82 size_t* out_len) const {
83 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
84 QuicErrorCode ret = QUIC_NO_ERROR;
85
86 if (it == tag_value_map_.end()) {
87 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
88 } else if (it->second.size() % sizeof(QuicTag) != 0) {
89 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
90 }
91
92 if (ret != QUIC_NO_ERROR) {
93 *out_tags = nullptr;
94 *out_len = 0;
95 return ret;
96 }
97
98 *out_tags = reinterpret_cast<const QuicTag*>(it->second.data());
99 *out_len = it->second.size() / sizeof(QuicTag);
100 return ret;
101 }
102
103 bool CryptoHandshakeMessage::GetStringPiece(QuicTag tag,
104 StringPiece* out) const {
105 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
106 if (it == tag_value_map_.end()) {
107 return false;
108 }
109 *out = it->second;
110 return true;
111 }
112
113 QuicErrorCode CryptoHandshakeMessage::GetNthValue24(QuicTag tag,
114 unsigned index,
115 StringPiece* out) const {
116 StringPiece value;
117 if (!GetStringPiece(tag, &value)) {
118 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
119 }
120
121 for (unsigned i = 0;; i++) {
122 if (value.empty()) {
123 return QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND;
124 }
125 if (value.size() < 3) {
126 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
127 }
128
129 const unsigned char* data =
130 reinterpret_cast<const unsigned char*>(value.data());
131 size_t size = static_cast<size_t>(data[0]) |
132 (static_cast<size_t>(data[1]) << 8) |
133 (static_cast<size_t>(data[2]) << 16);
134 value.remove_prefix(3);
135
136 if (value.size() < size) {
137 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
138 }
139
140 if (i == index) {
141 *out = StringPiece(value.data(), size);
142 return QUIC_NO_ERROR;
143 }
144
145 value.remove_prefix(size);
146 }
147 }
148
149 QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag,
150 uint32_t* out) const {
151 return GetPOD(tag, out, sizeof(uint32_t));
152 }
153
154 QuicErrorCode CryptoHandshakeMessage::GetUint64(QuicTag tag,
155 uint64_t* out) const {
156 return GetPOD(tag, out, sizeof(uint64_t));
157 }
158
159 size_t CryptoHandshakeMessage::size() const {
160 size_t ret = sizeof(QuicTag) + sizeof(uint16_t) /* number of entries */ +
161 sizeof(uint16_t) /* padding */;
162 ret += (sizeof(QuicTag) + sizeof(uint32_t) /* end offset */) *
163 tag_value_map_.size();
164 for (QuicTagValueMap::const_iterator i = tag_value_map_.begin();
165 i != tag_value_map_.end(); ++i) {
166 ret += i->second.size();
167 }
168
169 return ret;
170 }
171
172 void CryptoHandshakeMessage::set_minimum_size(size_t min_bytes) {
173 if (min_bytes == minimum_size_) {
174 return;
175 }
176 serialized_.reset();
177 minimum_size_ = min_bytes;
178 }
179
180 size_t CryptoHandshakeMessage::minimum_size() const {
181 return minimum_size_;
182 }
183
184 string CryptoHandshakeMessage::DebugString() const {
185 return DebugStringInternal(0);
186 }
187
188 QuicErrorCode CryptoHandshakeMessage::GetPOD(QuicTag tag,
189 void* out,
190 size_t len) const {
191 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
192 QuicErrorCode ret = QUIC_NO_ERROR;
193
194 if (it == tag_value_map_.end()) {
195 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
196 } else if (it->second.size() != len) {
197 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
198 }
199
200 if (ret != QUIC_NO_ERROR) {
201 memset(out, 0, len);
202 return ret;
203 }
204
205 memcpy(out, it->second.data(), len);
206 return ret;
207 }
208
209 string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const {
210 string ret = string(2 * indent, ' ') + QuicUtils::TagToString(tag_) + "<\n";
211 ++indent;
212 for (QuicTagValueMap::const_iterator it = tag_value_map_.begin();
213 it != tag_value_map_.end(); ++it) {
214 ret += string(2 * indent, ' ') + QuicUtils::TagToString(it->first) + ": ";
215
216 bool done = false;
217 switch (it->first) {
218 case kICSL:
219 case kCFCW:
220 case kSFCW:
221 case kIRTT:
222 case kMSPC:
223 case kSRBF:
224 case kSWND:
225 // uint32_t value
226 if (it->second.size() == 4) {
227 uint32_t value;
228 memcpy(&value, it->second.data(), sizeof(value));
229 ret += base::UintToString(value);
230 done = true;
231 }
232 break;
233 case kRCID:
234 // uint64_t value
235 if (it->second.size() == 8) {
236 uint64_t value;
237 memcpy(&value, it->second.data(), sizeof(value));
238 ret += base::Uint64ToString(value);
239 done = true;
240 }
241 break;
242 case kTBKP:
243 case kKEXS:
244 case kAEAD:
245 case kCOPT:
246 case kPDMD:
247 case kVER:
248 // tag lists
249 if (it->second.size() % sizeof(QuicTag) == 0) {
250 for (size_t j = 0; j < it->second.size(); j += sizeof(QuicTag)) {
251 QuicTag tag;
252 memcpy(&tag, it->second.data() + j, sizeof(tag));
253 if (j > 0) {
254 ret += ",";
255 }
256 ret += "'" + QuicUtils::TagToString(tag) + "'";
257 }
258 done = true;
259 }
260 break;
261 case kRREJ:
262 // uint32_t lists
263 if (it->second.size() % sizeof(uint32_t) == 0) {
264 for (size_t j = 0; j < it->second.size(); j += sizeof(uint32_t)) {
265 uint32_t value;
266 memcpy(&value, it->second.data() + j, sizeof(value));
267 if (j > 0) {
268 ret += ",";
269 }
270 ret += CryptoUtils::HandshakeFailureReasonToString(
271 static_cast<HandshakeFailureReason>(value));
272 }
273 done = true;
274 }
275 break;
276 case kCADR:
277 // IP address and port
278 if (!it->second.empty()) {
279 QuicSocketAddressCoder decoder;
280 if (decoder.Decode(it->second.data(), it->second.size())) {
281 ret += IPAddressToStringWithPort(decoder.ip(), decoder.port());
282 done = true;
283 }
284 }
285 break;
286 case kSCFG:
287 // nested messages.
288 if (!it->second.empty()) {
289 std::unique_ptr<CryptoHandshakeMessage> msg(
290 CryptoFramer::ParseMessage(it->second));
291 if (msg.get()) {
292 ret += "\n";
293 ret += msg->DebugStringInternal(indent + 1);
294
295 done = true;
296 }
297 }
298 break;
299 case kPAD:
300 ret += StringPrintf("(%d bytes of padding)",
301 static_cast<int>(it->second.size()));
302 done = true;
303 break;
304 case kSNI:
305 case kUAID:
306 ret += "\"" + it->second + "\"";
307 done = true;
308 break;
309 }
310
311 if (!done) {
312 // If there's no specific format for this tag, or the value is invalid,
313 // then just use hex.
314 ret += "0x" + QuicUtils::HexEncode(it->second);
315 }
316 ret += "\n";
317 }
318 --indent;
319 ret += string(2 * indent, ' ') + ">";
320 return ret;
321 }
322
323 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/crypto_handshake_message.h ('k') | net/quic/crypto/crypto_handshake_message_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698