/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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
 *
 *     http://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.
 *
 */

#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H
#define GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H

#include "src/core/lib/iomgr/resolve_address.h"

#include <sys/socket.h>
#include <unistd.h>

#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/socket_factory_posix.h"
#include "src/core/lib/iomgr/socket_mutator.h"

/* a wrapper for accept or accept4 */
int grpc_accept4(int sockfd, grpc_resolved_address *resolved_addr, int nonblock,
                 int cloexec);

/* set a socket to non blocking mode */
grpc_error *grpc_set_socket_nonblocking(int fd, int non_blocking);

/* set a socket to close on exec */
grpc_error *grpc_set_socket_cloexec(int fd, int close_on_exec);

/* set a socket to reuse old addresses */
grpc_error *grpc_set_socket_reuse_addr(int fd, int reuse);

/* disable nagle */
grpc_error *grpc_set_socket_low_latency(int fd, int low_latency);

/* set SO_REUSEPORT */
grpc_error *grpc_set_socket_reuse_port(int fd, int reuse);

/* Returns true if this system can create AF_INET6 sockets bound to ::1.
   The value is probed once, and cached for the life of the process.

   This is more restrictive than checking for socket(AF_INET6) to succeed,
   because Linux with "net.ipv6.conf.all.disable_ipv6 = 1" is able to create
   and bind IPv6 sockets, but cannot connect to a getsockname() of [::]:port
   without a valid loopback interface.  Rather than expose this half-broken
   state to library users, we turn off IPv6 sockets. */
int grpc_ipv6_loopback_available(void);

/* Tries to set SO_NOSIGPIPE if available on this platform.
   If SO_NO_SIGPIPE is not available, returns 1. */
grpc_error *grpc_set_socket_no_sigpipe_if_possible(int fd);

/* Tries to set IP_PKTINFO if available on this platform.
   If IP_PKTINFO is not available, returns 1. */
grpc_error *grpc_set_socket_ip_pktinfo_if_possible(int fd);

/* Tries to set IPV6_RECVPKTINFO if available on this platform.
   If IPV6_RECVPKTINFO is not available, returns 1. */
grpc_error *grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd);

/* Tries to set the socket's send buffer to given size. */
grpc_error *grpc_set_socket_sndbuf(int fd, int buffer_size_bytes);

/* Tries to set the socket's receive buffer to given size. */
grpc_error *grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes);

/* Tries to set the socket using a grpc_socket_mutator */
grpc_error *grpc_set_socket_with_mutator(int fd, grpc_socket_mutator *mutator);

/* An enum to keep track of IPv4/IPv6 socket modes.

   Currently, this information is only used when a socket is first created, but
   in the future we may wish to store it alongside the fd.  This would let calls
   like sendto() know which family to use without asking the kernel first. */
typedef enum grpc_dualstack_mode {
  /* Uninitialized, or a non-IP socket. */
  GRPC_DSMODE_NONE,
  /* AF_INET only. */
  GRPC_DSMODE_IPV4,
  /* AF_INET6 only, because IPV6_V6ONLY could not be cleared. */
  GRPC_DSMODE_IPV6,
  /* AF_INET6, which also supports ::ffff-mapped IPv4 addresses. */
  GRPC_DSMODE_DUALSTACK
} grpc_dualstack_mode;

/* Only tests should use this flag. */
extern int grpc_forbid_dualstack_sockets_for_testing;

/* Creates a new socket for connecting to (or listening on) an address.

   If addr is AF_INET6, this creates an IPv6 socket first.  If that fails,
   and addr is within ::ffff:0.0.0.0/96, then it automatically falls back to
   an IPv4 socket.

   If addr is AF_INET, AF_UNIX, or anything else, then this is similar to
   calling socket() directly.

   Returns an fd on success, otherwise returns -1 with errno set to the result
   of a failed socket() call.

   The *dsmode output indicates which address family was actually created.
   The recommended way to use this is:
   - First convert to IPv6 using grpc_sockaddr_to_v4mapped().
   - Create the socket.
   - If *dsmode is IPV4, use grpc_sockaddr_is_v4mapped() to convert back to
     IPv4, so that bind() or connect() see the correct family.
   Also, it's important to distinguish between DUALSTACK and IPV6 when
   listening on the [::] wildcard address. */
grpc_error *grpc_create_dualstack_socket(const grpc_resolved_address *addr,
                                         int type, int protocol,
                                         grpc_dualstack_mode *dsmode,
                                         int *newfd);

/* Same as grpc_create_dualstack_socket(), but use the given socket factory (if
   non-null) to create the socket, rather than calling socket() directly. */
grpc_error *grpc_create_dualstack_socket_using_factory(
    grpc_socket_factory *factory, const grpc_resolved_address *addr, int type,
    int protocol, grpc_dualstack_mode *dsmode, int *newfd);

#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H */
