summaryrefslogtreecommitdiffstats
path: root/net/quic/quic_config.cc
blob: 70e0b45097082cbb2f1f70f227d05be733f75f87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// 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 {
  DCHECK(error_details != NULL);

  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) {
    *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";
    return QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP;
  }

  uint32 idle;
  error = msg.GetUint32(kICSL, &idle);
  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;
  }

  return QUIC_NO_ERROR;
}

}  // namespace net