OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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/crypto/quic_crypto_server_config.h" | 5 #include "net/quic/crypto/quic_crypto_server_config.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 | 9 |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 using crypto::SecureHash; | 43 using crypto::SecureHash; |
44 using std::map; | 44 using std::map; |
45 using std::sort; | 45 using std::sort; |
46 using std::string; | 46 using std::string; |
47 using std::vector; | 47 using std::vector; |
48 | 48 |
49 namespace net { | 49 namespace net { |
50 | 50 |
51 namespace { | 51 namespace { |
52 | 52 |
| 53 const size_t kMaxTokenAddresses = 4; |
| 54 |
53 string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) { | 55 string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) { |
54 crypto::HKDF hkdf(source_address_token_secret, | 56 crypto::HKDF hkdf(source_address_token_secret, |
55 StringPiece() /* no salt */, | 57 StringPiece() /* no salt */, |
56 "QUIC source address token key", | 58 "QUIC source address token key", |
57 CryptoSecretBoxer::GetKeySize(), | 59 CryptoSecretBoxer::GetKeySize(), |
58 0 /* no fixed IV needed */, | 60 0 /* no fixed IV needed */, |
59 0 /* no subkey secret */); | 61 0 /* no subkey secret */); |
60 return hkdf.server_write_key().as_string(); | 62 return hkdf.server_write_key().as_string(); |
61 } | 63 } |
62 | 64 |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 760 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
759 } | 761 } |
760 | 762 |
761 out->set_tag(kSHLO); | 763 out->set_tag(kSHLO); |
762 QuicTagVector supported_version_tags; | 764 QuicTagVector supported_version_tags; |
763 for (size_t i = 0; i < supported_versions.size(); ++i) { | 765 for (size_t i = 0; i < supported_versions.size(); ++i) { |
764 supported_version_tags.push_back | 766 supported_version_tags.push_back |
765 (QuicVersionToQuicTag(supported_versions[i])); | 767 (QuicVersionToQuicTag(supported_versions[i])); |
766 } | 768 } |
767 out->SetVector(kVER, supported_version_tags); | 769 out->SetVector(kVER, supported_version_tags); |
768 out->SetStringPiece(kSourceAddressTokenTag, | 770 out->SetStringPiece( |
769 NewSourceAddressToken(*requested_config.get(), | 771 kSourceAddressTokenTag, |
770 client_address, | 772 NewSourceAddressToken(*requested_config.get(), info.source_address_tokens, |
771 rand, | 773 client_address, rand, info.now, nullptr)); |
772 info.now, | |
773 nullptr)); | |
774 QuicSocketAddressCoder address_coder(client_address); | 774 QuicSocketAddressCoder address_coder(client_address); |
775 out->SetStringPiece(kCADR, address_coder.Encode()); | 775 out->SetStringPiece(kCADR, address_coder.Encode()); |
776 out->SetStringPiece(kPUBS, forward_secure_public_value); | 776 out->SetStringPiece(kPUBS, forward_secure_public_value); |
777 | 777 |
778 return QUIC_NO_ERROR; | 778 return QUIC_NO_ERROR; |
779 } | 779 } |
780 | 780 |
781 scoped_refptr<QuicCryptoServerConfig::Config> | 781 scoped_refptr<QuicCryptoServerConfig::Config> |
782 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { | 782 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { |
783 // In Chromium, we will dead lock if the lock is held by the current thread. | 783 // In Chromium, we will dead lock if the lock is held by the current thread. |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE); | 933 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE); |
934 } | 934 } |
935 // No server config with the requested ID. | 935 // No server config with the requested ID. |
936 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 936 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
937 return; | 937 return; |
938 } | 938 } |
939 | 939 |
940 HandshakeFailureReason source_address_token_error; | 940 HandshakeFailureReason source_address_token_error; |
941 StringPiece srct; | 941 StringPiece srct; |
942 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { | 942 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { |
943 source_address_token_error = | 943 if (!FLAGS_quic_use_multiple_address_in_source_tokens) { |
944 ValidateSourceAddressToken(*requested_config.get(), | 944 source_address_token_error = ValidateSourceAddressToken( |
945 srct, | 945 *requested_config.get(), srct, info->client_ip, info->now, |
946 info->client_ip, | 946 &client_hello_state->cached_network_params); |
947 info->now, | 947 } else { |
948 &client_hello_state->cached_network_params); | 948 source_address_token_error = ParseSourceAddressToken( |
| 949 *requested_config.get(), srct, &info->source_address_tokens); |
| 950 |
| 951 if (source_address_token_error == HANDSHAKE_OK) { |
| 952 source_address_token_error = ValidateSourceAddressTokens( |
| 953 info->source_address_tokens, info->client_ip, info->now, |
| 954 &client_hello_state->cached_network_params); |
| 955 } |
| 956 } |
949 info->valid_source_address_token = | 957 info->valid_source_address_token = |
950 (source_address_token_error == HANDSHAKE_OK); | 958 (source_address_token_error == HANDSHAKE_OK); |
951 } else { | 959 } else { |
952 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; | 960 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; |
953 } | 961 } |
954 | 962 |
955 bool found_error = false; | 963 bool found_error = false; |
956 if (source_address_token_error != HANDSHAKE_OK) { | 964 if (source_address_token_error != HANDSHAKE_OK) { |
957 info->reject_reasons.push_back(source_address_token_error); | 965 info->reject_reasons.push_back(source_address_token_error); |
958 // No valid source address token. | 966 // No valid source address token. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 } | 1036 } |
1029 | 1037 |
1030 strike_register_client->VerifyNonceIsValidAndUnique( | 1038 strike_register_client->VerifyNonceIsValidAndUnique( |
1031 info->client_nonce, | 1039 info->client_nonce, |
1032 info->now, | 1040 info->now, |
1033 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); | 1041 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); |
1034 helper.StartedAsyncCallback(); | 1042 helper.StartedAsyncCallback(); |
1035 } | 1043 } |
1036 | 1044 |
1037 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( | 1045 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
| 1046 const SourceAddressTokens& previous_source_address_tokens, |
1038 const IPEndPoint& server_ip, | 1047 const IPEndPoint& server_ip, |
1039 const IPEndPoint& client_ip, | 1048 const IPEndPoint& client_ip, |
1040 const QuicClock* clock, | 1049 const QuicClock* clock, |
1041 QuicRandom* rand, | 1050 QuicRandom* rand, |
1042 const QuicCryptoNegotiatedParameters& params, | 1051 const QuicCryptoNegotiatedParameters& params, |
1043 const CachedNetworkParameters* cached_network_params, | 1052 const CachedNetworkParameters* cached_network_params, |
1044 CryptoHandshakeMessage* out) const { | 1053 CryptoHandshakeMessage* out) const { |
1045 base::AutoLock locked(configs_lock_); | 1054 base::AutoLock locked(configs_lock_); |
1046 out->set_tag(kSCUP); | 1055 out->set_tag(kSCUP); |
1047 out->SetStringPiece(kSCFG, primary_config_->serialized); | 1056 out->SetStringPiece(kSCFG, primary_config_->serialized); |
1048 out->SetStringPiece(kSourceAddressTokenTag, | 1057 out->SetStringPiece( |
1049 NewSourceAddressToken(*primary_config_.get(), | 1058 kSourceAddressTokenTag, |
1050 client_ip, | 1059 NewSourceAddressToken(*primary_config_.get(), |
1051 rand, | 1060 previous_source_address_tokens, client_ip, rand, |
1052 clock->WallNow(), | 1061 clock->WallNow(), cached_network_params)); |
1053 cached_network_params)); | |
1054 | 1062 |
1055 if (proof_source_ == nullptr) { | 1063 if (proof_source_ == nullptr) { |
1056 // Insecure QUIC, can send SCFG without proof. | 1064 // Insecure QUIC, can send SCFG without proof. |
1057 return true; | 1065 return true; |
1058 } | 1066 } |
1059 | 1067 |
1060 const vector<string>* certs; | 1068 const vector<string>* certs; |
1061 string signature; | 1069 string signature; |
1062 if (!proof_source_->GetProof( | 1070 if (!proof_source_->GetProof( |
1063 server_ip, params.sni, primary_config_->serialized, | 1071 server_ip, params.sni, primary_config_->serialized, |
(...skipping 15 matching lines...) Expand all Loading... |
1079 const IPEndPoint& server_ip, | 1087 const IPEndPoint& server_ip, |
1080 const Config& config, | 1088 const Config& config, |
1081 const CryptoHandshakeMessage& client_hello, | 1089 const CryptoHandshakeMessage& client_hello, |
1082 const ClientHelloInfo& info, | 1090 const ClientHelloInfo& info, |
1083 const CachedNetworkParameters& cached_network_params, | 1091 const CachedNetworkParameters& cached_network_params, |
1084 QuicRandom* rand, | 1092 QuicRandom* rand, |
1085 QuicCryptoNegotiatedParameters* params, | 1093 QuicCryptoNegotiatedParameters* params, |
1086 CryptoHandshakeMessage* out) const { | 1094 CryptoHandshakeMessage* out) const { |
1087 out->set_tag(kREJ); | 1095 out->set_tag(kREJ); |
1088 out->SetStringPiece(kSCFG, config.serialized); | 1096 out->SetStringPiece(kSCFG, config.serialized); |
1089 out->SetStringPiece(kSourceAddressTokenTag, | 1097 out->SetStringPiece( |
1090 NewSourceAddressToken( | 1098 kSourceAddressTokenTag, |
1091 config, | 1099 NewSourceAddressToken(config, info.source_address_tokens, info.client_ip, |
1092 info.client_ip, | 1100 rand, info.now, &cached_network_params)); |
1093 rand, | |
1094 info.now, | |
1095 &cached_network_params)); | |
1096 if (replay_protection_) { | 1101 if (replay_protection_) { |
1097 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); | 1102 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); |
1098 } | 1103 } |
1099 | 1104 |
1100 if (FLAGS_send_quic_crypto_reject_reason) { | 1105 if (FLAGS_send_quic_crypto_reject_reason) { |
1101 // Send client the reject reason for debugging purposes. | 1106 // Send client the reject reason for debugging purposes. |
1102 DCHECK_LT(0u, info.reject_reasons.size()); | 1107 DCHECK_LT(0u, info.reject_reasons.size()); |
1103 out->SetVector(kRREJ, info.reject_reasons); | 1108 out->SetVector(kRREJ, info.reject_reasons); |
1104 } | 1109 } |
1105 | 1110 |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1405 } | 1410 } |
1406 | 1411 |
1407 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( | 1412 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( |
1408 PrimaryConfigChangedCallback* cb) { | 1413 PrimaryConfigChangedCallback* cb) { |
1409 base::AutoLock locked(configs_lock_); | 1414 base::AutoLock locked(configs_lock_); |
1410 primary_config_changed_cb_.reset(cb); | 1415 primary_config_changed_cb_.reset(cb); |
1411 } | 1416 } |
1412 | 1417 |
1413 string QuicCryptoServerConfig::NewSourceAddressToken( | 1418 string QuicCryptoServerConfig::NewSourceAddressToken( |
1414 const Config& config, | 1419 const Config& config, |
| 1420 const SourceAddressTokens& previous_tokens, |
1415 const IPEndPoint& ip, | 1421 const IPEndPoint& ip, |
1416 QuicRandom* rand, | 1422 QuicRandom* rand, |
1417 QuicWallTime now, | 1423 QuicWallTime now, |
1418 const CachedNetworkParameters* cached_network_params) const { | 1424 const CachedNetworkParameters* cached_network_params) const { |
1419 IPAddressNumber ip_address = ip.address(); | 1425 IPAddressNumber ip_address = ip.address(); |
1420 if (ip.GetSockAddrFamily() == AF_INET) { | 1426 if (ip.GetSockAddrFamily() == AF_INET) { |
1421 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); | 1427 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); |
1422 } | 1428 } |
1423 SourceAddressToken source_address_token; | 1429 SourceAddressTokens source_address_tokens; |
1424 source_address_token.set_ip(IPAddressToPackedString(ip_address)); | 1430 SourceAddressToken* source_address_token = source_address_tokens.add_tokens(); |
1425 source_address_token.set_timestamp(now.ToUNIXSeconds()); | 1431 source_address_token->set_ip(IPAddressToPackedString(ip_address)); |
| 1432 source_address_token->set_timestamp(now.ToUNIXSeconds()); |
1426 if (cached_network_params != nullptr) { | 1433 if (cached_network_params != nullptr) { |
1427 source_address_token.set_cached_network_parameters(*cached_network_params); | 1434 *(source_address_token->mutable_cached_network_parameters()) = |
| 1435 *cached_network_params; |
| 1436 } |
| 1437 |
| 1438 if (!FLAGS_quic_use_multiple_address_in_source_tokens) { |
| 1439 return config.source_address_token_boxer->Box( |
| 1440 rand, source_address_token->SerializeAsString()); |
| 1441 } |
| 1442 |
| 1443 // Append previous tokens. |
| 1444 for (size_t i = 0; i < previous_tokens.tokens_size(); i++) { |
| 1445 const SourceAddressToken& token = previous_tokens.tokens(i); |
| 1446 if (source_address_tokens.tokens_size() > kMaxTokenAddresses) { |
| 1447 break; |
| 1448 } |
| 1449 |
| 1450 if (token.ip() == source_address_token->ip()) { |
| 1451 // It's for the same IP address. |
| 1452 continue; |
| 1453 } |
| 1454 |
| 1455 if (ValidateSourceAddressTokenTimestamp(token, now) != HANDSHAKE_OK) { |
| 1456 continue; |
| 1457 } |
| 1458 |
| 1459 *(source_address_tokens.add_tokens()) = token; |
1428 } | 1460 } |
1429 | 1461 |
1430 return config.source_address_token_boxer->Box( | 1462 return config.source_address_token_boxer->Box( |
1431 rand, source_address_token.SerializeAsString()); | 1463 rand, source_address_tokens.SerializeAsString()); |
1432 } | 1464 } |
1433 | 1465 |
1434 bool QuicCryptoServerConfig::HasProofSource() const { | 1466 bool QuicCryptoServerConfig::HasProofSource() const { |
1435 return proof_source_ != nullptr; | 1467 return proof_source_ != nullptr; |
1436 } | 1468 } |
1437 | 1469 |
| 1470 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken( |
| 1471 const Config& config, |
| 1472 StringPiece token, |
| 1473 SourceAddressTokens* tokens) const { |
| 1474 string storage; |
| 1475 StringPiece plaintext; |
| 1476 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { |
| 1477 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; |
| 1478 } |
| 1479 |
| 1480 if (!FLAGS_quic_use_multiple_address_in_source_tokens) { |
| 1481 SourceAddressToken token; |
| 1482 if (!token.ParseFromArray(plaintext.data(), plaintext.size())) { |
| 1483 return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE; |
| 1484 } |
| 1485 *(tokens->add_tokens()) = token; |
| 1486 return HANDSHAKE_OK; |
| 1487 } |
| 1488 |
| 1489 if (!tokens->ParseFromArray(plaintext.data(), plaintext.size())) { |
| 1490 // Some clients might still be using the old source token format so |
| 1491 // attempt to parse that format. |
| 1492 // TODO(rch): remove this code once the new format is ubiquitous. |
| 1493 SourceAddressToken token; |
| 1494 if (!token.ParseFromArray(plaintext.data(), plaintext.size())) { |
| 1495 return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE; |
| 1496 } |
| 1497 *tokens->add_tokens() = token; |
| 1498 } |
| 1499 |
| 1500 return HANDSHAKE_OK; |
| 1501 } |
| 1502 |
1438 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( | 1503 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( |
1439 const Config& config, | 1504 const Config& config, |
1440 StringPiece token, | 1505 StringPiece token, |
1441 const IPEndPoint& ip, | 1506 const IPEndPoint& ip, |
1442 QuicWallTime now, | 1507 QuicWallTime now, |
1443 CachedNetworkParameters* cached_network_params) const { | 1508 CachedNetworkParameters* cached_network_params) const { |
1444 string storage; | 1509 string storage; |
1445 StringPiece plaintext; | 1510 StringPiece plaintext; |
1446 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { | 1511 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { |
1447 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; | 1512 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; |
(...skipping 28 matching lines...) Expand all Loading... |
1476 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE; | 1541 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE; |
1477 } | 1542 } |
1478 | 1543 |
1479 if (source_address_token.has_cached_network_parameters()) { | 1544 if (source_address_token.has_cached_network_parameters()) { |
1480 *cached_network_params = source_address_token.cached_network_parameters(); | 1545 *cached_network_params = source_address_token.cached_network_parameters(); |
1481 } | 1546 } |
1482 | 1547 |
1483 return HANDSHAKE_OK; | 1548 return HANDSHAKE_OK; |
1484 } | 1549 } |
1485 | 1550 |
| 1551 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressTokens( |
| 1552 const SourceAddressTokens& source_address_tokens, |
| 1553 const IPEndPoint& ip, |
| 1554 QuicWallTime now, |
| 1555 CachedNetworkParameters* cached_network_params) const { |
| 1556 HandshakeFailureReason reason = |
| 1557 SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE; |
| 1558 for (size_t i = 0; i < source_address_tokens.tokens_size(); i++) { |
| 1559 const SourceAddressToken& token = source_address_tokens.tokens(i); |
| 1560 reason = ValidateSingleSourceAddressToken(token, ip, now); |
| 1561 if (reason == HANDSHAKE_OK) { |
| 1562 if (token.has_cached_network_parameters()) { |
| 1563 *cached_network_params = token.cached_network_parameters(); |
| 1564 } |
| 1565 break; |
| 1566 } |
| 1567 } |
| 1568 return reason; |
| 1569 } |
| 1570 |
| 1571 HandshakeFailureReason QuicCryptoServerConfig::ValidateSingleSourceAddressToken( |
| 1572 const SourceAddressToken& source_address_token, |
| 1573 const IPEndPoint& ip, |
| 1574 QuicWallTime now) const { |
| 1575 IPAddressNumber ip_address = ip.address(); |
| 1576 if (ip.GetSockAddrFamily() == AF_INET) { |
| 1577 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); |
| 1578 } |
| 1579 if (source_address_token.ip() != IPAddressToPackedString(ip_address)) { |
| 1580 // It's for a different IP address. |
| 1581 return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE; |
| 1582 } |
| 1583 |
| 1584 return ValidateSourceAddressTokenTimestamp(source_address_token, now); |
| 1585 } |
| 1586 |
| 1587 HandshakeFailureReason |
| 1588 QuicCryptoServerConfig::ValidateSourceAddressTokenTimestamp( |
| 1589 const SourceAddressToken& source_address_token, |
| 1590 QuicWallTime now) const { |
| 1591 const QuicWallTime timestamp( |
| 1592 QuicWallTime::FromUNIXSeconds(source_address_token.timestamp())); |
| 1593 const QuicTime::Delta delta(now.AbsoluteDifference(timestamp)); |
| 1594 |
| 1595 if (now.IsBefore(timestamp) && |
| 1596 delta.ToSeconds() > source_address_token_future_secs_) { |
| 1597 return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE; |
| 1598 } |
| 1599 |
| 1600 if (now.IsAfter(timestamp) && |
| 1601 delta.ToSeconds() > source_address_token_lifetime_secs_) { |
| 1602 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE; |
| 1603 } |
| 1604 |
| 1605 return HANDSHAKE_OK; |
| 1606 } |
| 1607 |
1486 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server | 1608 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server |
1487 // nonce. | 1609 // nonce. |
1488 static const size_t kServerNoncePlaintextSize = | 1610 static const size_t kServerNoncePlaintextSize = |
1489 4 /* timestamp */ + 20 /* random bytes */; | 1611 4 /* timestamp */ + 20 /* random bytes */; |
1490 | 1612 |
1491 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, | 1613 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, |
1492 QuicWallTime now) const { | 1614 QuicWallTime now) const { |
1493 const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds()); | 1615 const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds()); |
1494 | 1616 |
1495 uint8 server_nonce[kServerNoncePlaintextSize]; | 1617 uint8 server_nonce[kServerNoncePlaintextSize]; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1569 QuicCryptoServerConfig::Config::Config() | 1691 QuicCryptoServerConfig::Config::Config() |
1570 : channel_id_enabled(false), | 1692 : channel_id_enabled(false), |
1571 is_primary(false), | 1693 is_primary(false), |
1572 primary_time(QuicWallTime::Zero()), | 1694 primary_time(QuicWallTime::Zero()), |
1573 priority(0), | 1695 priority(0), |
1574 source_address_token_boxer(nullptr) {} | 1696 source_address_token_boxer(nullptr) {} |
1575 | 1697 |
1576 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1698 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } |
1577 | 1699 |
1578 } // namespace net | 1700 } // namespace net |
OLD | NEW |