// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/quic/quic_session_pool.h"

#include <fuzzer/FuzzedDataProvider.h>

#include <algorithm>

#include "base/no_destructor.h"
#include "base/task/sequenced_task_runner.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/privacy_mode.h"
#include "net/base/proxy_chain.h"
#include "net/base/session_usage.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/do_nothing_ct_verifier.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/x509_certificate.h"
#include "net/dns/context_host_resolver.h"
#include "net/dns/fuzzed_host_resolver_util.h"
#include "net/dns/host_resolver_system_task.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/http/http_server_properties.h"
#include "net/http/transport_security_state.h"
#include "net/quic/mock_crypto_client_stream_factory.h"
#include "net/quic/mock_quic_context.h"
#include "net/quic/quic_context.h"
#include "net/quic/quic_http_stream.h"
#include "net/quic/quic_session_key.h"
#include "net/quic/test_task_runner.h"
#include "net/socket/fuzzed_datagram_client_socket.h"
#include "net/socket/fuzzed_socket_factory.h"
#include "net/socket/socket_tag.h"
#include "net/spdy/multiplexed_session_creation_initiator.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/test/gtest_util.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "url/scheme_host_port.h"
#include "url/url_constants.h"

namespace net {

namespace {

const uint8_t kCertData[] = {
#include "net/data/ssl/certificates/wildcard.inc"
};

}  // namespace

namespace test {

const char kServerHostName[] = "www.example.org";
const int kServerPort = 443;
const char kUrl[] = "https://www.example.org/";
// TODO(nedwilliamson): Add POST here after testing
// whether that can lead blocking while waiting for
// the callbacks.
const char kMethod[] = "GET";
const size_t kBufferSize = 4096;
const int kCertVerifyFlags = 0;

// Persistent factory data, statically initialized on the first time
// LLVMFuzzerTestOneInput is called.
struct FuzzerEnvironment {
  FuzzerEnvironment()
      : scheme_host_port(url::kHttpsScheme, kServerHostName, kServerPort) {
    net::SetSystemDnsResolutionTaskRunnerForTesting(  // IN-TEST
        base::SequencedTaskRunner::GetCurrentDefault());

    quic_context.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
    ssl_config_service = std::make_unique<SSLConfigServiceDefaults>();
    crypto_client_stream_factory.set_use_mock_crypter(true);
    cert_verifier = std::make_unique<MockCertVerifier>();
    verify_details.cert_verify_result.verified_cert =
        X509Certificate::CreateFromBytes(kCertData);
    CHECK(verify_details.cert_verify_result.verified_cert);
    verify_details.cert_verify_result.is_issued_by_known_root = true;
  }
  ~FuzzerEnvironment() = default;

  std::unique_ptr<SSLConfigService> ssl_config_service;
  ProofVerifyDetailsChromium verify_details;
  MockCryptoClientStreamFactory crypto_client_stream_factory;
  url::SchemeHostPort scheme_host_port;
  NetLogWithSource net_log;
  std::unique_ptr<CertVerifier> cert_verifier;
  TransportSecurityState transport_security_state;
  quic::QuicTagVector connection_options;
  quic::QuicTagVector client_connection_options;
  MockQuicContext quic_context;
};

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  FuzzedDataProvider data_provider(data, size);
  FuzzerEnvironment env;

  std::unique_ptr<ContextHostResolver> host_resolver =
      CreateFuzzedContextHostResolver(HostResolver::ManagerOptions(), nullptr,
                                      &data_provider,
                                      true /* enable_caching */);
  FuzzedSocketFactory socket_factory(&data_provider);

  // Initialize this on each loop since some options mutate this.
  HttpServerProperties http_server_properties;

  QuicParams& params = *env.quic_context.params();
  params.max_server_configs_stored_in_properties =
      data_provider.ConsumeBool() ? 1 : 0;
  params.close_sessions_on_ip_change = data_provider.ConsumeBool();
  params.allow_server_migration = data_provider.ConsumeBool();
  params.estimate_initial_rtt = data_provider.ConsumeBool();
  params.enable_socket_recv_optimization = data_provider.ConsumeBool();

  env.crypto_client_stream_factory.AddProofVerifyDetails(&env.verify_details);

  params.goaway_sessions_on_ip_change = false;
  params.migrate_sessions_early_v2 = false;
  params.migrate_sessions_on_network_change_v2 = false;
  params.retry_on_alternate_network_before_handshake = false;
  params.migrate_idle_sessions = false;

  if (!params.close_sessions_on_ip_change) {
    params.goaway_sessions_on_ip_change = data_provider.ConsumeBool();
    if (!params.goaway_sessions_on_ip_change) {
      params.migrate_sessions_on_network_change_v2 =
          data_provider.ConsumeBool();
      if (params.migrate_sessions_on_network_change_v2) {
        params.migrate_sessions_early_v2 = data_provider.ConsumeBool();
        params.retry_on_alternate_network_before_handshake =
            data_provider.ConsumeBool();
        params.migrate_idle_sessions = data_provider.ConsumeBool();
      }
    }
  }

  std::unique_ptr<QuicSessionPool> factory = std::make_unique<QuicSessionPool>(
      env.net_log.net_log(), host_resolver.get(), env.ssl_config_service.get(),
      &socket_factory, &http_server_properties, env.cert_verifier.get(),
      &env.transport_security_state, nullptr, nullptr, nullptr,
      &env.crypto_client_stream_factory, &env.quic_context);

  QuicSessionRequest request(factory.get());
  TestCompletionCallback callback;
  NetErrorDetails net_error_details;
  quic::ParsedQuicVersionVector versions = AllSupportedQuicVersions();
  quic::ParsedQuicVersion version =
      versions[data_provider.ConsumeIntegralInRange<size_t>(
          0, versions.size() - 1)];

  quic::QuicEnableVersion(version);

  request.Request(
      env.scheme_host_port, version, ProxyChain::Direct(),
      TRAFFIC_ANNOTATION_FOR_TESTS, /*http_user_agent_settings=*/nullptr,
      SessionUsage::kDestination, PRIVACY_MODE_DISABLED, DEFAULT_PRIORITY,
      SocketTag(), NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
      /*require_dns_https_alpn=*/false, kCertVerifyFlags, GURL(kUrl),
      env.net_log, &net_error_details,
      MultiplexedSessionCreationInitiator::kUnknown,
      /*management_config=*/std::nullopt,
      /*failed_on_default_network_callback=*/CompletionOnceCallback(),
      callback.callback());

  callback.WaitForResult();
  std::unique_ptr<QuicChromiumClientSession::Handle> session =
      request.ReleaseSessionHandle();
  if (!session) {
    return 0;
  }
  auto dns_aliases = session->GetDnsAliasesForSessionKey(request.session_key());
  auto stream = std::make_unique<QuicHttpStream>(std::move(session),
                                                 std::move(dns_aliases));

  HttpRequestInfo request_info;
  request_info.method = kMethod;
  request_info.url = GURL(kUrl);
  request_info.traffic_annotation =
      MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  stream->RegisterRequest(&request_info);
  stream->InitializeStream(true, DEFAULT_PRIORITY, env.net_log,
                           CompletionOnceCallback());

  HttpResponseInfo response;
  HttpRequestHeaders request_headers;
  if (OK !=
      stream->SendRequest(request_headers, &response, callback.callback())) {
    return 0;
  }

  // TODO(nedwilliamson): attempt connection migration here
  int rv = stream->ReadResponseHeaders(callback.callback());
  if (rv != OK && rv != ERR_IO_PENDING) {
    return 0;
  }
  callback.WaitForResult();

  auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
  rv = stream->ReadResponseBody(buffer.get(), kBufferSize, callback.callback());
  if (rv == ERR_IO_PENDING) {
    callback.WaitForResult();
  }

  return 0;
}

}  // namespace test
}  // namespace net
