| 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 193 |
| 194 server_nonce_boxer_.SetKey( | 194 server_nonce_boxer_.SetKey( |
| 195 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); | 195 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); |
| 196 } | 196 } |
| 197 | 197 |
| 198 QuicCryptoServerConfig::~QuicCryptoServerConfig() { | 198 QuicCryptoServerConfig::~QuicCryptoServerConfig() { |
| 199 primary_config_ = NULL; | 199 primary_config_ = NULL; |
| 200 } | 200 } |
| 201 | 201 |
| 202 // static | 202 // static |
| 203 QuicServerConfigProtobuf* QuicCryptoServerConfig::DefaultConfig( | 203 QuicServerConfigProtobuf* QuicCryptoServerConfig::GenerateConfig( |
| 204 QuicRandom* rand, | 204 QuicRandom* rand, |
| 205 const QuicClock* clock, | 205 const QuicClock* clock, |
| 206 const ConfigOptions& options) { | 206 const ConfigOptions& options) { |
| 207 CryptoHandshakeMessage msg; | 207 CryptoHandshakeMessage msg; |
| 208 | 208 |
| 209 const string curve25519_private_key = | 209 const string curve25519_private_key = |
| 210 Curve25519KeyExchange::NewPrivateKey(rand); | 210 Curve25519KeyExchange::NewPrivateKey(rand); |
| 211 scoped_ptr<Curve25519KeyExchange> curve25519( | 211 scoped_ptr<Curve25519KeyExchange> curve25519( |
| 212 Curve25519KeyExchange::New(curve25519_private_key)); | 212 Curve25519KeyExchange::New(curve25519_private_key)); |
| 213 StringPiece curve25519_public_value = curve25519->public_value(); | 213 StringPiece curve25519_public_value = curve25519->public_value(); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 if (configs_.find(config->id) != configs_.end()) { | 324 if (configs_.find(config->id) != configs_.end()) { |
| 325 LOG(WARNING) << "Failed to add config because another with the same " | 325 LOG(WARNING) << "Failed to add config because another with the same " |
| 326 "server config id already exists: " | 326 "server config id already exists: " |
| 327 << base::HexEncode(config->id.data(), config->id.size()); | 327 << base::HexEncode(config->id.data(), config->id.size()); |
| 328 return NULL; | 328 return NULL; |
| 329 } | 329 } |
| 330 | 330 |
| 331 configs_[config->id] = config; | 331 configs_[config->id] = config; |
| 332 SelectNewPrimaryConfig(now); | 332 SelectNewPrimaryConfig(now); |
| 333 DCHECK(primary_config_.get()); | 333 DCHECK(primary_config_.get()); |
| 334 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
| 334 } | 335 } |
| 335 | 336 |
| 336 return msg.release(); | 337 return msg.release(); |
| 337 } | 338 } |
| 338 | 339 |
| 339 CryptoHandshakeMessage* QuicCryptoServerConfig::AddDefaultConfig( | 340 CryptoHandshakeMessage* QuicCryptoServerConfig::AddDefaultConfig( |
| 340 QuicRandom* rand, | 341 QuicRandom* rand, |
| 341 const QuicClock* clock, | 342 const QuicClock* clock, |
| 342 const ConfigOptions& options) { | 343 const ConfigOptions& options) { |
| 343 scoped_ptr<QuicServerConfigProtobuf> config( | 344 scoped_ptr<QuicServerConfigProtobuf> config( |
| 344 DefaultConfig(rand, clock, options)); | 345 GenerateConfig(rand, clock, options)); |
| 345 return AddConfig(config.get(), clock->WallNow()); | 346 return AddConfig(config.get(), clock->WallNow()); |
| 346 } | 347 } |
| 347 | 348 |
| 348 bool QuicCryptoServerConfig::SetConfigs( | 349 bool QuicCryptoServerConfig::SetConfigs( |
| 349 const vector<QuicServerConfigProtobuf*>& protobufs, | 350 const vector<QuicServerConfigProtobuf*>& protobufs, |
| 350 const QuicWallTime now) { | 351 const QuicWallTime now) { |
| 351 vector<scoped_refptr<Config> > new_configs; | 352 vector<scoped_refptr<Config> > parsed_configs; |
| 352 bool ok = true; | 353 bool ok = true; |
| 353 | 354 |
| 354 for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin(); | 355 for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin(); |
| 355 i != protobufs.end(); ++i) { | 356 i != protobufs.end(); ++i) { |
| 356 scoped_refptr<Config> config(ParseConfigProtobuf(*i)); | 357 scoped_refptr<Config> config(ParseConfigProtobuf(*i)); |
| 357 if (!config.get()) { | 358 if (!config.get()) { |
| 358 ok = false; | 359 ok = false; |
| 359 break; | 360 break; |
| 360 } | 361 } |
| 361 new_configs.push_back(config); | 362 |
| 363 parsed_configs.push_back(config); |
| 364 } |
| 365 |
| 366 if (parsed_configs.empty()) { |
| 367 LOG(WARNING) << "New config list is empty."; |
| 368 ok = false; |
| 362 } | 369 } |
| 363 | 370 |
| 364 if (!ok) { | 371 if (!ok) { |
| 365 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; | 372 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; |
| 366 } else { | 373 } else { |
| 374 VLOG(1) << "Updating configs:"; |
| 375 |
| 367 base::AutoLock locked(configs_lock_); | 376 base::AutoLock locked(configs_lock_); |
| 368 typedef ConfigMap::iterator ConfigMapIterator; | 377 ConfigMap new_configs; |
| 369 vector<ConfigMapIterator> to_delete; | |
| 370 | 378 |
| 371 DCHECK_EQ(protobufs.size(), new_configs.size()); | 379 for (vector<scoped_refptr<Config> >::const_iterator i = |
| 372 | 380 parsed_configs.begin(); |
| 373 // First, look for any configs that have been removed. | 381 i != parsed_configs.end(); ++i) { |
| 374 for (ConfigMapIterator i = configs_.begin(); | 382 scoped_refptr<Config> config = *i; |
| 375 i != configs_.end(); ++i) { | 383 ConfigMap::iterator it = configs_.find(config->id); |
| 376 const scoped_refptr<Config> old_config = i->second; | 384 if (it != configs_.end()) { |
| 377 bool found = false; | 385 VLOG(1) |
| 378 | 386 << "Keeping scid: " << base::HexEncode( |
| 379 for (vector<scoped_refptr<Config> >::const_iterator j = | 387 config->id.data(), config->id.size()) |
| 380 new_configs.begin(); | 388 << " orbit: " << base::HexEncode( |
| 381 j != new_configs.end(); ++j) { | 389 reinterpret_cast<const char *>(config->orbit), kOrbitSize) |
| 382 if ((*j)->id == old_config->id) { | 390 << " new primary_time " << config->primary_time.ToUNIXSeconds() |
| 383 found = true; | 391 << " old primary_time " << it->second->primary_time.ToUNIXSeconds() |
| 384 break; | 392 << " new priority " << config->priority |
| 385 } | 393 << " old priority " << it->second->priority; |
| 386 } | 394 // Update primary_time and priority. |
| 387 | 395 it->second->primary_time = config->primary_time; |
| 388 if (!found) { | 396 it->second->priority = config->priority; |
| 389 // We cannot remove the primary config. This has probably happened | 397 new_configs.insert(*it); |
| 390 // because our source of config information failed for a time and we're | 398 } else { |
| 391 // suddenly seeing a jump in time. No matter - we'll configure a new | 399 VLOG(1) << "Adding scid: " << base::HexEncode( |
| 392 // primary config and then we'll be able to delete it next time. | 400 config->id.data(), config->id.size()) |
| 393 if (!old_config->is_primary) { | 401 << " orbit: " << base::HexEncode( |
| 394 to_delete.push_back(i); | 402 reinterpret_cast<const char *>(config->orbit), kOrbitSize) |
| 395 } | 403 << " primary_time " << config->primary_time.ToUNIXSeconds() |
| 404 << " priority " << config->priority; |
| 405 new_configs.insert(make_pair(config->id, config)); |
| 396 } | 406 } |
| 397 } | 407 } |
| 398 | 408 |
| 399 for (vector<ConfigMapIterator>::const_iterator i = to_delete.begin(); | 409 configs_.swap(new_configs); |
| 400 i != to_delete.end(); ++i) { | |
| 401 configs_.erase(*i); | |
| 402 } | |
| 403 | |
| 404 // Find any configs that need to be added. | |
| 405 for (vector<scoped_refptr<Config> >::const_iterator i = new_configs.begin(); | |
| 406 i != new_configs.end(); ++i) { | |
| 407 const scoped_refptr<Config> new_config = *i; | |
| 408 if (configs_.find(new_config->id) != configs_.end()) { | |
| 409 continue; | |
| 410 } | |
| 411 | |
| 412 configs_[new_config->id] = new_config; | |
| 413 } | |
| 414 | |
| 415 SelectNewPrimaryConfig(now); | 410 SelectNewPrimaryConfig(now); |
| 411 DCHECK(primary_config_); |
| 412 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
| 416 } | 413 } |
| 417 | 414 |
| 418 return ok; | 415 return ok; |
| 419 } | 416 } |
| 420 | 417 |
| 421 void QuicCryptoServerConfig::ValidateClientHello( | 418 void QuicCryptoServerConfig::ValidateClientHello( |
| 422 const CryptoHandshakeMessage& client_hello, | 419 const CryptoHandshakeMessage& client_hello, |
| 423 IPEndPoint client_ip, | 420 IPEndPoint client_ip, |
| 424 const QuicClock* clock, | 421 const QuicClock* clock, |
| 425 ValidateClientHelloResultCallback* done_cb) const { | 422 ValidateClientHelloResultCallback* done_cb) const { |
| 426 const QuicWallTime now(clock->WallNow()); | 423 const QuicWallTime now(clock->WallNow()); |
| 424 |
| 427 ValidateClientHelloResultCallback::Result* result = | 425 ValidateClientHelloResultCallback::Result* result = |
| 428 new ValidateClientHelloResultCallback::Result( | 426 new ValidateClientHelloResultCallback::Result( |
| 429 client_hello, client_ip, now); | 427 client_hello, client_ip, now); |
| 430 | 428 |
| 431 uint8 primary_orbit[kOrbitSize]; | 429 uint8 primary_orbit[kOrbitSize]; |
| 432 { | 430 { |
| 433 base::AutoLock locked(configs_lock_); | 431 base::AutoLock locked(configs_lock_); |
| 434 | 432 |
| 435 if (!primary_config_) { | 433 if (!primary_config_.get()) { |
| 436 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; | 434 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; |
| 437 result->error_details = "No configurations loaded"; | 435 result->error_details = "No configurations loaded"; |
| 438 } else { | 436 } else { |
| 439 if (!next_config_promotion_time_.IsZero() && | 437 if (!next_config_promotion_time_.IsZero() && |
| 440 next_config_promotion_time_.IsAfter(now)) { | 438 next_config_promotion_time_.IsAfter(now)) { |
| 441 SelectNewPrimaryConfig(now); | 439 SelectNewPrimaryConfig(now); |
| 440 DCHECK(primary_config_); |
| 441 DCHECK(configs_.find(primary_config_->id)->second == primary_config_); |
| 442 } | 442 } |
| 443 | 443 |
| 444 memcpy(primary_orbit, primary_config_->orbit, sizeof(primary_orbit)); | 444 memcpy(primary_orbit, primary_config_->orbit, sizeof(primary_orbit)); |
| 445 } | 445 } |
| 446 } | 446 } |
| 447 | 447 |
| 448 if (result->error_code == QUIC_NO_ERROR) { | 448 if (result->error_code == QUIC_NO_ERROR) { |
| 449 EvaluateClientHello(primary_orbit, result, done_cb); | 449 EvaluateClientHello(primary_orbit, result, done_cb); |
| 450 } else { | 450 } else { |
| 451 done_cb->Run(result); | 451 done_cb->Run(result); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 base::AutoLock locked(configs_lock_); | 500 base::AutoLock locked(configs_lock_); |
| 501 | 501 |
| 502 if (!primary_config_.get()) { | 502 if (!primary_config_.get()) { |
| 503 *error_details = "No configurations loaded"; | 503 *error_details = "No configurations loaded"; |
| 504 return QUIC_CRYPTO_INTERNAL_ERROR; | 504 return QUIC_CRYPTO_INTERNAL_ERROR; |
| 505 } | 505 } |
| 506 | 506 |
| 507 if (!next_config_promotion_time_.IsZero() && | 507 if (!next_config_promotion_time_.IsZero() && |
| 508 next_config_promotion_time_.IsAfter(now)) { | 508 next_config_promotion_time_.IsAfter(now)) { |
| 509 SelectNewPrimaryConfig(now); | 509 SelectNewPrimaryConfig(now); |
| 510 DCHECK(primary_config_); |
| 511 DCHECK(configs_.find(primary_config_->id)->second == primary_config_); |
| 510 } | 512 } |
| 511 | 513 |
| 512 primary_config = primary_config_; | 514 primary_config = primary_config_; |
| 513 | 515 |
| 514 if (!requested_scid.empty()) { | 516 if (!requested_scid.empty()) { |
| 515 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); | 517 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); |
| 516 if (it != configs_.end()) { | 518 if (it != configs_.end()) { |
| 517 // We'll use the config that the client requested in order to do | 519 // We'll use the config that the client requested in order to do |
| 518 // key-agreement. Otherwise we'll give it a copy of |primary_config_| | 520 // key-agreement. Otherwise we'll give it a copy of |primary_config_| |
| 519 // to use. | 521 // to use. |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 out->SetStringPiece(kPUBS, forward_secure_public_value); | 704 out->SetStringPiece(kPUBS, forward_secure_public_value); |
| 703 return QUIC_NO_ERROR; | 705 return QUIC_NO_ERROR; |
| 704 } | 706 } |
| 705 | 707 |
| 706 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for | 708 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for |
| 707 // Config's based on their primary_time. | 709 // Config's based on their primary_time. |
| 708 // static | 710 // static |
| 709 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( | 711 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( |
| 710 const scoped_refptr<Config>& a, | 712 const scoped_refptr<Config>& a, |
| 711 const scoped_refptr<Config>& b) { | 713 const scoped_refptr<Config>& b) { |
| 712 return a->primary_time.IsBefore(b->primary_time); | 714 if (a->primary_time.IsBefore(b->primary_time) || |
| 715 b->primary_time.IsBefore(a->primary_time)) { |
| 716 // Primary times differ. |
| 717 return a->primary_time.IsBefore(b->primary_time); |
| 718 } else if (a->priority != b->priority) { |
| 719 // Primary times are equal, sort backwards by priority. |
| 720 return a->priority < b->priority; |
| 721 } else { |
| 722 // Primary times and priorities are equal, sort by config id. |
| 723 return a->id < b->id; |
| 724 } |
| 713 } | 725 } |
| 714 | 726 |
| 715 void QuicCryptoServerConfig::SelectNewPrimaryConfig( | 727 void QuicCryptoServerConfig::SelectNewPrimaryConfig( |
| 716 const QuicWallTime now) const { | 728 const QuicWallTime now) const { |
| 717 vector<scoped_refptr<Config> > configs; | 729 vector<scoped_refptr<Config> > configs; |
| 718 configs.reserve(configs_.size()); | 730 configs.reserve(configs_.size()); |
| 719 scoped_refptr<Config> first_config = NULL; | |
| 720 | 731 |
| 721 for (ConfigMap::const_iterator it = configs_.begin(); | 732 for (ConfigMap::const_iterator it = configs_.begin(); |
| 722 it != configs_.end(); ++it) { | 733 it != configs_.end(); ++it) { |
| 723 const scoped_refptr<Config> config(it->second); | 734 // TODO(avd) Exclude expired configs? |
| 724 if (!first_config.get()) { | |
| 725 first_config = config; | |
| 726 } | |
| 727 if (config->primary_time.IsZero()) { | |
| 728 continue; | |
| 729 } | |
| 730 configs.push_back(it->second); | 735 configs.push_back(it->second); |
| 731 } | 736 } |
| 732 | 737 |
| 733 if (configs.empty()) { | 738 if (configs.empty()) { |
| 734 // Tests don't set |primary_time_|. For that case we promote the first | 739 if (primary_config_.get()) { |
| 735 // Config and leave it as primary forever. | 740 LOG(DFATAL) << "No valid QUIC server config. Keeping the current config."; |
| 736 if (!primary_config_.get() && first_config.get()) { | 741 } else { |
| 737 primary_config_ = first_config; | 742 LOG(DFATAL) << "No valid QUIC server config."; |
| 738 primary_config_->is_primary = true; | |
| 739 } | 743 } |
| 740 return; | 744 return; |
| 741 } | 745 } |
| 742 | 746 |
| 743 std::sort(configs.begin(), configs.end(), ConfigPrimaryTimeLessThan); | 747 std::sort(configs.begin(), configs.end(), ConfigPrimaryTimeLessThan); |
| 744 | 748 |
| 749 Config* best_candidate = configs[0]; |
| 750 |
| 745 for (size_t i = 0; i < configs.size(); ++i) { | 751 for (size_t i = 0; i < configs.size(); ++i) { |
| 746 const scoped_refptr<Config> config(configs[i]); | 752 const scoped_refptr<Config> config(configs[i]); |
| 747 | |
| 748 if (!config->primary_time.IsAfter(now)) { | 753 if (!config->primary_time.IsAfter(now)) { |
| 754 if (config->primary_time.IsAfter(best_candidate->primary_time)) { |
| 755 best_candidate = config; |
| 756 } |
| 749 continue; | 757 continue; |
| 750 } | 758 } |
| 751 | 759 |
| 752 // This is the first config with a primary_time in the future. Thus the | 760 // This is the first config with a primary_time in the future. Thus the |
| 753 // previous Config should be the primary and this one should determine the | 761 // previous Config should be the primary and this one should determine the |
| 754 // next_config_promotion_time_. | 762 // next_config_promotion_time_. |
| 755 scoped_refptr<Config> new_primary; | 763 scoped_refptr<Config> new_primary(best_candidate); |
| 756 if (i == 0) { | 764 if (i == 0) { |
| 757 // There was no previous Config, so this will have to be primary. | |
| 758 new_primary = config; | |
| 759 | |
| 760 // We need the primary_time of the next config. | 765 // We need the primary_time of the next config. |
| 761 if (configs.size() > 1) { | 766 if (configs.size() > 1) { |
| 762 next_config_promotion_time_ = configs[1]->primary_time; | 767 next_config_promotion_time_ = configs[1]->primary_time; |
| 763 } else { | 768 } else { |
| 764 next_config_promotion_time_ = QuicWallTime::Zero(); | 769 next_config_promotion_time_ = QuicWallTime::Zero(); |
| 765 } | 770 } |
| 766 } else { | 771 } else { |
| 767 new_primary = configs[i - 1]; | |
| 768 next_config_promotion_time_ = config->primary_time; | 772 next_config_promotion_time_ = config->primary_time; |
| 769 } | 773 } |
| 770 | 774 |
| 771 if (primary_config_.get()) { | 775 if (primary_config_.get()) { |
| 772 primary_config_->is_primary = false; | 776 primary_config_->is_primary = false; |
| 773 } | 777 } |
| 774 primary_config_ = new_primary; | 778 primary_config_ = new_primary; |
| 775 new_primary->is_primary = true; | 779 new_primary->is_primary = true; |
| 780 DVLOG(1) << "New primary config. orbit: " |
| 781 << base::HexEncode( |
| 782 reinterpret_cast<const char*>(primary_config_->orbit), |
| 783 kOrbitSize); |
| 776 | 784 |
| 777 return; | 785 return; |
| 778 } | 786 } |
| 779 | 787 |
| 780 // All config's primary times are in the past. We should make the most recent | 788 // All config's primary times are in the past. We should make the most recent |
| 781 // primary. | 789 // most recent and highest priority candidate primary. |
| 782 scoped_refptr<Config> new_primary = configs[configs.size() - 1]; | 790 scoped_refptr<Config> new_primary(best_candidate); |
| 783 if (primary_config_.get()) { | 791 if (primary_config_.get()) { |
| 784 primary_config_->is_primary = false; | 792 primary_config_->is_primary = false; |
| 785 } | 793 } |
| 786 primary_config_ = new_primary; | 794 primary_config_ = new_primary; |
| 787 new_primary->is_primary = true; | 795 new_primary->is_primary = true; |
| 796 DVLOG(1) << "New primary config. orbit: " |
| 797 << base::HexEncode( |
| 798 reinterpret_cast<const char*>(primary_config_->orbit), |
| 799 kOrbitSize); |
| 788 next_config_promotion_time_ = QuicWallTime::Zero(); | 800 next_config_promotion_time_ = QuicWallTime::Zero(); |
| 789 } | 801 } |
| 790 | 802 |
| 791 void QuicCryptoServerConfig::EvaluateClientHello( | 803 void QuicCryptoServerConfig::EvaluateClientHello( |
| 792 const uint8* primary_orbit, | 804 const uint8* primary_orbit, |
| 793 ValidateClientHelloResultCallback::Result* client_hello_state, | 805 ValidateClientHelloResultCallback::Result* client_hello_state, |
| 794 ValidateClientHelloResultCallback* done_cb) const { | 806 ValidateClientHelloResultCallback* done_cb) const { |
| 795 ValidateClientHelloHelper helper(client_hello_state, done_cb); | 807 ValidateClientHelloHelper helper(client_hello_state, done_cb); |
| 796 | 808 |
| 797 const CryptoHandshakeMessage& client_hello = | 809 const CryptoHandshakeMessage& client_hello = |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 } | 981 } |
| 970 | 982 |
| 971 scoped_refptr<Config> config(new Config); | 983 scoped_refptr<Config> config(new Config); |
| 972 config->serialized = protobuf->config(); | 984 config->serialized = protobuf->config(); |
| 973 | 985 |
| 974 if (protobuf->has_primary_time()) { | 986 if (protobuf->has_primary_time()) { |
| 975 config->primary_time = | 987 config->primary_time = |
| 976 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); | 988 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); |
| 977 } | 989 } |
| 978 | 990 |
| 991 config->priority = protobuf->priority(); |
| 992 |
| 979 StringPiece scid; | 993 StringPiece scid; |
| 980 if (!msg->GetStringPiece(kSCID, &scid)) { | 994 if (!msg->GetStringPiece(kSCID, &scid)) { |
| 981 LOG(WARNING) << "Server config message is missing SCID"; | 995 LOG(WARNING) << "Server config message is missing SCID"; |
| 982 return NULL; | 996 return NULL; |
| 983 } | 997 } |
| 984 config->id = scid.as_string(); | 998 config->id = scid.as_string(); |
| 985 | 999 |
| 986 const QuicTag* aead_tags; | 1000 const QuicTag* aead_tags; |
| 987 size_t aead_len; | 1001 size_t aead_len; |
| 988 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { | 1002 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1012 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); | 1026 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); |
| 1013 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); | 1027 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); |
| 1014 | 1028 |
| 1015 { | 1029 { |
| 1016 StrikeRegisterClient* strike_register_client; | 1030 StrikeRegisterClient* strike_register_client; |
| 1017 { | 1031 { |
| 1018 base::AutoLock locked(strike_register_client_lock_); | 1032 base::AutoLock locked(strike_register_client_lock_); |
| 1019 strike_register_client = strike_register_client_.get(); | 1033 strike_register_client = strike_register_client_.get(); |
| 1020 } | 1034 } |
| 1021 | 1035 |
| 1022 if (strike_register_client != NULL) { | 1036 if (strike_register_client != NULL && |
| 1023 const string& orbit = strike_register_client->orbit(); | 1037 !strike_register_client->IsKnownOrbit(orbit)) { |
| 1024 if (0 != memcmp(orbit.data(), config->orbit, kOrbitSize)) { | 1038 LOG(WARNING) |
| 1025 LOG(WARNING) | 1039 << "Rejecting server config with orbit that the strike register " |
| 1026 << "Server config has different orbit than current config. " | 1040 "client doesn't know about."; |
| 1027 "Switching orbits at run-time is not supported."; | 1041 return NULL; |
| 1028 return NULL; | |
| 1029 } | |
| 1030 } | 1042 } |
| 1031 } | 1043 } |
| 1032 | 1044 |
| 1033 if (kexs_len != protobuf->key_size()) { | 1045 if (kexs_len != protobuf->key_size()) { |
| 1034 LOG(WARNING) << "Server config has " << kexs_len | 1046 LOG(WARNING) << "Server config has " << kexs_len |
| 1035 << " key exchange methods configured, but " | 1047 << " key exchange methods configured, but " |
| 1036 << protobuf->key_size() << " private keys"; | 1048 << protobuf->key_size() << " private keys"; |
| 1037 return NULL; | 1049 return NULL; |
| 1038 } | 1050 } |
| 1039 | 1051 |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1281 is_unique = server_nonce_strike_register_->Insert( | 1293 is_unique = server_nonce_strike_register_->Insert( |
| 1282 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); | 1294 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); |
| 1283 } | 1295 } |
| 1284 | 1296 |
| 1285 return is_unique; | 1297 return is_unique; |
| 1286 } | 1298 } |
| 1287 | 1299 |
| 1288 QuicCryptoServerConfig::Config::Config() | 1300 QuicCryptoServerConfig::Config::Config() |
| 1289 : channel_id_enabled(false), | 1301 : channel_id_enabled(false), |
| 1290 is_primary(false), | 1302 is_primary(false), |
| 1291 primary_time(QuicWallTime::Zero()) {} | 1303 primary_time(QuicWallTime::Zero()), |
| 1304 priority(0) {} |
| 1292 | 1305 |
| 1293 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1306 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } |
| 1294 | 1307 |
| 1295 } // namespace net | 1308 } // namespace net |
| OLD | NEW |