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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/quic_config.h ('k') | net/quic/quic_config_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_config.cc
diff --git a/net/quic/quic_config.cc b/net/quic/quic_config.cc
index 867cb6d2acf6763d03d974b7e4f61f917ad3e383..eacde842e27e2826d6c4ad89896ce0063674ffd3 100644
--- a/net/quic/quic_config.cc
+++ b/net/quic/quic_config.cc
@@ -4,126 +4,340 @@
#include "net/quic/quic_config.h"
+#include <algorithm>
+
+#include "base/logging.h"
+
using std::string;
namespace net {
-QuicNegotiatedParameters::QuicNegotiatedParameters()
- : idle_connection_state_lifetime(QuicTime::Delta::Zero()),
- keepalive_timeout(QuicTime::Delta::Zero()) {
+QuicNegotiableValue::QuicNegotiableValue(QuicTag tag, Presence presence)
+ : tag_(tag),
+ presence_(presence),
+ negotiated_(false) {
}
-QuicConfig::QuicConfig()
- : idle_connection_state_lifetime_(QuicTime::Delta::Zero()),
- keepalive_timeout_(QuicTime::Delta::Zero()) {
+QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag, Presence presence)
+ : QuicNegotiableValue(tag, presence) {
}
-QuicConfig::~QuicConfig() {
+void QuicNegotiableUint32::set(uint32 max, uint32 default_value) {
+ DCHECK_LE(default_value, max);
+ max_value_ = max;
+ default_value_ = default_value;
}
-void QuicConfig::SetDefaults() {
- idle_connection_state_lifetime_ = QuicTime::Delta::FromSeconds(300);
- keepalive_timeout_ = QuicTime::Delta::Zero();
- congestion_control_.clear();
- congestion_control_.push_back(kQBIC);
+uint32 QuicNegotiableUint32::GetUint32() const {
+ if (negotiated_) {
+ return negotiated_value_;
+ }
+ return default_value_;
+}
+
+void QuicNegotiableUint32::ToHandshakeMessage(
+ CryptoHandshakeMessage* out) const {
+ if (negotiated_) {
+ out->SetValue(tag_, negotiated_value_);
+ } else {
+ out->SetValue(tag_, max_value_);
+ }
}
-bool QuicConfig::SetFromHandshakeMessage(const CryptoHandshakeMessage& scfg) {
- const QuicTag* cgst;
- size_t num_cgst;
- QuicErrorCode error;
+QuicErrorCode QuicNegotiableUint32::ReadUint32(
+ const CryptoHandshakeMessage& msg,
+ uint32* out,
+ string* error_details) const {
+ DCHECK(error_details != NULL);
+ QuicErrorCode error = msg.GetUint32(tag_, out);
+ switch (error) {
+ case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+ if (presence_ == QuicNegotiableValue::PRESENCE_REQUIRED) {
+ *error_details = "Missing " + QuicUtils::TagToString(tag_);
+ break;
+ }
+ error = QUIC_NO_ERROR;
+ *out = default_value_;
- error = scfg.GetTaglist(kCGST, &cgst, &num_cgst);
+ case QUIC_NO_ERROR:
+ break;
+ default:
+ *error_details = "Bad " + QuicUtils::TagToString(tag_);
+ break;
+ }
+ return error;
+}
+
+QuicErrorCode QuicNegotiableUint32::ProcessClientHello(
+ const CryptoHandshakeMessage& client_hello,
+ string* error_details) {
+ DCHECK(!negotiated_);
+ DCHECK(error_details != NULL);
+ uint32 value;
+ QuicErrorCode error = ReadUint32(client_hello, &value, error_details);
if (error != QUIC_NO_ERROR) {
- return false;
+ return error;
}
- congestion_control_.assign(cgst, cgst + num_cgst);
+ negotiated_ = true;
+ negotiated_value_ = std::min(value, max_value_);
- uint32 idle;
- error = scfg.GetUint32(kICSL, &idle);
+ return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicNegotiableUint32::ProcessServerHello(
+ const CryptoHandshakeMessage& server_hello,
+ string* error_details) {
+ DCHECK(!negotiated_);
+ DCHECK(error_details != NULL);
+ uint32 value;
+ QuicErrorCode error = ReadUint32(server_hello, &value, error_details);
if (error != QUIC_NO_ERROR) {
- return false;
+ return error;
}
- idle_connection_state_lifetime_ = QuicTime::Delta::FromSeconds(idle);
-
- keepalive_timeout_ = QuicTime::Delta::Zero();
- uint32 keepalive;
- error = scfg.GetUint32(kKATO, &keepalive);
- // KATO is optional.
- if (error == QUIC_NO_ERROR) {
- keepalive_timeout_ = QuicTime::Delta::FromSeconds(keepalive);
+ if (value > max_value_) {
+ *error_details = "Invalid value received for " +
+ QuicUtils::TagToString(tag_);
+ return QUIC_INVALID_NEGOTIATED_VALUE;
}
- return true;
+ negotiated_ = true;
+ negotiated_value_ = value;
+ return QUIC_NO_ERROR;
}
-void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
- out->SetValue(
- kICSL, static_cast<uint32>(idle_connection_state_lifetime_.ToSeconds()));
- out->SetValue(kKATO, static_cast<uint32>(keepalive_timeout_.ToSeconds()));
- out->SetVector(kCGST, congestion_control_);
+QuicNegotiableTag::QuicNegotiableTag(QuicTag tag, Presence presence)
+ : QuicNegotiableValue(tag, presence) {
+}
+
+QuicNegotiableTag::~QuicNegotiableTag() {}
+
+void QuicNegotiableTag::set(const QuicTagVector& possible,
+ QuicTag default_value) {
+ DCHECK(std::find(possible.begin(), possible.end(), default_value) !=
+ possible.end());
+ possible_values_ = possible;
+ default_value_ = default_value;
+}
+
+QuicTag QuicNegotiableTag::GetTag() const {
+ if (negotiated_) {
+ return negotiated_tag_;
+ }
+ return default_value_;
}
-QuicErrorCode QuicConfig::ProcessFinalPeerHandshake(
+void QuicNegotiableTag::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
+ if (negotiated_) {
+ // Because of the way we serialize and parse handshake messages we can
+ // serialize this as value and still parse it as a vector.
+ out->SetValue(tag_, negotiated_tag_);
+ } else {
+ out->SetVector(tag_, possible_values_);
+ }
+}
+
+QuicErrorCode QuicNegotiableTag::ReadVector(
const CryptoHandshakeMessage& msg,
- CryptoUtils::Priority priority,
- QuicNegotiatedParameters* out_params,
+ const QuicTag** out,
+ size_t* out_length,
string* error_details) const {
DCHECK(error_details != NULL);
+ QuicErrorCode error = msg.GetTaglist(tag_, out, out_length);
+ switch (error) {
+ case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+ if (presence_ == PRESENCE_REQUIRED) {
+ *error_details = "Missing " + QuicUtils::TagToString(tag_);
+ break;
+ }
+ error = QUIC_NO_ERROR;
+ *out_length = 1;
+ *out = &default_value_;
- const QuicTag* their_congestion_controls;
- size_t num_their_congestion_controls;
- QuicErrorCode error;
+ case QUIC_NO_ERROR:
+ break;
+ default:
+ *error_details = "Bad " + QuicUtils::TagToString(tag_);
+ break;
+ }
+ return error;
+}
- error = msg.GetTaglist(kCGST, &their_congestion_controls,
- &num_their_congestion_controls);
+QuicErrorCode QuicNegotiableTag::ProcessClientHello(
+ const CryptoHandshakeMessage& client_hello,
+ string* error_details) {
+ DCHECK(!negotiated_);
+ DCHECK(error_details != NULL);
+ const QuicTag* received_tags;
+ size_t received_tags_length;
+ QuicErrorCode error = ReadVector(client_hello, &received_tags,
+ &received_tags_length, error_details);
if (error != QUIC_NO_ERROR) {
- *error_details = "Missing CGST";
return error;
}
- if (!CryptoUtils::FindMutualTag(congestion_control_,
- their_congestion_controls,
- num_their_congestion_controls,
- priority,
- &out_params->congestion_control,
- NULL)) {
- *error_details = "Unsuported CGST";
+ QuicTag negotiated_tag;
+ if (!QuicUtils::FindMutualTag(possible_values_,
+ received_tags,
+ received_tags_length,
+ QuicUtils::LOCAL_PRIORITY,
+ &negotiated_tag,
+ NULL)) {
+ *error_details = "Unsuported " + QuicUtils::TagToString(tag_);
return QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP;
}
- uint32 idle;
- error = msg.GetUint32(kICSL, &idle);
+ negotiated_ = true;
+ negotiated_tag_ = negotiated_tag;
+ return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicNegotiableTag::ProcessServerHello(
+ const CryptoHandshakeMessage& server_hello,
+ string* error_details) {
+ DCHECK(!negotiated_);
+ DCHECK(error_details != NULL);
+ const QuicTag* received_tags;
+ size_t received_tags_length;
+ QuicErrorCode error = ReadVector(server_hello, &received_tags,
+ &received_tags_length, error_details);
if (error != QUIC_NO_ERROR) {
- *error_details = "Missing ICSL";
return error;
}
- out_params->idle_connection_state_lifetime = QuicTime::Delta::FromSeconds(
- std::min(static_cast<uint32>(idle_connection_state_lifetime_.ToSeconds()),
- idle));
-
- uint32 keepalive;
- error = msg.GetUint32(kKATO, &keepalive);
- switch (error) {
- case QUIC_NO_ERROR:
- out_params->keepalive_timeout = QuicTime::Delta::FromSeconds(
- std::min(static_cast<uint32>(keepalive_timeout_.ToSeconds()),
- keepalive));
- break;
- case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
- // KATO is optional.
- out_params->keepalive_timeout = QuicTime::Delta::Zero();
- break;
- default:
- *error_details = "Bad KATO";
- return error;
+ if (received_tags_length != 1 ||
+ std::find(possible_values_.begin(), possible_values_.end(),
+ *received_tags) == possible_values_.end()) {
+ *error_details = "Invalid " + QuicUtils::TagToString(tag_);
+ return QUIC_INVALID_NEGOTIATED_VALUE;
}
+ negotiated_ = true;
+ negotiated_tag_ = *received_tags;
return QUIC_NO_ERROR;
}
+QuicConfig::QuicConfig() :
+ congestion_control_(kCGST, QuicNegotiableValue::PRESENCE_REQUIRED),
+ idle_connection_state_lifetime_seconds_(
+ kICSL, QuicNegotiableValue::PRESENCE_REQUIRED),
+ keepalive_timeout_seconds_(kKATO, QuicNegotiableValue::PRESENCE_OPTIONAL),
+ max_streams_per_connection_(kMSPC, QuicNegotiableValue::PRESENCE_REQUIRED) {
+ idle_connection_state_lifetime_seconds_.set(0, 0);
+ keepalive_timeout_seconds_.set(0, 0);
+}
+
+QuicConfig::~QuicConfig() {}
+
+void QuicConfig::set_congestion_control(
+ const QuicTagVector& congestion_control,
+ QuicTag default_congestion_control) {
+ congestion_control_.set(congestion_control, default_congestion_control);
+}
+
+QuicTag QuicConfig::congestion_control() const {
+ return congestion_control_.GetTag();
+}
+
+void QuicConfig::set_idle_connection_state_lifetime(
+ QuicTime::Delta max_idle_connection_state_lifetime,
+ QuicTime::Delta default_idle_conection_state_lifetime) {
+ idle_connection_state_lifetime_seconds_.set(
+ max_idle_connection_state_lifetime.ToSeconds(),
+ default_idle_conection_state_lifetime.ToSeconds());
+}
+
+QuicTime::Delta QuicConfig::idle_connection_state_lifetime() const {
+ return QuicTime::Delta::FromSeconds(
+ idle_connection_state_lifetime_seconds_.GetUint32());
+}
+
+QuicTime::Delta QuicConfig::keepalive_timeout() const {
+ return QuicTime::Delta::FromSeconds(
+ keepalive_timeout_seconds_.GetUint32());
+}
+
+void QuicConfig::set_max_streams_per_connection(size_t max_streams,
+ size_t default_streams) {
+ max_streams_per_connection_.set(max_streams, default_streams);
+}
+
+uint32 QuicConfig::max_streams_per_connection() const {
+ return max_streams_per_connection_.GetUint32();
+}
+
+bool QuicConfig::negotiated() {
+ return congestion_control_.negotiated() &&
+ idle_connection_state_lifetime_seconds_.negotiated() &&
+ keepalive_timeout_seconds_.negotiated() &&
+ max_streams_per_connection_.negotiated();
+}
+
+void QuicConfig::SetDefaults() {
+ congestion_control_.set(QuicTagVector(1, kQBIC), kQBIC);
+ idle_connection_state_lifetime_seconds_.set(kDefaultTimeoutSecs,
+ kDefaultTimeoutSecs);
+ // kKATO is optional. Return 0 if not negotiated.
+ keepalive_timeout_seconds_.set(0, 0);
+ max_streams_per_connection_.set(kDefaultMaxStreamsPerConnection,
+ kDefaultMaxStreamsPerConnection);
+}
+
+void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
+ congestion_control_.ToHandshakeMessage(out);
+ idle_connection_state_lifetime_seconds_.ToHandshakeMessage(out);
+ keepalive_timeout_seconds_.ToHandshakeMessage(out);
+ max_streams_per_connection_.ToHandshakeMessage(out);
+}
+
+QuicErrorCode QuicConfig::ProcessClientHello(
+ const CryptoHandshakeMessage& client_hello,
+ string* error_details) {
+ DCHECK(error_details != NULL);
+
+ QuicErrorCode error = QUIC_NO_ERROR;
+ if (error == QUIC_NO_ERROR) {
+ error = congestion_control_.ProcessClientHello(client_hello, error_details);
+ }
+ if (error == QUIC_NO_ERROR) {
+ error = idle_connection_state_lifetime_seconds_.ProcessClientHello(
+ client_hello, error_details);
+ }
+ if (error == QUIC_NO_ERROR) {
+ error = keepalive_timeout_seconds_.ProcessClientHello(
+ client_hello, error_details);
+ }
+ if (error == QUIC_NO_ERROR) {
+ error = max_streams_per_connection_.ProcessClientHello(
+ client_hello, error_details);
+ }
+ return error;
+}
+
+QuicErrorCode QuicConfig::ProcessServerHello(
+ const CryptoHandshakeMessage& server_hello,
+ string* error_details) {
+ DCHECK(error_details != NULL);
+
+ QuicErrorCode error = QUIC_NO_ERROR;
+ if (error == QUIC_NO_ERROR) {
+ error = congestion_control_.ProcessServerHello(server_hello, error_details);
+ }
+ if (error == QUIC_NO_ERROR) {
+ error = idle_connection_state_lifetime_seconds_.ProcessServerHello(
+ server_hello, error_details);
+ }
+ if (error == QUIC_NO_ERROR) {
+ error = keepalive_timeout_seconds_.ProcessServerHello(
+ server_hello, error_details);
+ }
+ if (error == QUIC_NO_ERROR) {
+ error = max_streams_per_connection_.ProcessServerHello(
+ server_hello, error_details);
+ }
+ return error;
+}
+
} // namespace net
« 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