blob: 95530f2538febaef440c6cb14275aee12ad7c8c1 [file] [log] [blame]
// Copyright (c) 2015 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/test_tools/quic_test_server.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/synchronization/lock.h"
#include "base/thread_task_runner_handle.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
#include "net/quic/crypto/quic_random.h"
#include "net/quic/quic_config.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_connection_helper.h"
#include "net/quic/quic_packet_writer.h"
#include "net/quic/quic_protocol.h"
#include "net/tools/quic/quic_dispatcher.h"
#include "net/tools/quic/quic_epoll_connection_helper.h"
#include "net/tools/quic/quic_server_session.h"
#include "net/tools/quic/quic_spdy_server_stream.h"
namespace net {
namespace tools {
namespace test {
class CustomStreamSession : public QuicServerSession {
public:
CustomStreamSession(
const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
const QuicCryptoServerConfig* crypto_config,
QuicTestServer::StreamFactory* factory,
QuicTestServer::CryptoStreamFactory* crypto_stream_factory)
: QuicServerSession(config, connection, visitor, crypto_config),
stream_factory_(factory),
crypto_stream_factory_(crypto_stream_factory) {}
QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override {
if (!ShouldCreateIncomingDynamicStream(id)) {
return nullptr;
}
if (stream_factory_) {
return stream_factory_->CreateStream(id, this);
}
return QuicServerSession::CreateIncomingDynamicStream(id);
}
QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
const QuicCryptoServerConfig* crypto_config) override {
if (crypto_stream_factory_) {
return crypto_stream_factory_->CreateCryptoStream(crypto_config, this);
}
return QuicServerSession::CreateQuicCryptoServerStream(crypto_config);
}
private:
QuicTestServer::StreamFactory* stream_factory_; // Not owned.
QuicTestServer::CryptoStreamFactory* crypto_stream_factory_; // Not owned.
};
class QuicTestDispatcher : public QuicDispatcher {
public:
QuicTestDispatcher(const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config,
const QuicVersionVector& versions,
PacketWriterFactory* factory,
QuicConnectionHelperInterface* helper)
: QuicDispatcher(config, crypto_config, versions, factory, helper),
session_factory_(nullptr),
stream_factory_(nullptr),
crypto_stream_factory_(nullptr) {}
QuicServerSession* CreateQuicSession(QuicConnectionId id,
const IPEndPoint& client) override {
base::AutoLock lock(factory_lock_);
if (session_factory_ == nullptr && stream_factory_ == nullptr &&
crypto_stream_factory_ == nullptr) {
return QuicDispatcher::CreateQuicSession(id, client);
}
QuicConnection* connection = new QuicConnection(
id, client, helper(), connection_writer_factory(),
/* owns_writer= */ true, Perspective::IS_SERVER, supported_versions());
QuicServerSession* session = nullptr;
if (stream_factory_ != nullptr || crypto_stream_factory_ != nullptr) {
session =
new CustomStreamSession(config(), connection, this, crypto_config(),
stream_factory_, crypto_stream_factory_);
} else {
session = session_factory_->CreateSession(config(), connection, this,
crypto_config());
}
session->Initialize();
return session;
}
void SetSessionFactory(QuicTestServer::SessionFactory* factory) {
base::AutoLock lock(factory_lock_);
DCHECK(session_factory_ == nullptr);
DCHECK(stream_factory_ == nullptr);
DCHECK(crypto_stream_factory_ == nullptr);
session_factory_ = factory;
}
void SetStreamFactory(QuicTestServer::StreamFactory* factory) {
base::AutoLock lock(factory_lock_);
DCHECK(session_factory_ == nullptr);
DCHECK(stream_factory_ == nullptr);
stream_factory_ = factory;
}
void SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory* factory) {
base::AutoLock lock(factory_lock_);
DCHECK(session_factory_ == nullptr);
DCHECK(crypto_stream_factory_ == nullptr);
crypto_stream_factory_ = factory;
}
private:
base::Lock factory_lock_;
QuicTestServer::SessionFactory* session_factory_; // Not owned.
QuicTestServer::StreamFactory* stream_factory_; // Not owned.
QuicTestServer::CryptoStreamFactory* crypto_stream_factory_; // Not owned.
};
QuicTestServer::QuicTestServer(ProofSource* proof_source)
: QuicServer(proof_source) {}
QuicTestServer::QuicTestServer(ProofSource* proof_source,
const QuicConfig& config,
const QuicVersionVector& supported_versions)
: QuicServer(proof_source, config, supported_versions) {}
QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
return new QuicTestDispatcher(
config(), &crypto_config(), supported_versions(),
new QuicDispatcher::DefaultPacketWriterFactory(),
new QuicEpollConnectionHelper(epoll_server()));
}
void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
DCHECK(dispatcher());
static_cast<QuicTestDispatcher*>(dispatcher())->SetSessionFactory(factory);
}
void QuicTestServer::SetSpdyStreamFactory(StreamFactory* factory) {
static_cast<QuicTestDispatcher*>(dispatcher())->SetStreamFactory(factory);
}
void QuicTestServer::SetCryptoStreamFactory(CryptoStreamFactory* factory) {
static_cast<QuicTestDispatcher*>(dispatcher())
->SetCryptoStreamFactory(factory);
}
/////////////////////////// TEST SESSIONS ///////////////////////////////
ImmediateGoAwaySession::ImmediateGoAwaySession(
const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
const QuicCryptoServerConfig* crypto_config)
: QuicServerSession(config, connection, visitor, crypto_config) {
SendGoAway(QUIC_PEER_GOING_AWAY, "");
}
} // namespace test
} // namespace tools
} // namespace net