// 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 "starboard/memory.h"
#include "starboard/types.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
