// Copyright 2016 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/socket/socket_bio_adapter.h"

#include <string.h>

#include <algorithm>

#include "base/bind.h"
#include "base/feature_list.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/socket/socket.h"
#include "net/socket/stream_socket.h"
#include "net/ssl/openssl_ssl_util.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "third_party/boringssl/src/include/openssl/bio.h"

namespace {

net::NetworkTrafficAnnotationTag kTrafficAnnotation =
    net::DefineNetworkTrafficAnnotation("socket_bio_adapter", R"(
      semantics {
        sender: "Socket BIO Adapter"
        description:
          "SocketBIOAdapter is used only internal to //net code as an internal "
          "detail to implement a TLS connection for a Socket class, and is not "
          "being called directly outside of this abstraction."
        trigger:
          "Establishing a TLS connection to a remote endpoint. There are many "
          "different ways in which a TLS connection may be triggered, such as "
          "loading an HTTPS URL."
        data:
          "All data sent or received over a TLS connection. This traffic may "
          "either be the handshake or application data. During the handshake, "
          "the target host name, user's IP, data related to previous "
          "handshake, client certificates, and channel ID, may be sent. When "
          "the connection is used to load an HTTPS URL, the application data "
          "includes cookies, request headers, and the response body."
        destination: OTHER
        destination_other:
          "Any destination the implementing socket is connected to."
      }
      policy {
        cookies_allowed: NO
        setting: "This feature cannot be disabled."
        policy_exception_justification: "Essential for navigation."
      })");

}  // namespace

namespace net {

SocketBIOAdapter::SocketBIOAdapter(StreamSocket* socket,
                                   int read_buffer_capacity,
                                   int write_buffer_capacity,
                                   Delegate* delegate)
    : socket_(socket),
      read_buffer_capacity_(read_buffer_capacity),
      read_offset_(0),
      read_result_(0),
      write_buffer_capacity_(write_buffer_capacity),
      write_buffer_used_(0),
      write_error_(OK),
      delegate_(delegate),
      weak_factory_(this) {
  bio_.reset(BIO_new(&kBIOMethod));
  bio_->ptr = this;
  bio_->init = 1;

  read_callback_ = base::BindRepeating(&SocketBIOAdapter::OnSocketReadComplete,
                                       weak_factory_.GetWeakPtr());
  write_callback_ = base::BindRepeating(
      &SocketBIOAdapter::OnSocketWriteComplete, weak_factory_.GetWeakPtr());
}

SocketBIOAdapter::~SocketBIOAdapter() {
  // BIOs are reference-counted and may outlive the adapter. Clear the pointer
  // so future operations fail.
  bio_->ptr = nullptr;
}

bool SocketBIOAdapter::HasPendingReadData() {
  return read_result_ > 0;
}

size_t SocketBIOAdapter::GetAllocationSize() const {
  size_t buffer_size = 0;
  if (read_buffer_)
    buffer_size += read_buffer_capacity_;

  if (write_buffer_)
    buffer_size += write_buffer_capacity_;
  return buffer_size;
}

int SocketBIOAdapter::BIORead(char* out, int len) {
  if (len <= 0)
    return len;

  // If there is no result available synchronously, report any Write() errors
  // that were observed. Otherwise the application may have encountered a socket
  // error while writing that would otherwise not be reported until the
  // application attempted to write again - which it may never do. See
  // https://crbug.com/249848.
  if (write_error_ != OK && write_error_ != ERR_IO_PENDING &&
      (read_result_ == 0 || read_result_ == ERR_IO_PENDING)) {
    OpenSSLPutNetError(FROM_HERE, write_error_);
    return -1;
  }

  if (read_result_ == 0) {
    // Instantiate the read buffer and read from the socket. Although only |len|
    // bytes were requested, intentionally read to the full buffer size. The SSL
    // layer reads the record header and body in separate reads to avoid
    // overreading, but issuing one is more efficient. SSL sockets are not
    // reused after shutdown for non-SSL traffic, so overreading is fine.
    DCHECK(!read_buffer_);
    DCHECK_EQ(0, read_offset_);
    read_buffer_ = base::MakeRefCounted<IOBuffer>(read_buffer_capacity_);
    int result = ERR_READ_IF_READY_NOT_IMPLEMENTED;
    if (base::FeatureList::IsEnabled(Socket::kReadIfReadyExperiment)) {
      result = socket_->ReadIfReady(
          read_buffer_.get(), read_buffer_capacity_,
          base::Bind(&SocketBIOAdapter::OnSocketReadIfReadyComplete,
                     weak_factory_.GetWeakPtr()));
      if (result == ERR_IO_PENDING)
        read_buffer_ = nullptr;
    }
    if (result == ERR_READ_IF_READY_NOT_IMPLEMENTED) {
      result = socket_->Read(read_buffer_.get(), read_buffer_capacity_,
                             read_callback_);
    }
    if (result == ERR_IO_PENDING) {
      read_result_ = ERR_IO_PENDING;
    } else {
      HandleSocketReadResult(result);
    }
  }

  // There is a pending Read(). Inform the caller to retry when it completes.
  if (read_result_ == ERR_IO_PENDING) {
    BIO_set_retry_read(bio());
    return -1;
  }

  // If the last Read() failed, report the error.
  if (read_result_ < 0) {
    OpenSSLPutNetError(FROM_HERE, read_result_);
    return -1;
  }

  // Report the result of the last Read() if non-empty.
  CHECK_LT(read_offset_, read_result_);
  len = std::min(len, read_result_ - read_offset_);
  memcpy(out, read_buffer_->data() + read_offset_, len);
  read_offset_ += len;

  // Release the buffer when empty.
  if (read_offset_ == read_result_) {
    read_buffer_ = nullptr;
    read_offset_ = 0;
    read_result_ = 0;
  }

  return len;
}

void SocketBIOAdapter::HandleSocketReadResult(int result) {
  DCHECK_NE(ERR_IO_PENDING, result);

  // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here, so that higher
  // levels don't report success.
  if (result == 0)
    result = ERR_CONNECTION_CLOSED;

  read_result_ = result;

  // The read buffer is no longer needed.
  if (read_result_ <= 0)
    read_buffer_ = nullptr;
}

void SocketBIOAdapter::OnSocketReadComplete(int result) {
  DCHECK_EQ(ERR_IO_PENDING, read_result_);

  HandleSocketReadResult(result);
  delegate_->OnReadReady();
}

void SocketBIOAdapter::OnSocketReadIfReadyComplete(int result) {
  DCHECK_EQ(ERR_IO_PENDING, read_result_);
  DCHECK_GE(OK, result);

  // Do not use HandleSocketReadResult() because result == OK doesn't mean EOF.
  read_result_ = result;

  delegate_->OnReadReady();
}

int SocketBIOAdapter::BIOWrite(const char* in, int len) {
  if (len <= 0)
    return len;

  // If the write buffer is not empty, there must be a pending Write() to flush
  // it.
  DCHECK(write_buffer_used_ == 0 || write_error_ == ERR_IO_PENDING);

  // If a previous Write() failed, report the error.
  if (write_error_ != OK && write_error_ != ERR_IO_PENDING) {
    OpenSSLPutNetError(FROM_HERE, write_error_);
    return -1;
  }

  // Instantiate the write buffer if needed.
  if (!write_buffer_) {
    DCHECK_EQ(0, write_buffer_used_);
    write_buffer_ = base::MakeRefCounted<GrowableIOBuffer>();
    write_buffer_->SetCapacity(write_buffer_capacity_);
  }

  // If the ring buffer is full, inform the caller to try again later.
  if (write_buffer_used_ == write_buffer_->capacity()) {
    BIO_set_retry_write(bio());
    return -1;
  }

  int bytes_copied = 0;

  // If there is space after the offset, fill it.
  if (write_buffer_used_ < write_buffer_->RemainingCapacity()) {
    int chunk =
        std::min(write_buffer_->RemainingCapacity() - write_buffer_used_, len);
    memcpy(write_buffer_->data() + write_buffer_used_, in, chunk);
    in += chunk;
    len -= chunk;
    bytes_copied += chunk;
    write_buffer_used_ += chunk;
  }

  // If there is still space for remaining data, try to wrap around.
  if (len > 0 && write_buffer_used_ < write_buffer_->capacity()) {
    // If there were any room after the offset, the previous branch would have
    // filled it.
    CHECK_LE(write_buffer_->RemainingCapacity(), write_buffer_used_);
    int write_offset = write_buffer_used_ - write_buffer_->RemainingCapacity();
    int chunk = std::min(len, write_buffer_->capacity() - write_buffer_used_);
    memcpy(write_buffer_->StartOfBuffer() + write_offset, in, chunk);
    in += chunk;
    len -= chunk;
    bytes_copied += chunk;
    write_buffer_used_ += chunk;
  }

  // Either the buffer is now full or there is no more input.
  DCHECK(len == 0 || write_buffer_used_ == write_buffer_->capacity());

  // Schedule a socket Write() if necessary. (The ring buffer may previously
  // have been empty.)
  SocketWrite();

  // If a read-interrupting write error was synchronously discovered,
  // asynchronously notify OnReadReady. See https://crbug.com/249848. Avoid
  // reentrancy by deferring it to a later event loop iteration.
  if (write_error_ != OK && write_error_ != ERR_IO_PENDING &&
      read_result_ == ERR_IO_PENDING) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(&SocketBIOAdapter::CallOnReadReady,
                              weak_factory_.GetWeakPtr()));
  }

  return bytes_copied;
}

void SocketBIOAdapter::SocketWrite() {
  while (write_error_ == OK && write_buffer_used_ > 0) {
    int write_size =
        std::min(write_buffer_used_, write_buffer_->RemainingCapacity());
    int result = socket_->Write(write_buffer_.get(), write_size,
                                write_callback_, kTrafficAnnotation);
    if (result == ERR_IO_PENDING) {
      write_error_ = ERR_IO_PENDING;
      return;
    }

    HandleSocketWriteResult(result);
  }
}

void SocketBIOAdapter::HandleSocketWriteResult(int result) {
  DCHECK_NE(ERR_IO_PENDING, result);

  if (result < 0) {
    write_error_ = result;

    // The write buffer is no longer needed.
    write_buffer_ = nullptr;
    write_buffer_used_ = 0;
    return;
  }

  // Advance the ring buffer.
  write_buffer_->set_offset(write_buffer_->offset() + result);
  write_buffer_used_ -= result;
  if (write_buffer_->RemainingCapacity() == 0)
    write_buffer_->set_offset(0);
  write_error_ = OK;

  // Release the write buffer if empty.
  if (write_buffer_used_ == 0)
    write_buffer_ = nullptr;
}

void SocketBIOAdapter::OnSocketWriteComplete(int result) {
  DCHECK_EQ(ERR_IO_PENDING, write_error_);

  bool was_full = write_buffer_used_ == write_buffer_->capacity();

  HandleSocketWriteResult(result);
  SocketWrite();

  // If transitioning from being unable to accept data to being able to, signal
  // OnWriteReady.
  if (was_full) {
    base::WeakPtr<SocketBIOAdapter> guard(weak_factory_.GetWeakPtr());
    delegate_->OnWriteReady();
    // OnWriteReady may delete the adapter.
    if (!guard)
      return;
  }

  // Write errors are fed back into BIO_read once the read buffer is empty. If
  // BIO_read is currently blocked, signal early that a read result is ready.
  if (result < 0 && read_result_ == ERR_IO_PENDING)
    delegate_->OnReadReady();
}

void SocketBIOAdapter::CallOnReadReady() {
  if (read_result_ == ERR_IO_PENDING)
    delegate_->OnReadReady();
}

SocketBIOAdapter* SocketBIOAdapter::GetAdapter(BIO* bio) {
  DCHECK_EQ(&kBIOMethod, bio->method);
  SocketBIOAdapter* adapter = reinterpret_cast<SocketBIOAdapter*>(bio->ptr);
  if (adapter)
    DCHECK_EQ(bio, adapter->bio());
  return adapter;
}

int SocketBIOAdapter::BIOWriteWrapper(BIO* bio, const char* in, int len) {
  BIO_clear_retry_flags(bio);

  SocketBIOAdapter* adapter = GetAdapter(bio);
  if (!adapter) {
    OpenSSLPutNetError(FROM_HERE, ERR_UNEXPECTED);
    return -1;
  }

  return adapter->BIOWrite(in, len);
}

int SocketBIOAdapter::BIOReadWrapper(BIO* bio, char* out, int len) {
  BIO_clear_retry_flags(bio);

  SocketBIOAdapter* adapter = GetAdapter(bio);
  if (!adapter) {
    OpenSSLPutNetError(FROM_HERE, ERR_UNEXPECTED);
    return -1;
  }

  return adapter->BIORead(out, len);
}

long SocketBIOAdapter::BIOCtrlWrapper(BIO* bio,
                                      int cmd,
                                      long larg,
                                      void* parg) {
  switch (cmd) {
    case BIO_CTRL_FLUSH:
      // The SSL stack requires BIOs handle BIO_flush.
      return 1;
  }

  NOTIMPLEMENTED();
  return 0;
}

const BIO_METHOD SocketBIOAdapter::kBIOMethod = {
    0,        // type (unused)
    nullptr,  // name (unused)
    SocketBIOAdapter::BIOWriteWrapper,
    SocketBIOAdapter::BIOReadWrapper,
    nullptr,  // puts
    nullptr,  // gets
    SocketBIOAdapter::BIOCtrlWrapper,
    nullptr,  // create
    nullptr,  // destroy
    nullptr,  // callback_ctrl
};

}  // namespace net
