blob: 0fbbedd88c406adb0741c8a44306f613935ab92e [file] [log] [blame]
// 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_, &params, &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