blob: f16f06fde96d9942dda0a3dfa3c220479a7cd2ac [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/quic/quic_config.h"
using std::string;
namespace net {
QuicNegotiatedParameters::QuicNegotiatedParameters()
: idle_connection_state_lifetime(QuicTime::Delta::Zero()),
keepalive_timeout(QuicTime::Delta::Zero()) {
}
QuicConfig::QuicConfig()
: idle_connection_state_lifetime_(QuicTime::Delta::Zero()),
keepalive_timeout_(QuicTime::Delta::Zero()) {
}
QuicConfig::~QuicConfig() {
}
void QuicConfig::SetDefaults() {
idle_connection_state_lifetime_ = QuicTime::Delta::FromSeconds(300);
keepalive_timeout_ = QuicTime::Delta::Zero();
congestion_control_.clear();
congestion_control_.push_back(kQBIC);
}
bool QuicConfig::SetFromHandshakeMessage(const CryptoHandshakeMessage& scfg) {
const CryptoTag* cgst;
size_t num_cgst;
QuicErrorCode error;
error = scfg.GetTaglist(kCGST, &cgst, &num_cgst);
if (error != QUIC_NO_ERROR) {
return false;
}
congestion_control_.assign(cgst, cgst + num_cgst);
uint32 idle;
error = scfg.GetUint32(kICSL, &idle);
if (error != QUIC_NO_ERROR) {
return false;
}
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);
}
return true;
}
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_);
}
QuicErrorCode QuicConfig::ProcessFinalPeerHandshake(
const CryptoHandshakeMessage& msg,
CryptoUtils::Priority priority,
QuicNegotiatedParameters* out_params,
string* error_details) const {
const CryptoTag* their_congestion_controls;
size_t num_their_congestion_controls;
QuicErrorCode error;
error = msg.GetTaglist(kCGST, &their_congestion_controls,
&num_their_congestion_controls);
if (error != QUIC_NO_ERROR) {
if (error_details) {
*error_details = "Missing CGST";
}
return error;
}
if (!CryptoUtils::FindMutualTag(congestion_control_,
their_congestion_controls,
num_their_congestion_controls,
priority,
&out_params->congestion_control,
NULL)) {
if (error_details) {
*error_details = "Unsuported CGST";
}
return QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP;
}
uint32 idle;
error = msg.GetUint32(kICSL, &idle);
if (error != QUIC_NO_ERROR) {
if (error_details) {
*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:
if (error_details) {
*error_details = "Bad KATO";
}
return error;
}
return QUIC_NO_ERROR;
}
} // namespace net