// Copyright (c) 2021 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 "quic/core/crypto/quic_client_session_cache.h"

#include "quic/core/quic_clock.h"

namespace quic {

namespace {

const size_t kDefaultMaxEntries = 1024;
// Returns false if the SSL |session| doesn't exist or it is expired at |now|.
bool IsValid(SSL_SESSION* session, uint64_t now) {
  if (!session) return false;

  // now_u64 may be slightly behind because of differences in how
  // time is calculated at this layer versus BoringSSL.
  // Add a second of wiggle room to account for this.
  return !(now + 1 < SSL_SESSION_get_time(session) ||
           now >= SSL_SESSION_get_time(session) +
                      SSL_SESSION_get_timeout(session));
}

bool DoApplicationStatesMatch(const ApplicationState* state,
                              ApplicationState* other) {
  if ((state && !other) || (!state && other)) return false;
  if ((!state && !other) || *state == *other) return true;
  return false;
}

}  // namespace

QuicClientSessionCache::QuicClientSessionCache()
    : QuicClientSessionCache(kDefaultMaxEntries) {}

QuicClientSessionCache::QuicClientSessionCache(size_t max_entries)
    : cache_(max_entries) {}

QuicClientSessionCache::~QuicClientSessionCache() { Clear(); }

void QuicClientSessionCache::Insert(const QuicServerId& server_id,
                                    bssl::UniquePtr<SSL_SESSION> session,
                                    const TransportParameters& params,
                                    const ApplicationState* application_state) {
  QUICHE_DCHECK(session) << "TLS session is not inserted into client cache.";
  auto iter = cache_.Lookup(server_id);
  if (iter == cache_.end()) {
    CreateAndInsertEntry(server_id, std::move(session), params,
                         application_state);
    return;
  }

  QUICHE_DCHECK(iter->second->params);
  // The states are both the same, so only need to insert sessions.
  if (params == *iter->second->params &&
      DoApplicationStatesMatch(application_state,
                               iter->second->application_state.get())) {
    iter->second->PushSession(std::move(session));
    return;
  }
  // Erase the existing entry because this Insert call must come from a
  // different QUIC session.
  cache_.Erase(iter);
  CreateAndInsertEntry(server_id, std::move(session), params,
                       application_state);
}

std::unique_ptr<QuicResumptionState> QuicClientSessionCache::Lookup(
    const QuicServerId& server_id, QuicWallTime now, const SSL_CTX* /*ctx*/) {
  auto iter = cache_.Lookup(server_id);
  if (iter == cache_.end()) return nullptr;

  if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
    QUIC_DLOG(INFO) << "TLS Session expired for host:" << server_id.host();
    cache_.Erase(iter);
    return nullptr;
  }
  auto state = std::make_unique<QuicResumptionState>();
  state->tls_session = iter->second->PopSession();
  if (iter->second->params != nullptr) {
    state->transport_params =
        std::make_unique<TransportParameters>(*iter->second->params);
  }
  if (iter->second->application_state != nullptr) {
    state->application_state =
        std::make_unique<ApplicationState>(*iter->second->application_state);
  }
  if (GetQuicReloadableFlag(quic_tls_use_token_in_session_cache) &&
      !iter->second->token.empty()) {
    state->token = iter->second->token;
    // Clear token after use.
    iter->second->token.clear();
  }

  return state;
}

void QuicClientSessionCache::ClearEarlyData(const QuicServerId& server_id) {
  auto iter = cache_.Lookup(server_id);
  if (iter == cache_.end()) return;
  for (auto& session : iter->second->sessions) {
    if (session) {
      QUIC_DLOG(INFO) << "Clear early data for for host: " << server_id.host();
      session.reset(SSL_SESSION_copy_without_early_data(session.get()));
    }
  }
}

void QuicClientSessionCache::OnNewTokenReceived(const QuicServerId& server_id,
                                                absl::string_view token) {
  if (token.empty()) {
    return;
  }
  auto iter = cache_.Lookup(server_id);
  if (iter == cache_.end()) {
    return;
  }
  iter->second->token = std::string(token);
}

void QuicClientSessionCache::RemoveExpiredEntries(QuicWallTime now) {
  auto iter = cache_.begin();
  while (iter != cache_.end()) {
    if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
      iter = cache_.Erase(iter);
    } else {
      ++iter;
    }
  }
}

void QuicClientSessionCache::Clear() { cache_.Clear(); }

void QuicClientSessionCache::CreateAndInsertEntry(
    const QuicServerId& server_id, bssl::UniquePtr<SSL_SESSION> session,
    const TransportParameters& params,
    const ApplicationState* application_state) {
  auto entry = std::make_unique<Entry>();
  entry->PushSession(std::move(session));
  entry->params = std::make_unique<TransportParameters>(params);
  if (application_state) {
    entry->application_state =
        std::make_unique<ApplicationState>(*application_state);
  }
  cache_.Insert(server_id, std::move(entry));
}

QuicClientSessionCache::Entry::Entry() = default;
QuicClientSessionCache::Entry::Entry(Entry&&) = default;
QuicClientSessionCache::Entry::~Entry() = default;

void QuicClientSessionCache::Entry::PushSession(
    bssl::UniquePtr<SSL_SESSION> session) {
  if (sessions[0] != nullptr) {
    sessions[1] = std::move(sessions[0]);
  }
  sessions[0] = std::move(session);
}

bssl::UniquePtr<SSL_SESSION> QuicClientSessionCache::Entry::PopSession() {
  if (sessions[0] == nullptr) return nullptr;
  bssl::UniquePtr<SSL_SESSION> session = std::move(sessions[0]);
  sessions[0] = std::move(sessions[1]);
  sessions[1] = nullptr;
  return session;
}

SSL_SESSION* QuicClientSessionCache::Entry::PeekSession() {
  return sessions[0].get();
}

}  // namespace quic
