// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/bio.h>

#if !defined(OPENSSL_NO_SOCK)

#include <fcntl.h>
#include <string.h>

#if !defined(OPENSSL_WINDOWS)
#include <unistd.h>
#else
#include <winsock2.h>
OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
#endif

#include "internal.h"


using namespace bssl;

#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) { return close(sock); }
#endif

static int sock_free(BIO *bio) {
  if (BIO_get_shutdown(bio)) {
    if (BIO_get_init(bio)) {
      closesocket(FromOpaque(bio)->num);
    }
    BIO_set_init(bio, 0);
    BIO_clear_retry_flags(bio);
  }
  return 1;
}

static int sock_read(BIO *b, char *out, int outl) {
  if (out == nullptr) {
    return 0;
  }

  bio_clear_socket_error();
#if defined(OPENSSL_WINDOWS)
  int ret = recv(FromOpaque(b)->num, out, outl, 0);
#else
  int ret = (int)read(FromOpaque(b)->num, out, outl);
#endif
  BIO_clear_retry_flags(b);
  if (ret <= 0) {
    if (bio_socket_should_retry(ret)) {
      BIO_set_retry_read(b);
    }
  }
  return ret;
}

static int sock_write(BIO *b, const char *in, int inl) {
  bio_clear_socket_error();
#if defined(OPENSSL_WINDOWS)
  int ret = send(FromOpaque(b)->num, in, inl, 0);
#else
  int ret = (int)write(FromOpaque(b)->num, in, inl);
#endif
  BIO_clear_retry_flags(b);
  if (ret <= 0) {
    if (bio_socket_should_retry(ret)) {
      BIO_set_retry_write(b);
    }
  }
  return ret;
}

static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) {
  switch (cmd) {
    case BIO_C_SET_FD:
      sock_free(b);
      FromOpaque(b)->num = *static_cast<int *>(ptr);
      BIO_set_shutdown(b, static_cast<int>(num));
      BIO_set_init(b, 1);
      return 1;
    case BIO_C_GET_FD:
      if (BIO_get_init(b)) {
        int *out = static_cast<int *>(ptr);
        if (out != nullptr) {
          *out = FromOpaque(b)->num;
        }
        return FromOpaque(b)->num;
      }
      return -1;
    case BIO_CTRL_GET_CLOSE:
      return BIO_get_shutdown(b);
    case BIO_CTRL_SET_CLOSE:
      BIO_set_shutdown(b, static_cast<int>(num));
      return 1;
    case BIO_CTRL_FLUSH:
      return 1;
    default:
      return 0;
  }
}

static const BIO_METHOD methods_sockp = {
    BIO_TYPE_SOCKET,
    "socket",
    sock_write,
    sock_read,
    nullptr /* gets, */,
    sock_ctrl,
    nullptr /* create */,
    sock_free,
    nullptr /* callback_ctrl */,
};

const BIO_METHOD *BIO_s_socket() { return &methods_sockp; }

BIO *BIO_new_socket(int fd, int close_flag) {
  BIO *ret;

  ret = BIO_new(BIO_s_socket());
  if (ret == nullptr) {
    return nullptr;
  }
  BIO_set_fd(ret, fd, close_flag);
  return ret;
}

// These functions are provided solely for compatibility with software that
// tries to copy and then modify |BIO_s_socket|. See bio.h for details.
// PostgreSQL's use makes several fragile assumptions on |BIO_s_socket|:
//
// - We do not store anything in |BIO_set_data|. (Broken in upstream OpenSSL,
//   which broke PostgreSQL.)
// - We do not store anything in |BIO_set_app_data|.
// - |BIO_s_socket| is implemented internally using the non-|size_t|-clean
//   I/O functions rather than the |size_t|-clean ones.
// - |BIO_METHOD| never gains another function pointer that is used in concert
//   with any of the functions here.
//
// Some other projects doing similar things use |BIO_meth_get_read| and
// |BIO_meth_get_write| and in turn assume that |BIO_s_socket| has not been
// ported to the |size_t|-clean |BIO_read_ex| and |BIO_write_ex|. (Not yet
// implemented in BoringSSL.)
//
// This is hopelessly fragile. PostgreSQL 18 will include a fix to stop using
// these APIs, but older versions and other software remain impacted, so we
// implement these functions, but only support |BIO_s_socket|. For now they just
// return the underlying functions, but if we ever need to break the above
// assumptions, we can return an older, frozen version of |BIO_s_socket|.
// Limiting to exactly one allowed |BIO_METHOD| lets us do this.
//
// These functions are also deprecated in upstream OpenSSL. See
// https://github.com/openssl/openssl/issues/26047
//
// TODO(davidben): Once Folly and all versions of PostgreSQL we care about are
// updated or patched, remove these functions.

int (*BIO_meth_get_write(const BIO_METHOD *method))(BIO *, const char *, int) {
  BSSL_CHECK(method == BIO_s_socket());
  return method->bwrite;
}

int (*BIO_meth_get_read(const BIO_METHOD *method))(BIO *, char *, int) {
  BSSL_CHECK(method == BIO_s_socket());
  return method->bread;
}

int (*BIO_meth_get_gets(const BIO_METHOD *method))(BIO *, char *, int) {
  BSSL_CHECK(method == BIO_s_socket());
  return method->bgets;
}

int (*BIO_meth_get_puts(const BIO_METHOD *method))(BIO *, const char *) {
  BSSL_CHECK(method == BIO_s_socket());
  return nullptr;
}

long (*BIO_meth_get_ctrl(const BIO_METHOD *method))(BIO *, int, long, void *) {
  BSSL_CHECK(method == BIO_s_socket());
  return method->ctrl;
}

int (*BIO_meth_get_create(const BIO_METHOD *method))(BIO *) {
  BSSL_CHECK(method == BIO_s_socket());
  return method->create;
}

int (*BIO_meth_get_destroy(const BIO_METHOD *method))(BIO *) {
  BSSL_CHECK(method == BIO_s_socket());
  return method->destroy;
}

long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *method))(BIO *, int,
                                                             bio_info_cb) {
  BSSL_CHECK(method == BIO_s_socket());
  return method->callback_ctrl;
}

#endif  // OPENSSL_NO_SOCK
