// 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"


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

static int sock_free(BIO *bio) {
  if (bio->shutdown) {
    if (bio->init) {
      closesocket(bio->num);
    }
    bio->init = 0;
    bio->flags = 0;
  }
  return 1;
}

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

  bio_clear_socket_error();
#if defined(OPENSSL_WINDOWS)
  int ret = recv(b->num, out, outl, 0);
#else
  int ret = (int)read(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(b->num, in, inl, 0);
#else
  int ret = (int)write(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);
      b->num = *static_cast<int *>(ptr);
      b->shutdown = static_cast<int>(num);
      b->init = 1;
      return 1;
    case BIO_C_GET_FD:
      if (b->init) {
        int *out = static_cast<int*>(ptr);
        if (out != nullptr) {
          *out = b->num;
        }
        return b->num;
      }
      return -1;
    case BIO_CTRL_GET_CLOSE:
      return b->shutdown;
    case BIO_CTRL_SET_CLOSE:
      b->shutdown = 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,
    NULL /* puts */, NULL /* gets, */,
    sock_ctrl,       NULL /* create */,
    sock_free,       NULL /* callback_ctrl */,
};

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

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

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

// These functions are provided solely for compatibility with older versions of
// PostgreSQL. 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_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 remain impact, 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 all versions of PostgreSQL we care about are updated or
// patched, remove these functions.

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 method->bputs;
}

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
