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

Side by Side Diff: net/quic/quic_config.cc

Issue 15074007: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix for windows 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/quic_config.h ('k') | net/quic/quic_config_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) 2013 The Chromium Authors. All rights reserved. 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 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/quic_config.h" 5 #include "net/quic/quic_config.h"
6 6
7 #include <algorithm>
8
9 #include "base/logging.h"
10
7 using std::string; 11 using std::string;
8 12
9 namespace net { 13 namespace net {
10 14
11 QuicNegotiatedParameters::QuicNegotiatedParameters() 15 QuicNegotiableValue::QuicNegotiableValue(QuicTag tag, Presence presence)
12 : idle_connection_state_lifetime(QuicTime::Delta::Zero()), 16 : tag_(tag),
13 keepalive_timeout(QuicTime::Delta::Zero()) { 17 presence_(presence),
14 } 18 negotiated_(false) {
15 19 }
16 QuicConfig::QuicConfig() 20
17 : idle_connection_state_lifetime_(QuicTime::Delta::Zero()), 21 QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag, Presence presence)
18 keepalive_timeout_(QuicTime::Delta::Zero()) { 22 : QuicNegotiableValue(tag, presence) {
19 } 23 }
20 24
21 QuicConfig::~QuicConfig() { 25 void QuicNegotiableUint32::set(uint32 max, uint32 default_value) {
22 } 26 DCHECK_LE(default_value, max);
23 27 max_value_ = max;
24 void QuicConfig::SetDefaults() { 28 default_value_ = default_value;
25 idle_connection_state_lifetime_ = QuicTime::Delta::FromSeconds(300); 29 }
26 keepalive_timeout_ = QuicTime::Delta::Zero(); 30
27 congestion_control_.clear(); 31 uint32 QuicNegotiableUint32::GetUint32() const {
28 congestion_control_.push_back(kQBIC); 32 if (negotiated_) {
29 } 33 return negotiated_value_;
30 34 }
31 bool QuicConfig::SetFromHandshakeMessage(const CryptoHandshakeMessage& scfg) { 35 return default_value_;
32 const QuicTag* cgst; 36 }
33 size_t num_cgst; 37
34 QuicErrorCode error; 38 void QuicNegotiableUint32::ToHandshakeMessage(
35 39 CryptoHandshakeMessage* out) const {
36 error = scfg.GetTaglist(kCGST, &cgst, &num_cgst); 40 if (negotiated_) {
37 if (error != QUIC_NO_ERROR) { 41 out->SetValue(tag_, negotiated_value_);
38 return false; 42 } else {
39 } 43 out->SetValue(tag_, max_value_);
40 44 }
41 congestion_control_.assign(cgst, cgst + num_cgst); 45 }
42 46
43 uint32 idle; 47 QuicErrorCode QuicNegotiableUint32::ReadUint32(
44 error = scfg.GetUint32(kICSL, &idle);
45 if (error != QUIC_NO_ERROR) {
46 return false;
47 }
48 idle_connection_state_lifetime_ = QuicTime::Delta::FromSeconds(idle);
49
50 keepalive_timeout_ = QuicTime::Delta::Zero();
51
52 uint32 keepalive;
53 error = scfg.GetUint32(kKATO, &keepalive);
54 // KATO is optional.
55 if (error == QUIC_NO_ERROR) {
56 keepalive_timeout_ = QuicTime::Delta::FromSeconds(keepalive);
57 }
58
59 return true;
60 }
61
62 void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
63 out->SetValue(
64 kICSL, static_cast<uint32>(idle_connection_state_lifetime_.ToSeconds()));
65 out->SetValue(kKATO, static_cast<uint32>(keepalive_timeout_.ToSeconds()));
66 out->SetVector(kCGST, congestion_control_);
67 }
68
69 QuicErrorCode QuicConfig::ProcessFinalPeerHandshake(
70 const CryptoHandshakeMessage& msg, 48 const CryptoHandshakeMessage& msg,
71 CryptoUtils::Priority priority, 49 uint32* out,
72 QuicNegotiatedParameters* out_params,
73 string* error_details) const { 50 string* error_details) const {
74 DCHECK(error_details != NULL); 51 DCHECK(error_details != NULL);
75 52 QuicErrorCode error = msg.GetUint32(tag_, out);
76 const QuicTag* their_congestion_controls;
77 size_t num_their_congestion_controls;
78 QuicErrorCode error;
79
80 error = msg.GetTaglist(kCGST, &their_congestion_controls,
81 &num_their_congestion_controls);
82 if (error != QUIC_NO_ERROR) {
83 *error_details = "Missing CGST";
84 return error;
85 }
86
87 if (!CryptoUtils::FindMutualTag(congestion_control_,
88 their_congestion_controls,
89 num_their_congestion_controls,
90 priority,
91 &out_params->congestion_control,
92 NULL)) {
93 *error_details = "Unsuported CGST";
94 return QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP;
95 }
96
97 uint32 idle;
98 error = msg.GetUint32(kICSL, &idle);
99 if (error != QUIC_NO_ERROR) {
100 *error_details = "Missing ICSL";
101 return error;
102 }
103
104 out_params->idle_connection_state_lifetime = QuicTime::Delta::FromSeconds(
105 std::min(static_cast<uint32>(idle_connection_state_lifetime_.ToSeconds()),
106 idle));
107
108 uint32 keepalive;
109 error = msg.GetUint32(kKATO, &keepalive);
110 switch (error) { 53 switch (error) {
54 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
55 if (presence_ == QuicNegotiableValue::PRESENCE_REQUIRED) {
56 *error_details = "Missing " + QuicUtils::TagToString(tag_);
57 break;
58 }
59 error = QUIC_NO_ERROR;
60 *out = default_value_;
61
111 case QUIC_NO_ERROR: 62 case QUIC_NO_ERROR:
112 out_params->keepalive_timeout = QuicTime::Delta::FromSeconds(
113 std::min(static_cast<uint32>(keepalive_timeout_.ToSeconds()),
114 keepalive));
115 break;
116 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
117 // KATO is optional.
118 out_params->keepalive_timeout = QuicTime::Delta::Zero();
119 break; 63 break;
120 default: 64 default:
121 *error_details = "Bad KATO"; 65 *error_details = "Bad " + QuicUtils::TagToString(tag_);
122 return error; 66 break;
123 } 67 }
68 return error;
69 }
70
71 QuicErrorCode QuicNegotiableUint32::ProcessClientHello(
72 const CryptoHandshakeMessage& client_hello,
73 string* error_details) {
74 DCHECK(!negotiated_);
75 DCHECK(error_details != NULL);
76 uint32 value;
77 QuicErrorCode error = ReadUint32(client_hello, &value, error_details);
78 if (error != QUIC_NO_ERROR) {
79 return error;
80 }
81
82 negotiated_ = true;
83 negotiated_value_ = std::min(value, max_value_);
124 84
125 return QUIC_NO_ERROR; 85 return QUIC_NO_ERROR;
126 } 86 }
127 87
88 QuicErrorCode QuicNegotiableUint32::ProcessServerHello(
89 const CryptoHandshakeMessage& server_hello,
90 string* error_details) {
91 DCHECK(!negotiated_);
92 DCHECK(error_details != NULL);
93 uint32 value;
94 QuicErrorCode error = ReadUint32(server_hello, &value, error_details);
95 if (error != QUIC_NO_ERROR) {
96 return error;
97 }
98
99 if (value > max_value_) {
100 *error_details = "Invalid value received for " +
101 QuicUtils::TagToString(tag_);
102 return QUIC_INVALID_NEGOTIATED_VALUE;
103 }
104
105 negotiated_ = true;
106 negotiated_value_ = value;
107 return QUIC_NO_ERROR;
108 }
109
110 QuicNegotiableTag::QuicNegotiableTag(QuicTag tag, Presence presence)
111 : QuicNegotiableValue(tag, presence) {
112 }
113
114 QuicNegotiableTag::~QuicNegotiableTag() {}
115
116 void QuicNegotiableTag::set(const QuicTagVector& possible,
117 QuicTag default_value) {
118 DCHECK(std::find(possible.begin(), possible.end(), default_value) !=
119 possible.end());
120 possible_values_ = possible;
121 default_value_ = default_value;
122 }
123
124 QuicTag QuicNegotiableTag::GetTag() const {
125 if (negotiated_) {
126 return negotiated_tag_;
127 }
128 return default_value_;
129 }
130
131 void QuicNegotiableTag::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
132 if (negotiated_) {
133 // Because of the way we serialize and parse handshake messages we can
134 // serialize this as value and still parse it as a vector.
135 out->SetValue(tag_, negotiated_tag_);
136 } else {
137 out->SetVector(tag_, possible_values_);
138 }
139 }
140
141 QuicErrorCode QuicNegotiableTag::ReadVector(
142 const CryptoHandshakeMessage& msg,
143 const QuicTag** out,
144 size_t* out_length,
145 string* error_details) const {
146 DCHECK(error_details != NULL);
147 QuicErrorCode error = msg.GetTaglist(tag_, out, out_length);
148 switch (error) {
149 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
150 if (presence_ == PRESENCE_REQUIRED) {
151 *error_details = "Missing " + QuicUtils::TagToString(tag_);
152 break;
153 }
154 error = QUIC_NO_ERROR;
155 *out_length = 1;
156 *out = &default_value_;
157
158 case QUIC_NO_ERROR:
159 break;
160 default:
161 *error_details = "Bad " + QuicUtils::TagToString(tag_);
162 break;
163 }
164 return error;
165 }
166
167 QuicErrorCode QuicNegotiableTag::ProcessClientHello(
168 const CryptoHandshakeMessage& client_hello,
169 string* error_details) {
170 DCHECK(!negotiated_);
171 DCHECK(error_details != NULL);
172 const QuicTag* received_tags;
173 size_t received_tags_length;
174 QuicErrorCode error = ReadVector(client_hello, &received_tags,
175 &received_tags_length, error_details);
176 if (error != QUIC_NO_ERROR) {
177 return error;
178 }
179
180 QuicTag negotiated_tag;
181 if (!QuicUtils::FindMutualTag(possible_values_,
182 received_tags,
183 received_tags_length,
184 QuicUtils::LOCAL_PRIORITY,
185 &negotiated_tag,
186 NULL)) {
187 *error_details = "Unsuported " + QuicUtils::TagToString(tag_);
188 return QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP;
189 }
190
191 negotiated_ = true;
192 negotiated_tag_ = negotiated_tag;
193 return QUIC_NO_ERROR;
194 }
195
196 QuicErrorCode QuicNegotiableTag::ProcessServerHello(
197 const CryptoHandshakeMessage& server_hello,
198 string* error_details) {
199 DCHECK(!negotiated_);
200 DCHECK(error_details != NULL);
201 const QuicTag* received_tags;
202 size_t received_tags_length;
203 QuicErrorCode error = ReadVector(server_hello, &received_tags,
204 &received_tags_length, error_details);
205 if (error != QUIC_NO_ERROR) {
206 return error;
207 }
208
209 if (received_tags_length != 1 ||
210 std::find(possible_values_.begin(), possible_values_.end(),
211 *received_tags) == possible_values_.end()) {
212 *error_details = "Invalid " + QuicUtils::TagToString(tag_);
213 return QUIC_INVALID_NEGOTIATED_VALUE;
214 }
215
216 negotiated_ = true;
217 negotiated_tag_ = *received_tags;
218 return QUIC_NO_ERROR;
219 }
220
221 QuicConfig::QuicConfig() :
222 congestion_control_(kCGST, QuicNegotiableValue::PRESENCE_REQUIRED),
223 idle_connection_state_lifetime_seconds_(
224 kICSL, QuicNegotiableValue::PRESENCE_REQUIRED),
225 keepalive_timeout_seconds_(kKATO, QuicNegotiableValue::PRESENCE_OPTIONAL),
226 max_streams_per_connection_(kMSPC, QuicNegotiableValue::PRESENCE_REQUIRED) {
227 idle_connection_state_lifetime_seconds_.set(0, 0);
228 keepalive_timeout_seconds_.set(0, 0);
229 }
230
231 QuicConfig::~QuicConfig() {}
232
233 void QuicConfig::set_congestion_control(
234 const QuicTagVector& congestion_control,
235 QuicTag default_congestion_control) {
236 congestion_control_.set(congestion_control, default_congestion_control);
237 }
238
239 QuicTag QuicConfig::congestion_control() const {
240 return congestion_control_.GetTag();
241 }
242
243 void QuicConfig::set_idle_connection_state_lifetime(
244 QuicTime::Delta max_idle_connection_state_lifetime,
245 QuicTime::Delta default_idle_conection_state_lifetime) {
246 idle_connection_state_lifetime_seconds_.set(
247 max_idle_connection_state_lifetime.ToSeconds(),
248 default_idle_conection_state_lifetime.ToSeconds());
249 }
250
251 QuicTime::Delta QuicConfig::idle_connection_state_lifetime() const {
252 return QuicTime::Delta::FromSeconds(
253 idle_connection_state_lifetime_seconds_.GetUint32());
254 }
255
256 QuicTime::Delta QuicConfig::keepalive_timeout() const {
257 return QuicTime::Delta::FromSeconds(
258 keepalive_timeout_seconds_.GetUint32());
259 }
260
261 void QuicConfig::set_max_streams_per_connection(size_t max_streams,
262 size_t default_streams) {
263 max_streams_per_connection_.set(max_streams, default_streams);
264 }
265
266 uint32 QuicConfig::max_streams_per_connection() const {
267 return max_streams_per_connection_.GetUint32();
268 }
269
270 bool QuicConfig::negotiated() {
271 return congestion_control_.negotiated() &&
272 idle_connection_state_lifetime_seconds_.negotiated() &&
273 keepalive_timeout_seconds_.negotiated() &&
274 max_streams_per_connection_.negotiated();
275 }
276
277 void QuicConfig::SetDefaults() {
278 congestion_control_.set(QuicTagVector(1, kQBIC), kQBIC);
279 idle_connection_state_lifetime_seconds_.set(kDefaultTimeoutSecs,
280 kDefaultTimeoutSecs);
281 // kKATO is optional. Return 0 if not negotiated.
282 keepalive_timeout_seconds_.set(0, 0);
283 max_streams_per_connection_.set(kDefaultMaxStreamsPerConnection,
284 kDefaultMaxStreamsPerConnection);
285 }
286
287 void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
288 congestion_control_.ToHandshakeMessage(out);
289 idle_connection_state_lifetime_seconds_.ToHandshakeMessage(out);
290 keepalive_timeout_seconds_.ToHandshakeMessage(out);
291 max_streams_per_connection_.ToHandshakeMessage(out);
292 }
293
294 QuicErrorCode QuicConfig::ProcessClientHello(
295 const CryptoHandshakeMessage& client_hello,
296 string* error_details) {
297 DCHECK(error_details != NULL);
298
299 QuicErrorCode error = QUIC_NO_ERROR;
300 if (error == QUIC_NO_ERROR) {
301 error = congestion_control_.ProcessClientHello(client_hello, error_details);
302 }
303 if (error == QUIC_NO_ERROR) {
304 error = idle_connection_state_lifetime_seconds_.ProcessClientHello(
305 client_hello, error_details);
306 }
307 if (error == QUIC_NO_ERROR) {
308 error = keepalive_timeout_seconds_.ProcessClientHello(
309 client_hello, error_details);
310 }
311 if (error == QUIC_NO_ERROR) {
312 error = max_streams_per_connection_.ProcessClientHello(
313 client_hello, error_details);
314 }
315 return error;
316 }
317
318 QuicErrorCode QuicConfig::ProcessServerHello(
319 const CryptoHandshakeMessage& server_hello,
320 string* error_details) {
321 DCHECK(error_details != NULL);
322
323 QuicErrorCode error = QUIC_NO_ERROR;
324 if (error == QUIC_NO_ERROR) {
325 error = congestion_control_.ProcessServerHello(server_hello, error_details);
326 }
327 if (error == QUIC_NO_ERROR) {
328 error = idle_connection_state_lifetime_seconds_.ProcessServerHello(
329 server_hello, error_details);
330 }
331 if (error == QUIC_NO_ERROR) {
332 error = keepalive_timeout_seconds_.ProcessServerHello(
333 server_hello, error_details);
334 }
335 if (error == QUIC_NO_ERROR) {
336 error = max_streams_per_connection_.ProcessServerHello(
337 server_hello, error_details);
338 }
339 return error;
340 }
341
128 } // namespace net 342 } // namespace net
129 343
OLDNEW
« no previous file with comments | « net/quic/quic_config.h ('k') | net/quic/quic_config_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698