| // Copyright 2016 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/tools/quic/stateless_rejector.h" |
| |
| #include "net/quic/quic_crypto_server_stream.h" |
| #include "net/quic/quic_flags.h" |
| |
| namespace net { |
| |
| class StatelessRejector::ValidateCallback |
| : public ValidateClientHelloResultCallback { |
| public: |
| explicit ValidateCallback(StatelessRejector* rejector) |
| : rejector_(rejector) {} |
| |
| ~ValidateCallback() override {} |
| |
| void RunImpl(const CryptoHandshakeMessage& client_hello, |
| const Result& result) override { |
| rejector_->ProcessClientHello(client_hello, result); |
| } |
| |
| private: |
| StatelessRejector* rejector_; |
| }; |
| |
| StatelessRejector::StatelessRejector( |
| QuicVersion version, |
| const QuicVersionVector& versions, |
| const QuicCryptoServerConfig* crypto_config, |
| QuicCompressedCertsCache* compressed_certs_cache, |
| const QuicClock* clock, |
| QuicRandom* random, |
| const IPEndPoint& client_address, |
| const IPEndPoint& server_address) |
| : state_(FAILED), |
| error_(QUIC_INTERNAL_ERROR), |
| version_(version), |
| versions_(versions), |
| connection_id_(0), |
| client_address_(client_address), |
| server_address_(server_address), |
| clock_(clock), |
| random_(random), |
| crypto_config_(crypto_config), |
| compressed_certs_cache_(compressed_certs_cache), |
| chlo_(nullptr) {} |
| |
| StatelessRejector::~StatelessRejector() {} |
| |
| void StatelessRejector::OnChlo(QuicVersion version, |
| QuicConnectionId connection_id, |
| QuicConnectionId server_designated_connection_id, |
| const CryptoHandshakeMessage& message) { |
| DCHECK_EQ(kCHLO, message.tag()); |
| DCHECK_NE(connection_id, server_designated_connection_id); |
| |
| if (!FLAGS_enable_quic_stateless_reject_support || |
| !FLAGS_quic_use_cheap_stateless_rejects || |
| !QuicCryptoServerStream::DoesPeerSupportStatelessRejects(message) || |
| version <= QUIC_VERSION_32) { |
| state_ = UNSUPPORTED; |
| return; |
| } |
| |
| connection_id_ = connection_id; |
| server_designated_connection_id_ = server_designated_connection_id; |
| chlo_ = &message; |
| |
| crypto_config_->ValidateClientHello( |
| message, client_address_.address(), server_address_.address(), version_, |
| clock_, &proof_, new ValidateCallback(this)); |
| } |
| |
| void StatelessRejector::ProcessClientHello( |
| const CryptoHandshakeMessage& client_hello, |
| const ValidateClientHelloResultCallback::Result& result) { |
| QuicCryptoNegotiatedParameters params; |
| DiversificationNonce diversification_nonce; |
| QuicErrorCode error = crypto_config_->ProcessClientHello( |
| result, |
| /*reject_only=*/true, connection_id_, server_address_.address(), |
| client_address_, version_, versions_, |
| /*use_stateless_rejects=*/true, server_designated_connection_id_, clock_, |
| random_, compressed_certs_cache_, ¶ms, &proof_, &reply_, |
| &diversification_nonce, &error_details_); |
| if (error != QUIC_NO_ERROR) { |
| error_ = error; |
| return; |
| } |
| |
| if (reply_.tag() == kSREJ) { |
| state_ = REJECTED; |
| return; |
| } |
| |
| state_ = ACCEPTED; |
| } |
| |
| } // namespace net |