/*
 *   stunnel       TLS offloading and load-balancing proxy
 *   Copyright (C) 1998-2015 Michal Trojnara <Michal.Trojnara@mirt.net>
 *
 *   This program is free software; you can redistribute it and/or modify it
 *   under the terms of the GNU General Public License as published by the
 *   Free Software Foundation; either version 2 of the License, or (at your
 *   option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *   See the GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License along
 *   with this program; if not, see <http://www.gnu.org/licenses>.
 *
 *   Linking stunnel statically or dynamically with other modules is making
 *   a combined work based on stunnel. Thus, the terms and conditions of
 *   the GNU General Public License cover the whole combination.
 *
 *   In addition, as a special exception, the copyright holder of stunnel
 *   gives you permission to combine stunnel with free software programs or
 *   libraries that are released under the GNU LGPL and with code included
 *   in the standard release of OpenSSL under the OpenSSL License (or
 *   modified versions of such code, with unchanged license). You may copy
 *   and distribute such a system following the terms of the GNU GPL for
 *   stunnel and the licenses of the other code concerned.
 *
 *   Note that people who make modified versions of stunnel are not obligated
 *   to grant this special exception for their modified versions; it is their
 *   choice whether to do so. The GNU General Public License gives permission
 *   to release a modified version without this exception; this exception
 *   also makes it possible to release a modified version which carries
 *   forward this exception.
 */

#include "common.h"
#include "prototypes.h"

#if defined HAVE_PIPE2 && defined HAVE_ACCEPT4
#define USE_NEW_LINUX_API 1
#endif

/* try to use non-POSIX O_NDELAY on obsolete BSD systems */
#if !defined O_NONBLOCK && defined O_NDELAY
#define O_NONBLOCK O_NDELAY
#endif

/**************************************** prototypes */

NOEXPORT SOCKET setup_fd(SOCKET, int, char *);

/**************************************** internal limit of file descriptors */

#ifndef USE_FORK

static SOCKET max_fds;

void get_limits(void) { /* set max_fds and max_clients */
    /* start with current ulimit */
#if defined(HAVE_SYSCONF)
    errno=0;
    max_fds=(SOCKET)sysconf(_SC_OPEN_MAX);
    if(errno)
        ioerror("sysconf");
    if(max_fds<0)
        max_fds=0; /* unlimited */
#elif defined(HAVE_GETRLIMIT)
    struct rlimit rlim;

    if(getrlimit(RLIMIT_NOFILE, &rlim)<0) {
        ioerror("getrlimit");
        max_fds=0; /* unlimited */
    } else
        max_fds=rlim.rlim_cur!=RLIM_INFINITY ? rlim.rlim_cur : 0;
#else
    max_fds=0; /* unlimited */
#endif /* HAVE_SYSCONF || HAVE_GETRLIMIT */

#if !defined(USE_WIN32) && !defined(USE_POLL) && !defined(__INNOTEK_LIBC__)
    /* apply FD_SETSIZE if select() is used on Unix */
    if(!max_fds || max_fds>FD_SETSIZE)
        max_fds=FD_SETSIZE; /* start with select() limit */
#endif /* select() on Unix */

    /* stunnel needs at least 16 file desriptors */
    if(max_fds && max_fds<16)
        max_fds=16;

    if(max_fds) {
        max_clients=(long)(max_fds>=256 ? max_fds*125/256 : (max_fds-6)/2);
        s_log(LOG_DEBUG, "Clients allowed=%ld", max_clients);
    } else {
        max_clients=0;
        s_log(LOG_DEBUG, "No limit detected for the number of clients");
    }
}

#endif

/**************************************** file descriptor validation */

SOCKET s_socket(int domain, int type, int protocol, int nonblock, char *msg) {
    SOCKET fd;

#ifdef USE_NEW_LINUX_API
    if(nonblock)
        type|=SOCK_NONBLOCK;
    type|=SOCK_CLOEXEC;
#endif
#ifdef USE_WIN32
    /* http://stackoverflow.com/questions/4993119 */
    /* CreateProcess() needs a non-overlapped handle */
    fd=WSASocket(domain, type, protocol, NULL, 0, 0);
#else /* USE_WIN32 */
    fd=socket(domain, type, protocol);
#endif /* USE_WIN32 */
    return setup_fd(fd, nonblock, msg);
}

SOCKET s_accept(SOCKET sockfd, struct sockaddr *addr, socklen_t *addrlen,
        int nonblock, char *msg) {
    SOCKET fd;

#ifdef USE_NEW_LINUX_API
    if(nonblock)
        fd=accept4(sockfd, addr, addrlen, SOCK_NONBLOCK|SOCK_CLOEXEC);
    else
        fd=accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);
#else
    fd=accept(sockfd, addr, addrlen);
#endif
    return setup_fd(fd, nonblock, msg);
}

#ifndef USE_WIN32

int s_socketpair(int domain, int type, int protocol, SOCKET sv[2],
        int nonblock, char *msg) {
#ifdef USE_NEW_LINUX_API
    if(nonblock)
        type|=SOCK_NONBLOCK;
    type|=SOCK_CLOEXEC;
#endif
    if(socketpair(domain, type, protocol, sv)<0) {
        ioerror(msg);
        return -1;
    }
    if(setup_fd(sv[0], nonblock, msg)<0) {
        closesocket(sv[1]);
        return -1;
    }
    if(setup_fd(sv[1], nonblock, msg)<0) {
        closesocket(sv[0]);
        return -1;
    }
    return 0;
}

int s_pipe(int pipefd[2], int nonblock, char *msg) {
    int retval;

#ifdef USE_NEW_LINUX_API
    if(nonblock)
        retval=pipe2(pipefd, O_NONBLOCK|O_CLOEXEC);
    else
        retval=pipe2(pipefd, O_CLOEXEC);
#else
    retval=pipe(pipefd);
#endif
    if(retval<0) {
        ioerror(msg);
        return -1;
    }
    if(setup_fd(pipefd[0], nonblock, msg)<0) {
        close(pipefd[1]);
        return -1;
    }
    if(setup_fd(pipefd[1], nonblock, msg)<0) {
        close(pipefd[0]);
        return -1;
    }
    return 0;
}

#endif /* USE_WIN32 */

NOEXPORT SOCKET setup_fd(SOCKET fd, int nonblock, char *msg) {
#if !defined USE_NEW_LINUX_API && defined FD_CLOEXEC
    int err;
#endif

    if(fd==INVALID_SOCKET) {
        sockerror(msg);
        return INVALID_SOCKET;
    }
#ifndef USE_FORK
    if(max_fds && fd>=max_fds) {
        s_log(LOG_ERR, "%s: FD=%d out of range (max %d)",
            msg, (int)fd, (int)max_fds);
        closesocket(fd);
        return INVALID_SOCKET;
    }
#endif

#ifdef USE_NEW_LINUX_API
    (void)nonblock; /* skip warning about unused parameter */
#else /* set O_NONBLOCK and F_SETFD */
    set_nonblock(fd, (unsigned long)nonblock);
#ifdef FD_CLOEXEC
    do {
        err=fcntl(fd, F_SETFD, FD_CLOEXEC);
    } while(err<0 && get_last_socket_error()==S_EINTR);
    if(err<0)
        sockerror("fcntl SETFD"); /* non-critical */
#endif /* FD_CLOEXEC */
#endif /* USE_NEW_LINUX_API */

#ifdef DEBUG_FD_ALLOC
    s_log(LOG_DEBUG, "%s: FD=%d allocated (%sblocking mode)",
        msg, fd, nonblock?"non-":"");
#endif /* DEBUG_FD_ALLOC */

    return fd;
}

void set_nonblock(SOCKET fd, unsigned long nonblock) {
#if defined F_GETFL && defined F_SETFL && defined O_NONBLOCK && !defined __INNOTEK_LIBC__
    int err, flags;

    do {
        flags=fcntl(fd, F_GETFL, 0);
    } while(flags<0 && get_last_socket_error()==S_EINTR);
    if(flags<0) {
        sockerror("fcntl GETFL"); /* non-critical */
        return;
    }
    if(nonblock)
        flags|=O_NONBLOCK;
    else
        flags&=~O_NONBLOCK;
    do {
        err=fcntl(fd, F_SETFL, flags);
    } while(err<0 && get_last_socket_error()==S_EINTR);
    if(err<0)
        sockerror("fcntl SETFL"); /* non-critical */
#else /* WIN32 or similar */
    if(ioctlsocket(fd, (long)FIONBIO, &nonblock)<0)
        sockerror("ioctlsocket"); /* non-critical */
#if 0
    else
        s_log(LOG_DEBUG, "Socket %d set to %s mode",
            fd, nonblock ? "non-blocking" : "blocking");
#endif
#endif
}

/* end of fd.c */
