// Copyright (c) 2018 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/third_party/quiche/src/quic/core/quic_stream_id_manager.h"

#include "net/third_party/quiche/src/quic/core/quic_connection.h"
#include "net/third_party/quiche/src/quic/core/quic_constants.h"
#include "net/third_party/quiche/src/quic/core/quic_session.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"

namespace quic {

#define ENDPOINT                                                   \
  (session_->perspective() == Perspective::IS_SERVER ? " Server: " \
                                                     : " Client: ")

QuicStreamIdManager::QuicStreamIdManager(
    QuicSession* session,
    QuicStreamId next_outgoing_stream_id,
    QuicStreamId largest_peer_created_stream_id,
    QuicStreamId first_incoming_dynamic_stream_id,
    size_t max_allowed_outgoing_streams,
    size_t max_allowed_incoming_streams)
    : session_(session),
      next_outgoing_stream_id_(next_outgoing_stream_id),
      largest_peer_created_stream_id_(largest_peer_created_stream_id),
      max_allowed_outgoing_stream_id_(0),
      actual_max_allowed_incoming_stream_id_(0),
      advertised_max_allowed_incoming_stream_id_(0),
      max_stream_id_window_(max_allowed_incoming_streams /
                            kMaxStreamIdWindowDivisor),
      max_allowed_incoming_streams_(max_allowed_incoming_streams),
      first_incoming_dynamic_stream_id_(first_incoming_dynamic_stream_id),
      first_outgoing_dynamic_stream_id_(next_outgoing_stream_id) {
  available_incoming_streams_ = max_allowed_incoming_streams_;
  SetMaxOpenOutgoingStreams(max_allowed_outgoing_streams);
  SetMaxOpenIncomingStreams(max_allowed_incoming_streams);
}

QuicStreamIdManager::~QuicStreamIdManager() {
  QUIC_LOG_IF(WARNING,
              session_->num_locally_closed_incoming_streams_highest_offset() >
                  max_allowed_incoming_streams_)
      << "Surprisingly high number of locally closed peer initiated streams"
         "still waiting for final byte offset: "
      << session_->num_locally_closed_incoming_streams_highest_offset();
  QUIC_LOG_IF(WARNING,
              session_->GetNumLocallyClosedOutgoingStreamsHighestOffset() >
                  max_allowed_outgoing_streams_)
      << "Surprisingly high number of locally closed self initiated streams"
         "still waiting for final byte offset: "
      << session_->GetNumLocallyClosedOutgoingStreamsHighestOffset();
}

bool QuicStreamIdManager::OnMaxStreamIdFrame(
    const QuicMaxStreamIdFrame& frame) {
  DCHECK_EQ(QuicUtils::IsBidirectionalStreamId(frame.max_stream_id),
            QuicUtils::IsBidirectionalStreamId(next_outgoing_stream_id_));
  // Need to determine whether the stream id matches our client/server
  // perspective or not. If not, it's an error. If so, update appropriate
  // maxima.
  QUIC_CODE_COUNT_N(max_stream_id_received, 2, 2);
  // TODO(fkastenholz): this test needs to be broader to handle uni- and bi-
  // directional stream ids when that functionality is supported.
  if (IsIncomingStream(frame.max_stream_id)) {
    // TODO(fkastenholz): This, and following, closeConnection may
    // need modification when proper support for IETF CONNECTION
    // CLOSE is done.
    QUIC_CODE_COUNT(max_stream_id_bad_direction);
    session_->connection()->CloseConnection(
        QUIC_MAX_STREAM_ID_ERROR,
        "Recevied max stream ID with wrong initiator bit setting",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return false;
  }

  // If a MAX_STREAM_ID advertises a stream ID that is smaller than previously
  // advertised, it is to be ignored.
  if (frame.max_stream_id < max_allowed_outgoing_stream_id_) {
    QUIC_CODE_COUNT(max_stream_id_ignored);
    return true;
  }
  max_allowed_outgoing_stream_id_ = frame.max_stream_id;

  // Outgoing stream limit has increased, tell the applications
  session_->OnCanCreateNewOutgoingStream();

  return true;
}

bool QuicStreamIdManager::OnStreamIdBlockedFrame(
    const QuicStreamIdBlockedFrame& frame) {
  DCHECK_EQ(QuicUtils::IsBidirectionalStreamId(frame.stream_id),
            QuicUtils::IsBidirectionalStreamId(next_outgoing_stream_id_));
  QUIC_CODE_COUNT_N(stream_id_blocked_received, 2, 2);
  QuicStreamId id = frame.stream_id;
  if (!IsIncomingStream(frame.stream_id)) {
    // Client/server mismatch, close the connection
    // TODO(fkastenholz): revise when proper IETF Connection Close support is
    // done.
    QUIC_CODE_COUNT(stream_id_blocked_bad_direction);
    session_->connection()->CloseConnection(
        QUIC_STREAM_ID_BLOCKED_ERROR,
        "Invalid stream ID directionality specified",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return false;
  }

  if (id > advertised_max_allowed_incoming_stream_id_) {
    // Peer thinks it can send more streams that we've told it.
    // This is a protocol error.
    // TODO(fkastenholz): revise when proper IETF Connection Close support is
    // done.
    QUIC_CODE_COUNT(stream_id_blocked_id_too_big);
    session_->connection()->CloseConnection(
        QUIC_STREAM_ID_BLOCKED_ERROR, "Invalid stream ID specified",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return false;
  }
  if (id < actual_max_allowed_incoming_stream_id_) {
    // Peer thinks it's blocked on an ID that is less than our current
    // max. Inform the peer of the correct stream ID.
    SendMaxStreamIdFrame();
    return true;
  }
  // The peer's notion of the maximum ID is correct,
  // there is nothing to do.
  QUIC_CODE_COUNT(stream_id_blocked_id_correct);
  return true;
}

// TODO(fkastenholz): Many changes will be needed here:
//  -- Use IETF QUIC server/client-initiation sense
//  -- Support both BIDI and UNI streams.
//  -- can not change the max number of streams after config negotiation has
//     been done.
void QuicStreamIdManager::SetMaxOpenOutgoingStreams(size_t max_streams) {
  max_allowed_outgoing_streams_ = max_streams;
  max_allowed_outgoing_stream_id_ =
      next_outgoing_stream_id_ + (max_streams - 1) * kV99StreamIdIncrement;
}

// TODO(fkastenholz): Many changes will be needed here:
//  -- can not change the max number of streams after config negotiation has
//     been done.
//  -- Currently uses the Google Client/server-initiation sense, needs to
//     be IETF.
//  -- Support both BIDI and UNI streams.
//  -- Convert calculation of the maximum ID from Google-QUIC semantics to IETF
//     QUIC semantics.
void QuicStreamIdManager::SetMaxOpenIncomingStreams(size_t max_streams) {
  max_allowed_incoming_streams_ = max_streams;
  // The peer should always believe that it has the negotiated
  // number of stream ids available for use.
  available_incoming_streams_ = max_allowed_incoming_streams_;

  // the window is a fraction of the peer's notion of its stream-id space.
  max_stream_id_window_ =
      available_incoming_streams_ / kMaxStreamIdWindowDivisor;
  if (max_stream_id_window_ == 0) {
    max_stream_id_window_ = 1;
  }

  actual_max_allowed_incoming_stream_id_ =
      first_incoming_dynamic_stream_id_ +
      (max_allowed_incoming_streams_ - 1) * kV99StreamIdIncrement;
  // To start, we can assume advertised and actual are the same.
  advertised_max_allowed_incoming_stream_id_ =
      actual_max_allowed_incoming_stream_id_;
}

void QuicStreamIdManager::MaybeSendMaxStreamIdFrame() {
  if (available_incoming_streams_ > max_stream_id_window_) {
    // window too large, no advertisement
    return;
  }
  // Calculate the number of streams that the peer will believe
  // it has. The "/kV99StreamIdIncrement" converts from stream-id-
  // values to number-of-stream-ids.
  available_incoming_streams_ += (actual_max_allowed_incoming_stream_id_ -
                                  advertised_max_allowed_incoming_stream_id_) /
                                 kV99StreamIdIncrement;
  SendMaxStreamIdFrame();
}

void QuicStreamIdManager::SendMaxStreamIdFrame() {
  advertised_max_allowed_incoming_stream_id_ =
      actual_max_allowed_incoming_stream_id_;
  // And Advertise it.
  session_->SendMaxStreamId(advertised_max_allowed_incoming_stream_id_);
}

void QuicStreamIdManager::OnStreamClosed(QuicStreamId stream_id) {
  DCHECK_EQ(QuicUtils::IsBidirectionalStreamId(stream_id),
            QuicUtils::IsBidirectionalStreamId(next_outgoing_stream_id_));
  if (!IsIncomingStream(stream_id)) {
    // Nothing to do for outbound streams with respect to the
    // stream ID space management.
    return;
  }
  // If the stream is inbound, we can increase the stream ID limit and maybe
  // advertise the new limit to the peer.
  if (actual_max_allowed_incoming_stream_id_ >=
      (kMaxQuicStreamId - kV99StreamIdIncrement)) {
    // Reached the maximum stream id value that the implementation
    // supports. Nothing can be done here.
    return;
  }
  actual_max_allowed_incoming_stream_id_ += kV99StreamIdIncrement;
  MaybeSendMaxStreamIdFrame();
}

QuicStreamId QuicStreamIdManager::GetNextOutgoingStreamId() {
  QUIC_BUG_IF(next_outgoing_stream_id_ > max_allowed_outgoing_stream_id_)
      << "Attempt allocate a new outgoing stream ID would exceed the limit";
  QuicStreamId id = next_outgoing_stream_id_;
  next_outgoing_stream_id_ += kV99StreamIdIncrement;
  return id;
}

bool QuicStreamIdManager::CanOpenNextOutgoingStream() {
  DCHECK_EQ(QUIC_VERSION_99, session_->connection()->transport_version());
  if (next_outgoing_stream_id_ > max_allowed_outgoing_stream_id_) {
    // Next stream ID would exceed the limit, need to inform the peer.
    session_->SendStreamIdBlocked(max_allowed_outgoing_stream_id_);
    QUIC_CODE_COUNT(reached_outgoing_stream_id_limit);
    return false;
  }
  return true;
}

void QuicStreamIdManager::RegisterStaticStream(QuicStreamId stream_id) {
  DCHECK_EQ(QuicUtils::IsBidirectionalStreamId(stream_id),
            QuicUtils::IsBidirectionalStreamId(next_outgoing_stream_id_));
  QuicStreamId first_dynamic_stream_id = stream_id + kV99StreamIdIncrement;

  if (IsIncomingStream(first_dynamic_stream_id)) {
    // This code is predicated on static stream ids being allocated densely, in
    // order, and starting with the first stream allowed. QUIC_BUG if this is
    // not so.
    QUIC_BUG_IF(stream_id > first_incoming_dynamic_stream_id_)
        << "Error in incoming static stream allocation, expected to allocate "
        << first_incoming_dynamic_stream_id_ << " got " << stream_id;

    // This is a stream id for a stream that is started by the peer, deal with
    // the incoming stream ids. Increase the floor and adjust everything
    // accordingly.
    if (stream_id == first_incoming_dynamic_stream_id_) {
      actual_max_allowed_incoming_stream_id_ += kV99StreamIdIncrement;
      first_incoming_dynamic_stream_id_ = first_dynamic_stream_id;
    }
    return;
  }

  // This code is predicated on static stream ids being allocated densely, in
  // order, and starting with the first stream allowed. QUIC_BUG if this is
  // not so.
  QUIC_BUG_IF(stream_id > first_outgoing_dynamic_stream_id_)
      << "Error in outgoing static stream allocation, expected to allocate "
      << first_outgoing_dynamic_stream_id_ << " got " << stream_id;
  // This is a stream id for a stream that is started by this node; deal with
  // the outgoing stream ids. Increase the floor and adjust everything
  // accordingly.
  if (stream_id == first_outgoing_dynamic_stream_id_) {
    max_allowed_outgoing_stream_id_ += kV99StreamIdIncrement;
    first_outgoing_dynamic_stream_id_ = first_dynamic_stream_id;
  }
}

bool QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
    const QuicStreamId stream_id) {
  DCHECK_EQ(QuicUtils::IsBidirectionalStreamId(stream_id),
            QuicUtils::IsBidirectionalStreamId(next_outgoing_stream_id_));
  available_streams_.erase(stream_id);

  if (largest_peer_created_stream_id_ !=
          QuicUtils::GetInvalidStreamId(
              session_->connection()->transport_version()) &&
      stream_id <= largest_peer_created_stream_id_) {
    return true;
  }

  if (stream_id > actual_max_allowed_incoming_stream_id_) {
    // Desired stream ID is larger than the limit, do not increase.
    QUIC_DLOG(INFO) << ENDPOINT
                    << "Failed to create a new incoming stream with id:"
                    << stream_id << ".  Maximum allowed stream id is "
                    << actual_max_allowed_incoming_stream_id_ << ".";
    session_->connection()->CloseConnection(
        QUIC_INVALID_STREAM_ID,
        QuicStrCat("Stream id ", stream_id, " above ",
                   actual_max_allowed_incoming_stream_id_),
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return false;
  }

  available_incoming_streams_--;

  QuicStreamId id = largest_peer_created_stream_id_ + kV99StreamIdIncrement;
  if (largest_peer_created_stream_id_ ==
      QuicUtils::GetInvalidStreamId(
          session_->connection()->transport_version())) {
    // Adjust id based on perspective and whether stream_id is bidirectional or
    // unidirectional.
    if (QuicUtils::IsBidirectionalStreamId(stream_id)) {
      // This should only happen on client side because server bidirectional
      // stream ID manager's largest_peer_created_stream_id_ is initialized to
      // the crypto stream ID.
      DCHECK_EQ(Perspective::IS_CLIENT, session_->perspective());
      id = 1;
    } else {
      id = session_->perspective() == Perspective::IS_SERVER ? 2 : 3;
    }
  }
  for (; id < stream_id; id += kV99StreamIdIncrement) {
    available_streams_.insert(id);
  }
  largest_peer_created_stream_id_ = stream_id;
  return true;
}

bool QuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
  DCHECK_EQ(QuicUtils::IsBidirectionalStreamId(id),
            QuicUtils::IsBidirectionalStreamId(next_outgoing_stream_id_));
  if (!IsIncomingStream(id)) {
    // Stream IDs under next_ougoing_stream_id_ are either open or previously
    // open but now closed.
    return id >= next_outgoing_stream_id_;
  }
  // For peer created streams, we also need to consider available streams.
  return largest_peer_created_stream_id_ ==
             QuicUtils::GetInvalidStreamId(
                 session_->connection()->transport_version()) ||
         id > largest_peer_created_stream_id_ ||
         QuicContainsKey(available_streams_, id);
}

bool QuicStreamIdManager::IsIncomingStream(QuicStreamId id) const {
  DCHECK_EQ(QuicUtils::IsBidirectionalStreamId(id),
            QuicUtils::IsBidirectionalStreamId(next_outgoing_stream_id_));
  return id % kV99StreamIdIncrement !=
         next_outgoing_stream_id_ % kV99StreamIdIncrement;
}

}  // namespace quic
