/*
 * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/ssl.h>

#include <assert.h>
#include <limits.h>
#include <string.h>

#include <algorithm>

#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/rand.h>

#include "../crypto/internal.h"
#include "internal.h"


BSSL_NAMESPACE_BEGIN

// TODO(davidben): 28 comes from the size of IP + UDP header. Is this reasonable
// for these values? Notably, why is kMinMTU a function of the transport
// protocol's overhead rather than, say, what's needed to hold a minimally-sized
// handshake fragment plus protocol overhead.

// kMinMTU is the minimum acceptable MTU value.
static const unsigned int kMinMTU = 256 - 28;

// kDefaultMTU is the default MTU value to use if neither the user nor
// the underlying BIO supplies one.
static const unsigned int kDefaultMTU = 1500 - 28;

// BitRange returns a |uint8_t| with bits |start|, inclusive, to |end|,
// exclusive, set.
static uint8_t BitRange(size_t start, size_t end) {
  assert(start <= end && end <= 8);
  return static_cast<uint8_t>(~((1u << start) - 1) & ((1u << end) - 1));
}

// FirstUnmarkedRangeInByte returns the first unmarked range in bits |b|.
static DTLSMessageBitmap::Range FirstUnmarkedRangeInByte(uint8_t b) {
  size_t start, end;
  for (start = 0; start < 8; start++) {
    if ((b & (1u << start)) == 0) {
      break;
    }
  }
  for (end = start; end < 8; end++) {
    if ((b & (1u << end)) != 0) {
      break;
    }
  }
  return DTLSMessageBitmap::Range{start, end};
}

bool DTLSMessageBitmap::Init(size_t num_bits) {
  if (num_bits + 7 < num_bits) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
    return false;
  }
  size_t num_bytes = (num_bits + 7) / 8;
  size_t bits_rounded = num_bytes * 8;
  if (!bytes_.Init(num_bytes)) {
    return false;
  }
  MarkRange(num_bits, bits_rounded);
  first_unmarked_byte_ = 0;
  return true;
}

void DTLSMessageBitmap::MarkRange(size_t start, size_t end) {
  assert(start <= end);
  // Don't bother touching bytes that have already been marked.
  start = std::max(start, first_unmarked_byte_ << 3);
  // Clamp everything within range.
  start = std::min(start, bytes_.size() << 3);
  end = std::min(end, bytes_.size() << 3);
  if (start >= end) {
    return;
  }

  if ((start >> 3) == (end >> 3)) {
    bytes_[start >> 3] |= BitRange(start & 7, end & 7);
  } else {
    bytes_[start >> 3] |= BitRange(start & 7, 8);
    for (size_t i = (start >> 3) + 1; i < (end >> 3); i++) {
      bytes_[i] = 0xff;
    }
    if ((end & 7) != 0) {
      bytes_[end >> 3] |= BitRange(0, end & 7);
    }
  }

  // Maintain the |first_unmarked_byte_| invariant. This work is amortized
  // across all |MarkRange| calls.
  while (first_unmarked_byte_ < bytes_.size() &&
         bytes_[first_unmarked_byte_] == 0xff) {
    first_unmarked_byte_++;
  }
  // If the whole message is marked, we no longer need to spend memory on the
  // bitmap.
  if (first_unmarked_byte_ >= bytes_.size()) {
    bytes_.Reset();
    first_unmarked_byte_ = 0;
  }
}

DTLSMessageBitmap::Range DTLSMessageBitmap::NextUnmarkedRange(
    size_t start) const {
  // Don't bother looking at bytes that are known to be fully marked.
  start = std::max(start, first_unmarked_byte_ << 3);

  size_t idx = start >> 3;
  if (idx >= bytes_.size()) {
    return Range{0, 0};
  }

  // Look at the bits from |start| up to a byte boundary.
  uint8_t byte = bytes_[idx] | BitRange(0, start & 7);
  if (byte == 0xff) {
    // Nothing unmarked at this byte. Keep searching for an unmarked bit.
    for (idx = idx + 1; idx < bytes_.size(); idx++) {
      if (bytes_[idx] != 0xff) {
        byte = bytes_[idx];
        break;
      }
    }
    if (idx >= bytes_.size()) {
      return Range{0, 0};
    }
  }

  Range range = FirstUnmarkedRangeInByte(byte);
  assert(!range.empty());
  bool should_extend = range.end == 8;
  range.start += idx << 3;
  range.end += idx << 3;
  if (!should_extend) {
    // The range did not end at a byte boundary. We're done.
    return range;
  }

  // Collect all fully unmarked bytes.
  for (idx = idx + 1; idx < bytes_.size(); idx++) {
    if (bytes_[idx] != 0) {
      break;
    }
  }
  range.end = idx << 3;

  // Add any bits from the remaining byte, if any.
  if (idx < bytes_.size()) {
    Range extra = FirstUnmarkedRangeInByte(bytes_[idx]);
    if (extra.start == 0) {
      range.end += extra.end;
    }
  }

  return range;
}

// Receiving handshake messages.

static UniquePtr<DTLSIncomingMessage> dtls_new_incoming_message(
    const struct hm_header_st *msg_hdr) {
  ScopedCBB cbb;
  UniquePtr<DTLSIncomingMessage> frag = MakeUnique<DTLSIncomingMessage>();
  if (!frag) {
    return nullptr;
  }
  frag->type = msg_hdr->type;
  frag->seq = msg_hdr->seq;

  // Allocate space for the reassembled message and fill in the header.
  if (!frag->data.InitForOverwrite(DTLS1_HM_HEADER_LENGTH + msg_hdr->msg_len)) {
    return nullptr;
  }

  if (!CBB_init_fixed(cbb.get(), frag->data.data(), DTLS1_HM_HEADER_LENGTH) ||
      !CBB_add_u8(cbb.get(), msg_hdr->type) ||
      !CBB_add_u24(cbb.get(), msg_hdr->msg_len) ||
      !CBB_add_u16(cbb.get(), msg_hdr->seq) ||
      !CBB_add_u24(cbb.get(), 0 /* frag_off */) ||
      !CBB_add_u24(cbb.get(), msg_hdr->msg_len) ||
      !CBB_finish(cbb.get(), NULL, NULL)) {
    return nullptr;
  }

  if (!frag->reassembly.Init(msg_hdr->msg_len)) {
    return nullptr;
  }

  return frag;
}

// dtls1_is_current_message_complete returns whether the current handshake
// message is complete.
static bool dtls1_is_current_message_complete(const SSL *ssl) {
  size_t idx = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
  DTLSIncomingMessage *frag = ssl->d1->incoming_messages[idx].get();
  return frag != nullptr && frag->reassembly.IsComplete();
}

// dtls1_get_incoming_message returns the incoming message corresponding to
// |msg_hdr|. If none exists, it creates a new one and inserts it in the
// queue. Otherwise, it checks |msg_hdr| is consistent with the existing one. It
// returns NULL on failure. The caller does not take ownership of the result.
static DTLSIncomingMessage *dtls1_get_incoming_message(
    SSL *ssl, uint8_t *out_alert, const struct hm_header_st *msg_hdr) {
  if (msg_hdr->seq < ssl->d1->handshake_read_seq ||
      msg_hdr->seq - ssl->d1->handshake_read_seq >= SSL_MAX_HANDSHAKE_FLIGHT) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return NULL;
  }

  size_t idx = msg_hdr->seq % SSL_MAX_HANDSHAKE_FLIGHT;
  DTLSIncomingMessage *frag = ssl->d1->incoming_messages[idx].get();
  if (frag != NULL) {
    assert(frag->seq == msg_hdr->seq);
    // The new fragment must be compatible with the previous fragments from this
    // message.
    if (frag->type != msg_hdr->type ||  //
        frag->msg_len() != msg_hdr->msg_len) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH);
      *out_alert = SSL_AD_ILLEGAL_PARAMETER;
      return NULL;
    }
    return frag;
  }

  // This is the first fragment from this message.
  ssl->d1->incoming_messages[idx] = dtls_new_incoming_message(msg_hdr);
  if (!ssl->d1->incoming_messages[idx]) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return NULL;
  }
  return ssl->d1->incoming_messages[idx].get();
}

bool dtls1_process_handshake_fragments(SSL *ssl, uint8_t *out_alert,
                                       DTLSRecordNumber record_number,
                                       Span<const uint8_t> record) {
  bool implicit_ack = false;
  bool skipped_fragments = false;
  CBS cbs = record;
  while (CBS_len(&cbs) > 0) {
    // Read a handshake fragment.
    struct hm_header_st msg_hdr;
    CBS body;
    if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD);
      *out_alert = SSL_AD_DECODE_ERROR;
      return false;
    }

    const size_t frag_off = msg_hdr.frag_off;
    const size_t frag_len = msg_hdr.frag_len;
    const size_t msg_len = msg_hdr.msg_len;
    if (frag_off > msg_len || frag_len > msg_len - frag_off) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD);
      *out_alert = SSL_AD_ILLEGAL_PARAMETER;
      return false;
    }

    if (msg_hdr.seq < ssl->d1->handshake_read_seq ||
        ssl->d1->handshake_read_overflow) {
      // Ignore fragments from the past. This is a retransmit of data we already
      // received.
      //
      // TODO(crbug.com/42290594): Use this to drive retransmits.
      continue;
    }

    if (record_number.epoch() != ssl->d1->read_epoch.epoch ||
        ssl->d1->next_read_epoch != nullptr) {
      // New messages can only arrive in the latest epoch. This can fail if the
      // record came from |prev_read_epoch|, or if it came from |read_epoch| but
      // |next_read_epoch| exists. (It cannot come from |next_read_epoch|
      // because |next_read_epoch| becomes |read_epoch| once it receives a
      // record.)
      OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA);
      *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
      return false;
    }

    if (msg_len > ssl_max_handshake_message_len(ssl)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
      *out_alert = SSL_AD_ILLEGAL_PARAMETER;
      return false;
    }

    if (SSL_in_init(ssl) && ssl_has_final_version(ssl) &&
        ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
      // During the handshake, if we receive any portion of the next flight, the
      // peer must have received our most recent flight. In DTLS 1.3, this is an
      // implicit ACK. See RFC 9147, Section 7.1.
      //
      // This only applies during the handshake. After the handshake, the next
      // message may be part of a post-handshake transaction. It also does not
      // apply immediately after the handshake. As a client, receiving a
      // KeyUpdate or NewSessionTicket does not imply the server has received
      // our Finished. The server may have sent those messages in half-RTT.
      implicit_ack = true;
    }

    if (msg_hdr.seq - ssl->d1->handshake_read_seq > SSL_MAX_HANDSHAKE_FLIGHT) {
      // Ignore fragments too far in the future.
      skipped_fragments = true;
      continue;
    }

    DTLSIncomingMessage *frag =
        dtls1_get_incoming_message(ssl, out_alert, &msg_hdr);
    if (frag == nullptr) {
      return false;
    }
    assert(frag->msg_len() == msg_len);

    if (frag->reassembly.IsComplete()) {
      // The message is already assembled.
      continue;
    }
    assert(msg_len > 0);

    // Copy the body into the fragment.
    Span<uint8_t> dest = frag->msg().subspan(frag_off, CBS_len(&body));
    OPENSSL_memcpy(dest.data(), CBS_data(&body), CBS_len(&body));
    frag->reassembly.MarkRange(frag_off, frag_off + frag_len);
  }

  if (implicit_ack) {
    dtls1_stop_timer(ssl);
    dtls_clear_outgoing_messages(ssl);
  }

  if (!skipped_fragments) {
    ssl->d1->records_to_ack.PushBack(record_number);

    if (ssl_has_final_version(ssl) &&
        ssl_protocol_version(ssl) >= TLS1_3_VERSION &&
        !ssl->d1->ack_timer.IsSet() && !ssl->d1->sending_ack) {
      // Schedule sending an ACK. The delay serves several purposes:
      // - If there are more records to come, we send only one ACK.
      // - If there are more records to come and the flight is now complete, we
      //   will send the reply (which implicitly ACKs the previous flight) and
      //   cancel the timer.
      // - If there are more records to come, the flight is now complete, but
      //   generating the response is delayed (e.g. a slow, async private key),
      //   the timer will fire and we send an ACK anyway.
      OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());
      ssl->d1->ack_timer.StartMicroseconds(
          now, uint64_t{ssl->d1->timeout_duration_ms} * 1000 / 4);
    }
  }

  return true;
}

ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed,
                                       uint8_t *out_alert, Span<uint8_t> in) {
  uint8_t type;
  DTLSRecordNumber record_number;
  Span<uint8_t> record;
  auto ret = dtls_open_record(ssl, &type, &record_number, &record, out_consumed,
                              out_alert, in);
  if (ret != ssl_open_record_success) {
    return ret;
  }

  switch (type) {
    case SSL3_RT_APPLICATION_DATA:
      // In DTLS 1.2, out-of-order application data may be received between
      // ChangeCipherSpec and Finished. Discard it.
      return ssl_open_record_discard;

    case SSL3_RT_CHANGE_CIPHER_SPEC:
      if (record.size() != 1u || record[0] != SSL3_MT_CCS) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
        *out_alert = SSL_AD_ILLEGAL_PARAMETER;
        return ssl_open_record_error;
      }

      // We do not support renegotiation, so encrypted ChangeCipherSpec records
      // are illegal.
      if (record_number.epoch() != 0) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
        *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
        return ssl_open_record_error;
      }

      // Ignore ChangeCipherSpec from a previous epoch.
      if (record_number.epoch() != ssl->d1->read_epoch.epoch) {
        return ssl_open_record_discard;
      }

      // Flag the ChangeCipherSpec for later.
      // TODO(crbug.com/42290594): Should we reject this in DTLS 1.3?
      ssl->d1->has_change_cipher_spec = true;
      ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC,
                          record);
      return ssl_open_record_success;

    case SSL3_RT_ACK:
      return dtls1_process_ack(ssl, out_alert, record_number, record);

    case SSL3_RT_HANDSHAKE:
      if (!dtls1_process_handshake_fragments(ssl, out_alert, record_number,
                                             record)) {
        return ssl_open_record_error;
      }
      return ssl_open_record_success;

    default:
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
      *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
      return ssl_open_record_error;
  }
}

bool dtls1_get_message(const SSL *ssl, SSLMessage *out) {
  if (!dtls1_is_current_message_complete(ssl)) {
    return false;
  }

  size_t idx = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
  const DTLSIncomingMessage *frag = ssl->d1->incoming_messages[idx].get();
  out->type = frag->type;
  out->raw = CBS(frag->data);
  out->body = CBS(frag->msg());
  out->is_v2_hello = false;
  if (!ssl->s3->has_message) {
    ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw);
    ssl->s3->has_message = true;
  }
  return true;
}

void dtls1_next_message(SSL *ssl) {
  assert(ssl->s3->has_message);
  assert(dtls1_is_current_message_complete(ssl));
  size_t index = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
  ssl->d1->incoming_messages[index].reset();
  ssl->d1->handshake_read_seq++;
  if (ssl->d1->handshake_read_seq == 0) {
    ssl->d1->handshake_read_overflow = true;
  }
  ssl->s3->has_message = false;
  // If we previously sent a flight, mark it as having a reply, so
  // |on_handshake_complete| can manage post-handshake retransmission.
  if (ssl->d1->outgoing_messages_complete) {
    ssl->d1->flight_has_reply = true;
  }
}

bool dtls_has_unprocessed_handshake_data(const SSL *ssl) {
  size_t current = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
  for (size_t i = 0; i < SSL_MAX_HANDSHAKE_FLIGHT; i++) {
    // Skip the current message.
    if (ssl->s3->has_message && i == current) {
      assert(dtls1_is_current_message_complete(ssl));
      continue;
    }
    if (ssl->d1->incoming_messages[i] != nullptr) {
      return true;
    }
  }
  return false;
}

bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr,
                          CBS *out_body) {
  OPENSSL_memset(out_hdr, 0x00, sizeof(struct hm_header_st));

  if (!CBS_get_u8(cbs, &out_hdr->type) ||
      !CBS_get_u24(cbs, &out_hdr->msg_len) ||
      !CBS_get_u16(cbs, &out_hdr->seq) ||
      !CBS_get_u24(cbs, &out_hdr->frag_off) ||
      !CBS_get_u24(cbs, &out_hdr->frag_len) ||
      !CBS_get_bytes(cbs, out_body, out_hdr->frag_len)) {
    return false;
  }

  return true;
}

ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
                                                uint8_t *out_alert,
                                                Span<uint8_t> in) {
  if (!ssl->d1->has_change_cipher_spec) {
    // dtls1_open_handshake processes both handshake and ChangeCipherSpec.
    auto ret = dtls1_open_handshake(ssl, out_consumed, out_alert, in);
    if (ret != ssl_open_record_success) {
      return ret;
    }
  }
  if (ssl->d1->has_change_cipher_spec) {
    ssl->d1->has_change_cipher_spec = false;
    return ssl_open_record_success;
  }
  return ssl_open_record_discard;
}


// Sending handshake messages.

void dtls_clear_outgoing_messages(SSL *ssl) {
  ssl->d1->outgoing_messages.clear();
  ssl->d1->sent_records = nullptr;
  ssl->d1->outgoing_written = 0;
  ssl->d1->outgoing_offset = 0;
  ssl->d1->outgoing_messages_complete = false;
  ssl->d1->flight_has_reply = false;
  ssl->d1->sending_flight = false;
  dtls_clear_unused_write_epochs(ssl);
}

void dtls_clear_unused_write_epochs(SSL *ssl) {
  ssl->d1->extra_write_epochs.EraseIf(
      [ssl](const UniquePtr<DTLSWriteEpoch> &write_epoch) -> bool {
        // Non-current epochs may be discarded once there are no incomplete
        // outgoing messages that reference them.
        //
        // TODO(crbug.com/42290594): Epoch 1 (0-RTT) should be retained until
        // epoch 3 (app data) is available.
        for (const auto &msg : ssl->d1->outgoing_messages) {
          if (msg.epoch == write_epoch->epoch() && !msg.IsFullyAcked()) {
            return false;
          }
        }
        return true;
      });
}

bool dtls1_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
  // Pick a modest size hint to save most of the |realloc| calls.
  if (!CBB_init(cbb, 64) ||                                   //
      !CBB_add_u8(cbb, type) ||                               //
      !CBB_add_u24(cbb, 0 /* length (filled in later) */) ||  //
      !CBB_add_u16(cbb, ssl->d1->handshake_write_seq) ||      //
      !CBB_add_u24(cbb, 0 /* offset */) ||                    //
      !CBB_add_u24_length_prefixed(cbb, body)) {
    return false;
  }

  return true;
}

bool dtls1_finish_message(const SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg) {
  if (!CBBFinishArray(cbb, out_msg) ||
      out_msg->size() < DTLS1_HM_HEADER_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  // Fix up the header. Copy the fragment length into the total message
  // length.
  OPENSSL_memcpy(out_msg->data() + 1,
                 out_msg->data() + DTLS1_HM_HEADER_LENGTH - 3, 3);
  return true;
}

// add_outgoing adds a new handshake message or ChangeCipherSpec to the current
// outgoing flight. It returns true on success and false on error.
static bool add_outgoing(SSL *ssl, bool is_ccs, Array<uint8_t> data) {
  if (ssl->d1->outgoing_messages_complete) {
    // If we've begun writing a new flight, we received the peer flight. Discard
    // the timer and the our flight.
    dtls1_stop_timer(ssl);
    dtls_clear_outgoing_messages(ssl);
  }

  if (!is_ccs) {
    if (ssl->d1->handshake_write_overflow) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
      return false;
    }
    // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript
    // on hs.
    if (ssl->s3->hs != NULL && !ssl->s3->hs->transcript.Update(data)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return false;
    }
    ssl->d1->handshake_write_seq++;
    if (ssl->d1->handshake_write_seq == 0) {
      ssl->d1->handshake_write_overflow = true;
    }
  }

  DTLSOutgoingMessage msg;
  msg.data = std::move(data);
  msg.epoch = ssl->d1->write_epoch.epoch();
  msg.is_ccs = is_ccs;
  // Zero-length messages need 1 bit to track whether the peer has received the
  // message header. (Normally the message header is implicitly received when
  // any fragment of the message is received at all.)
  if (!is_ccs && !msg.acked.Init(std::max(msg.msg_len(), size_t{1}))) {
    return false;
  }

  // This should not fail if |SSL_MAX_HANDSHAKE_FLIGHT| was sized correctly.
  //
  // TODO(crbug.com/42290594): This can currently fail in DTLS 1.3. The caller
  // can configure how many tickets to send, up to kMaxTickets. Additionally, if
  // we send 0.5-RTT tickets in 0-RTT, we may even have tickets queued up with
  // the server flight.
  if (!ssl->d1->outgoing_messages.TryPushBack(std::move(msg))) {
    assert(false);
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  return true;
}

bool dtls1_add_message(SSL *ssl, Array<uint8_t> data) {
  return add_outgoing(ssl, false /* handshake */, std::move(data));
}

bool dtls1_add_change_cipher_spec(SSL *ssl) {
  // DTLS 1.3 disables compatibility mode, which means that DTLS 1.3 never sends
  // a ChangeCipherSpec message.
  if (ssl_protocol_version(ssl) > TLS1_2_VERSION) {
    return true;
  }
  return add_outgoing(ssl, true /* ChangeCipherSpec */, Array<uint8_t>());
}

// dtls1_update_mtu updates the current MTU from the BIO, ensuring it is above
// the minimum.
static void dtls1_update_mtu(SSL *ssl) {
  // TODO(davidben): No consumer implements |BIO_CTRL_DGRAM_SET_MTU| and the
  // only |BIO_CTRL_DGRAM_QUERY_MTU| implementation could use
  // |SSL_set_mtu|. Does this need to be so complex?
  if (ssl->d1->mtu < dtls1_min_mtu() &&
      !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
    long mtu = BIO_ctrl(ssl->wbio.get(), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
    if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
      ssl->d1->mtu = (unsigned)mtu;
    } else {
      ssl->d1->mtu = kDefaultMTU;
      BIO_ctrl(ssl->wbio.get(), BIO_CTRL_DGRAM_SET_MTU, ssl->d1->mtu, NULL);
    }
  }

  // The MTU should be above the minimum now.
  assert(ssl->d1->mtu >= dtls1_min_mtu());
}

enum seal_result_t {
  seal_error,
  seal_continue,
  seal_flush,
};

// seal_next_record seals one record's worth of messages to |out| and advances
// |ssl|'s internal state past the data that was sealed. If progress was made,
// it returns |seal_flush| or |seal_continue| and sets
// |*out_len| to the number of bytes written.
//
// If the function stopped because the next message could not be combined into
// this record, it returns |seal_continue| and the caller should loop again.
// Otherwise, it returns |seal_flush| and the packet is complete (either because
// there are no more messages or the packet is full).
static seal_result_t seal_next_record(SSL *ssl, Span<uint8_t> out,
                                      size_t *out_len) {
  *out_len = 0;

  // Skip any fully acked messages.
  while (ssl->d1->outgoing_written < ssl->d1->outgoing_messages.size() &&
         ssl->d1->outgoing_messages[ssl->d1->outgoing_written].IsFullyAcked()) {
    ssl->d1->outgoing_offset = 0;
    ssl->d1->outgoing_written++;
  }

  // There was nothing left to write.
  if (ssl->d1->outgoing_written >= ssl->d1->outgoing_messages.size()) {
    return seal_flush;
  }

  const auto &first_msg = ssl->d1->outgoing_messages[ssl->d1->outgoing_written];
  size_t prefix_len = dtls_seal_prefix_len(ssl, first_msg.epoch);
  size_t max_in_len = dtls_seal_max_input_len(ssl, first_msg.epoch, out.size());
  if (max_in_len == 0) {
    // There is no room for a single record.
    return seal_flush;
  }

  if (first_msg.is_ccs) {
    static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
    DTLSRecordNumber record_number;
    if (!dtls_seal_record(ssl, &record_number, out.data(), out_len, out.size(),
                          SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
                          sizeof(kChangeCipherSpec), first_msg.epoch)) {
      return seal_error;
    }

    ssl_do_msg_callback(ssl, /*is_write=*/1, SSL3_RT_CHANGE_CIPHER_SPEC,
                        kChangeCipherSpec);
    ssl->d1->outgoing_offset = 0;
    ssl->d1->outgoing_written++;
    return seal_continue;
  }

  // TODO(crbug.com/374991962): For now, only send one message per record in
  // epoch 0. Sending multiple is allowed and more efficient, but breaks
  // b/378742138.
  const bool allow_multiple_messages = first_msg.epoch != 0;

  // Pack as many handshake fragments into one record as we can. We stage the
  // fragments in the output buffer, to be sealed in-place.
  bool should_continue = false;
  Span<uint8_t> fragments = out.subspan(prefix_len, max_in_len);
  CBB cbb;
  CBB_init_fixed(&cbb, fragments.data(), fragments.size());
  DTLSSentRecord sent_record;
  sent_record.first_msg = ssl->d1->outgoing_written;
  sent_record.first_msg_start = ssl->d1->outgoing_offset;
  while (ssl->d1->outgoing_written < ssl->d1->outgoing_messages.size()) {
    const auto &msg = ssl->d1->outgoing_messages[ssl->d1->outgoing_written];
    if (msg.epoch != first_msg.epoch || msg.is_ccs) {
      // We can only pack messages if the epoch matches. There may be more room
      // in the packet, so tell the caller to keep going.
      should_continue = true;
      break;
    }

    // Decode |msg|'s header.
    CBS cbs(msg.data), body_cbs;
    struct hm_header_st hdr;
    if (!dtls1_parse_fragment(&cbs, &hdr, &body_cbs) ||  //
        hdr.frag_off != 0 ||                             //
        hdr.frag_len != CBS_len(&body_cbs) ||            //
        hdr.msg_len != CBS_len(&body_cbs) ||             //
        CBS_len(&cbs) != 0) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return seal_error;
    }

    // Iterate over every un-acked range in the message, if any.
    Span<const uint8_t> body = body_cbs;
    for (;;) {
      auto range = msg.acked.NextUnmarkedRange(ssl->d1->outgoing_offset);
      if (range.empty()) {
        // Advance to the next message.
        ssl->d1->outgoing_offset = 0;
        ssl->d1->outgoing_written++;
        break;
      }

      // Determine how much progress can be made (minimum one byte of progress).
      size_t capacity = fragments.size() - CBB_len(&cbb);
      if (capacity < DTLS1_HM_HEADER_LENGTH + 1) {
        goto packet_full;
      }
      size_t todo = std::min(range.size(), capacity - DTLS1_HM_HEADER_LENGTH);

      // Empty messages are special-cased in ACK tracking. We act as if they
      // have one byte, but in reality that byte is tracking the header.
      Span<const uint8_t> frag;
      if (!body.empty()) {
        frag = body.subspan(range.start, todo);
      }

      // Assemble the fragment.
      size_t frag_start = CBB_len(&cbb);
      CBB child;
      if (!CBB_add_u8(&cbb, hdr.type) ||                       //
          !CBB_add_u24(&cbb, hdr.msg_len) ||                   //
          !CBB_add_u16(&cbb, hdr.seq) ||                       //
          !CBB_add_u24(&cbb, range.start) ||                   //
          !CBB_add_u24_length_prefixed(&cbb, &child) ||        //
          !CBB_add_bytes(&child, frag.data(), frag.size()) ||  //
          !CBB_flush(&cbb)) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
        return seal_error;
      }
      size_t frag_end = CBB_len(&cbb);

      // TODO(davidben): It is odd that, on output, we inform the caller of
      // retransmits and individual fragments, but on input we only inform the
      // caller of complete messages.
      ssl_do_msg_callback(ssl, /*is_write=*/1, SSL3_RT_HANDSHAKE,
                          fragments.subspan(frag_start, frag_end - frag_start));

      ssl->d1->outgoing_offset = range.start + todo;
      if (todo < range.size()) {
        // The packet was the limiting factor.
        goto packet_full;
      }
    }

    if (!allow_multiple_messages) {
      should_continue = true;
      break;
    }
  }

packet_full:
  sent_record.last_msg = ssl->d1->outgoing_written;
  sent_record.last_msg_end = ssl->d1->outgoing_offset;

  // We could not fit anything. Don't try to make a record.
  if (CBB_len(&cbb) == 0) {
    assert(!should_continue);
    return seal_flush;
  }

  if (!dtls_seal_record(ssl, &sent_record.number, out.data(), out_len,
                        out.size(), SSL3_RT_HANDSHAKE, CBB_data(&cbb),
                        CBB_len(&cbb), first_msg.epoch)) {
    return seal_error;
  }

  // If DTLS 1.3 (or if the version is not yet known and it may be DTLS 1.3),
  // save the record number to match against ACKs later.
  if (ssl->s3->version == 0 || ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    if (ssl->d1->sent_records == nullptr) {
      ssl->d1->sent_records =
          MakeUnique<MRUQueue<DTLSSentRecord, DTLS_MAX_ACK_BUFFER>>();
      if (ssl->d1->sent_records == nullptr) {
        return seal_error;
      }
    }
    ssl->d1->sent_records->PushBack(sent_record);
  }

  return should_continue ? seal_continue : seal_flush;
}

// seal_next_packet writes as much of the next flight as possible to |out| and
// advances |ssl->d1->outgoing_written| and |ssl->d1->outgoing_offset| as
// appropriate.
static bool seal_next_packet(SSL *ssl, Span<uint8_t> out, size_t *out_len) {
  size_t total = 0;
  for (;;) {
    size_t len;
    seal_result_t ret = seal_next_record(ssl, out, &len);
    switch (ret) {
      case seal_error:
        return false;

      case seal_flush:
      case seal_continue:
        out = out.subspan(len);
        total += len;
        break;
    }

    if (ret == seal_flush) {
      break;
    }
  }

  *out_len = total;
  return true;
}

static int send_flight(SSL *ssl) {
  if (ssl->s3->write_shutdown != ssl_shutdown_none) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
    return -1;
  }

  if (ssl->wbio == nullptr) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
    return -1;
  }

  if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED);
    return -1;
  }

  dtls1_update_mtu(ssl);

  Array<uint8_t> packet;
  if (!packet.InitForOverwrite(ssl->d1->mtu)) {
    return -1;
  }

  while (ssl->d1->outgoing_written < ssl->d1->outgoing_messages.size()) {
    uint8_t old_written = ssl->d1->outgoing_written;
    uint32_t old_offset = ssl->d1->outgoing_offset;

    size_t packet_len;
    if (!seal_next_packet(ssl, MakeSpan(packet), &packet_len)) {
      return -1;
    }

    if (packet_len == 0 &&
        ssl->d1->outgoing_written < ssl->d1->outgoing_messages.size()) {
      // We made no progress with the packet size available, but did not reach
      // the end.
      OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL);
      return false;
    }

    if (packet_len != 0) {
      int bio_ret = BIO_write(ssl->wbio.get(), packet.data(), packet_len);
      if (bio_ret <= 0) {
        // Retry this packet the next time around.
        ssl->d1->outgoing_written = old_written;
        ssl->d1->outgoing_offset = old_offset;
        ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
        return bio_ret;
      }
    }
  }

  if (BIO_flush(ssl->wbio.get()) <= 0) {
    ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
    return -1;
  }

  return 1;
}

void dtls1_finish_flight(SSL *ssl) {
  if (ssl->d1->outgoing_messages.empty() ||
      ssl->d1->outgoing_messages_complete) {
    return;  // Nothing to do.
  }

  if (ssl->d1->outgoing_messages[0].epoch <= 2) {
    // DTLS 1.3 handshake messages (epoch 2 and below) implicitly ACK the
    // previous flight, so there is no need to ACK previous records. This
    // clears the ACK buffer slightly earlier than the specification suggests.
    // See the discussion in
    // https://mailarchive.ietf.org/arch/msg/tls/kjJnquJOVaWxu5hUCmNzB35eqY0/
    ssl->d1->records_to_ack.Clear();
    ssl->d1->ack_timer.Stop();
    ssl->d1->sending_ack = false;
  }

  ssl->d1->outgoing_messages_complete = true;
  ssl->d1->sending_flight = true;
  // Stop retransmitting the previous flight. In DTLS 1.3, we'll have stopped
  // the timer already, but DTLS 1.2 keeps it running until the next flight is
  // ready.
  dtls1_stop_timer(ssl);
}

void dtls1_schedule_ack(SSL *ssl) {
  ssl->d1->ack_timer.Stop();
  ssl->d1->sending_ack = !ssl->d1->records_to_ack.empty();
}

static int send_ack(SSL *ssl) {
  assert(ssl_protocol_version(ssl) >= TLS1_3_VERSION);

  // Ensure we don't send so many ACKs that we overflow the MTU. There is a
  // 2-byte length prefix and each ACK is 16 bytes.
  dtls1_update_mtu(ssl);
  size_t max_plaintext =
      dtls_seal_max_input_len(ssl, ssl->d1->write_epoch.epoch(), ssl->d1->mtu);
  if (max_plaintext < 2 + 16) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL);  // No room for even one ACK.
    return -1;
  }
  size_t num_acks =
      std::min((max_plaintext - 2) / 16, ssl->d1->records_to_ack.size());

  // Assemble the ACK. RFC 9147 says to sort ACKs numerically. It is unclear if
  // other implementations do this, but go ahead and sort for now. See
  // https://mailarchive.ietf.org/arch/msg/tls/kjJnquJOVaWxu5hUCmNzB35eqY0/.
  // Remove this if rfc9147bis removes this requirement.
  InplaceVector<DTLSRecordNumber, DTLS_MAX_ACK_BUFFER> sorted;
  for (size_t i = ssl->d1->records_to_ack.size() - num_acks;
       i < ssl->d1->records_to_ack.size(); i++) {
    sorted.PushBack(ssl->d1->records_to_ack[i]);
  }
  std::sort(sorted.begin(), sorted.end());

  uint8_t buf[2 + 16 * DTLS_MAX_ACK_BUFFER];
  CBB cbb, child;
  CBB_init_fixed(&cbb, buf, sizeof(buf));
  BSSL_CHECK(CBB_add_u16_length_prefixed(&cbb, &child));
  for (const auto &number : sorted) {
    BSSL_CHECK(CBB_add_u64(&child, number.epoch()));
    BSSL_CHECK(CBB_add_u64(&child, number.sequence()));
  }
  BSSL_CHECK(CBB_flush(&cbb));

  // Encrypt it.
  uint8_t record[DTLS1_3_RECORD_HEADER_WRITE_LENGTH + sizeof(buf) +
                 1 /* record type */ + EVP_AEAD_MAX_OVERHEAD];
  size_t record_len;
  DTLSRecordNumber record_number;
  if (!dtls_seal_record(ssl, &record_number, record, &record_len,
                        sizeof(record), SSL3_RT_ACK, CBB_data(&cbb),
                        CBB_len(&cbb), ssl->d1->write_epoch.epoch())) {
    return -1;
  }

  ssl_do_msg_callback(ssl, /*is_write=*/1, SSL3_RT_ACK,
                      MakeConstSpan(CBB_data(&cbb), CBB_len(&cbb)));

  int bio_ret =
      BIO_write(ssl->wbio.get(), record, static_cast<int>(record_len));
  if (bio_ret <= 0) {
    ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
    return bio_ret;
  }

  if (BIO_flush(ssl->wbio.get()) <= 0) {
    ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
    return -1;
  }

  return 1;
}

int dtls1_flush(SSL *ssl) {
  // Send the pending ACK, if any.
  if (ssl->d1->sending_ack) {
    int ret = send_ack(ssl);
    if (ret <= 0) {
      return ret;
    }
    ssl->d1->sending_ack = false;
  }

  // Send the pending flight, if any.
  if (ssl->d1->sending_flight) {
    int ret = send_flight(ssl);
    if (ret <= 0) {
      return ret;
    }

    // Reset state for the next send.
    ssl->d1->outgoing_written = 0;
    ssl->d1->outgoing_offset = 0;
    ssl->d1->sending_flight = false;

    // Schedule the next retransmit timer. In DTLS 1.3, we retransmit all
    // flights until ACKed. In DTLS 1.2, the final Finished flight is never
    // ACKed, so we do not keep the timer running after the handshake.
    if (SSL_in_init(ssl) || ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
      if (ssl->d1->num_timeouts == 0) {
        ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms;
      } else {
        ssl->d1->timeout_duration_ms =
            std::min(ssl->d1->timeout_duration_ms * 2, uint32_t{60000});
      }

      OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());
      ssl->d1->retransmit_timer.StartMicroseconds(
          now, uint64_t{ssl->d1->timeout_duration_ms} * 1000);
    }
  }

  return 1;
}

unsigned int dtls1_min_mtu(void) { return kMinMTU; }

BSSL_NAMESPACE_END
