/*
 *   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.
 */

#if defined(_WIN32) || defined(_WIN32_WCE)
/* bypass automatic index bound checks in the FD_SET() macro */
#define FD_SETSIZE 1000000
#endif

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

/* #define DEBUG_UCONTEXT */

NOEXPORT void s_poll_realloc(s_poll_set *);
NOEXPORT int get_socket_error(const SOCKET);

/**************************************** s_poll functions */

#ifdef USE_POLL

s_poll_set *s_poll_alloc() {
    /* it needs to be filled with zeros */
    return str_alloc(sizeof(s_poll_set));
}

void s_poll_free(s_poll_set *fds) {
    if(fds) {
        str_free(fds->ufds);
        str_free(fds);
    }
}

void s_poll_init(s_poll_set *fds) {
    fds->nfds=0;
    fds->allocated=4; /* prealloc 4 file desciptors */
    s_poll_realloc(fds);
}

void s_poll_add(s_poll_set *fds, SOCKET fd, int rd, int wr) {
    unsigned i;

    for(i=0; i<fds->nfds && fds->ufds[i].fd!=fd; i++)
        ;
    if(i==fds->nfds) { /* not found */
        if(i==fds->allocated) {
            fds->allocated=i+1;
            s_poll_realloc(fds);
        }
        fds->ufds[i].fd=fd;
        fds->ufds[i].events=0;
        fds->nfds++;
    }
    if(rd) {
        fds->ufds[i].events|=POLLIN;
#ifdef POLLRDHUP
        fds->ufds[i].events|=POLLRDHUP;
#endif
    }
    if(wr)
        fds->ufds[i].events|=POLLOUT;
}

void s_poll_remove(s_poll_set *fds, SOCKET fd) {
    unsigned i;

    for(i=0; i<fds->nfds && fds->ufds[i].fd!=fd; i++)
        ;
    if(i<fds->nfds) { /* found */
        memmove(fds->ufds+i, fds->ufds+i+1,
            (fds->nfds-i-1)*sizeof(struct pollfd));
        fds->nfds--;
    }
}

int s_poll_canread(s_poll_set *fds, SOCKET fd) {
    unsigned i;

    for(i=0; i<fds->nfds; i++)
        if(fds->ufds[i].fd==fd)
            return fds->ufds[i].revents&(POLLIN|POLLERR);
    return 0; /* not listed in fds */
}

int s_poll_canwrite(s_poll_set *fds, SOCKET fd) {
    unsigned i;

    for(i=0; i<fds->nfds; i++)
        if(fds->ufds[i].fd==fd)
            return fds->ufds[i].revents&(POLLOUT|POLLERR);
    return 0; /* not listed in fds */
}

/* best doc: http://lxr.free-electrons.com/source/net/ipv4/tcp.c#L456 */

int s_poll_hup(s_poll_set *fds, SOCKET fd) {
    unsigned i;

    for(i=0; i<fds->nfds; i++)
        if(fds->ufds[i].fd==fd)
            return fds->ufds[i].revents&POLLHUP; /* read and write closed */
    return 0; /* not listed in fds */
}

int s_poll_rdhup(s_poll_set *fds, SOCKET fd) {
    unsigned i;

    for(i=0; i<fds->nfds; i++)
        if(fds->ufds[i].fd==fd)
#ifdef POLLRDHUP
            return fds->ufds[i].revents&POLLRDHUP; /* read closed */
#else
            return fds->ufds[i].revents&POLLHUP; /* read and write closed */
#endif
    return 0; /* not listed in fds */
}

NOEXPORT void s_poll_realloc(s_poll_set *fds) {
    fds->ufds=str_realloc(fds->ufds, fds->allocated*sizeof(struct pollfd));
}

void s_poll_dump(s_poll_set *fds, int level) {
    unsigned i;

    for(i=0; i<fds->nfds; i++)
        s_log(level, "fd=%d events=0x%X revents=0x%X",
            fds->ufds[i].fd, fds->ufds[i].events, fds->ufds[i].revents);
}

#ifdef USE_UCONTEXT

/* move ready contexts from waiting queue to ready queue */
NOEXPORT void scan_waiting_queue(void) {
    int retval;
    CONTEXT *context, *prev;
    int min_timeout;
    unsigned nfds, i;
    time_t now;
    static unsigned max_nfds=0;
    static struct pollfd *ufds=NULL;

    time(&now);
    /* count file descriptors */
    min_timeout=-1; /* infinity */
    nfds=0;
    for(context=waiting_head; context; context=context->next) {
        nfds+=context->fds->nfds;
        if(context->finish>=0) /* finite time */
            if(min_timeout<0 || min_timeout>context->finish-now)
                min_timeout=
                    (int)(context->finish-now<0 ? 0 : context->finish-now);
    }
    /* setup ufds structure */
    if(nfds>max_nfds) { /* need to allocate more memory */
        ufds=str_realloc(ufds, nfds*sizeof(struct pollfd));
        max_nfds=nfds;
    }
    nfds=0;
    for(context=waiting_head; context; context=context->next)
        for(i=0; i<context->fds->nfds; i++) {
            ufds[nfds].fd=context->fds->ufds[i].fd;
            ufds[nfds].events=context->fds->ufds[i].events;
            nfds++;
        }

#ifdef DEBUG_UCONTEXT
    s_log(LOG_DEBUG, "Waiting %d second(s) for %d file descriptor(s)",
        min_timeout, nfds);
#endif
    do { /* skip "Interrupted system call" errors */
        retval=poll(ufds, nfds, min_timeout<0 ? -1 : 1000*min_timeout);
    } while(retval<0 && get_last_socket_error()==S_EINTR);
    time(&now);
    /* process the returned data */
    nfds=0;
    prev=NULL; /* previous element of the waiting queue */
    context=waiting_head;
    while(context) {
        context->ready=0;
        /* count ready file descriptors in each context */
        for(i=0; i<context->fds->nfds; i++) {
            context->fds->ufds[i].revents=ufds[nfds].revents;
#ifdef DEBUG_UCONTEXT
            s_log(LOG_DEBUG, "CONTEXT %ld, FD=%d,%s%s ->%s%s%s%s%s",
                context->id, ufds[nfds].fd,
                ufds[nfds].events & POLLIN ? " IN" : "",
                ufds[nfds].events & POLLOUT ? " OUT" : "",
                ufds[nfds].revents & POLLIN ? " IN" : "",
                ufds[nfds].revents & POLLOUT ? " OUT" : "",
                ufds[nfds].revents & POLLERR ? " ERR" : "",
                ufds[nfds].revents & POLLHUP ? " HUP" : "",
                ufds[nfds].revents & POLLNVAL ? " NVAL" : "");
#endif
            if(ufds[nfds].revents)
                context->ready++;
            nfds++;
        }
        if(context->ready || (context->finish>=0 && context->finish<=now)) {
            /* remove context from the waiting queue */
            if(prev)
                prev->next=context->next;
            else
                waiting_head=context->next;
            if(!context->next) /* same as context==waiting_tail */
                waiting_tail=prev;

            /* append context context to the ready queue */
            context->next=NULL;
            if(ready_tail)
                ready_tail->next=context;
            ready_tail=context;
            if(!ready_head)
                ready_head=context;
        } else { /* leave the context context in the waiting queue */
            prev=context;
        }
        context=prev ? prev->next : waiting_head;
    }
}

int s_poll_wait(s_poll_set *fds, int sec, int msec) {
    CONTEXT *context; /* current context */
    static CONTEXT *to_free=NULL; /* delayed memory deallocation */

    /* FIXME: msec parameter is currently ignored with UCONTEXT threads */
    (void)msec; /* skip warning about unused parameter */

    /* remove the current context from ready queue */
    context=ready_head;
    ready_head=ready_head->next;
    if(!ready_head) /* the queue is empty */
        ready_tail=NULL;
    /* it is safe to s_log() after new ready_head is set */

    /* it is illegal to deallocate the stack of the current context */
    if(to_free) { /* a delayed deallocation is scheduled */
#ifdef DEBUG_UCONTEXT
        s_log(LOG_DEBUG, "Releasing context %ld", to_free->id);
#endif
        str_free(to_free->stack);
        str_free(to_free);
        to_free=NULL;
    }

    /* manage the current thread */
    if(fds) { /* something to wait for -> swap the context */
        context->fds=fds; /* set file descriptors to wait for */
        context->finish=sec<0 ? -1 : time(NULL)+sec;

        /* append the current context to the waiting queue */
        context->next=NULL;
        if(waiting_tail)
            waiting_tail->next=context;
        waiting_tail=context;
        if(!waiting_head)
            waiting_head=context;
    } else { /* nothing to wait for -> drop the context */
        to_free=context; /* schedule for delayed deallocation */
    }

    while(!ready_head) /* wait until there is a thread to switch to */
        scan_waiting_queue();

    /* switch threads */
    if(fds) { /* swap the current context */
        if(context->id!=ready_head->id) {
#ifdef DEBUG_UCONTEXT
            s_log(LOG_DEBUG, "Context swap: %ld -> %ld",
                context->id, ready_head->id);
#endif
            swapcontext(&context->context, &ready_head->context);
#ifdef DEBUG_UCONTEXT
            s_log(LOG_DEBUG, "Current context: %ld", ready_head->id);
#endif
        }
        return ready_head->ready;
    } else { /* drop the current context */
#ifdef DEBUG_UCONTEXT
        s_log(LOG_DEBUG, "Context set: %ld (dropped) -> %ld",
            context->id, ready_head->id);
#endif
        setcontext(&ready_head->context);
        ioerror("setcontext"); /* should not ever happen */
        return 0;
    }
}

#else /* USE_UCONTEXT */

int s_poll_wait(s_poll_set *fds, int sec, int msec) {
    int retval;

    do { /* skip "Interrupted system call" errors */
        retval=poll(fds->ufds, fds->nfds, sec<0 ? -1 : 1000*sec+msec);
    } while(retval<0 && get_last_socket_error()==S_EINTR);
    return retval;
}

#endif /* USE_UCONTEXT */

#else /* select */

s_poll_set *s_poll_alloc() {
    /* it needs to be filled with zeros */
    return str_alloc(sizeof(s_poll_set));
}

void s_poll_free(s_poll_set *fds) {
    if(fds) {
        str_free(fds->irfds);
        str_free(fds->iwfds);
        str_free(fds->ixfds);
        str_free(fds->orfds);
        str_free(fds->owfds);
        str_free(fds->oxfds);
        str_free(fds);
    }
}

void s_poll_init(s_poll_set *fds) {
#ifdef USE_WIN32
    fds->allocated=4; /* prealloc 4 file desciptors */
#endif
    s_poll_realloc(fds);
    FD_ZERO(fds->irfds);
    FD_ZERO(fds->iwfds);
    FD_ZERO(fds->ixfds);
    fds->max=0; /* no file descriptors */
}

void s_poll_add(s_poll_set *fds, SOCKET fd, int rd, int wr) {
#ifdef USE_WIN32
    /* fds->ixfds contains union of fds->irfds and fds->iwfds */
    if(fds->ixfds->fd_count>=fds->allocated) {
        fds->allocated=fds->ixfds->fd_count+1;
        s_poll_realloc(fds);
    }
#endif
    if(rd)
        FD_SET(fd, fds->irfds);
    if(wr)
        FD_SET(fd, fds->iwfds);
    /* always expect errors (and the Spanish Inquisition) */
    FD_SET(fd, fds->ixfds);
    if(fd>fds->max)
        fds->max=fd;
}

void s_poll_remove(s_poll_set *fds, SOCKET fd) {
    FD_CLR(fd, fds->irfds);
    FD_CLR(fd, fds->iwfds);
    FD_CLR(fd, fds->ixfds);
}

int s_poll_canread(s_poll_set *fds, SOCKET fd) {
    return FD_ISSET(fd, fds->orfds) || FD_ISSET(fd, fds->oxfds);
}

int s_poll_canwrite(s_poll_set *fds, SOCKET fd) {
    return FD_ISSET(fd, fds->owfds) || FD_ISSET(fd, fds->oxfds);
}

int s_poll_hup(s_poll_set *fds, SOCKET fd) {
    (void)fds; /* skip warning about unused parameter */
    (void)fd; /* skip warning about unused parameter */
    return 0; /* FIXME: how to detect HUP condition with select()? */
}

int s_poll_rdhup(s_poll_set *fds, SOCKET fd) {
    (void)fds; /* skip warning about unused parameter */
    (void)fd; /* skip warning about unused parameter */
    return 0; /* FIXME: how to detect RDHUP condition with select()? */
}

#ifdef USE_WIN32
#define FD_SIZE(fds) (sizeof(u_int)+(fds)->allocated*sizeof(SOCKET))
#else
#define FD_SIZE(fds) (sizeof(fd_set))
#endif

int s_poll_wait(s_poll_set *fds, int sec, int msec) {
    int retval;
    struct timeval tv, *tv_ptr;

    do { /* skip "Interrupted system call" errors */
        memcpy(fds->orfds, fds->irfds, FD_SIZE(fds));
        memcpy(fds->owfds, fds->iwfds, FD_SIZE(fds));
        memcpy(fds->oxfds, fds->ixfds, FD_SIZE(fds));
        if(sec<0) { /* infinite timeout */
            tv_ptr=NULL;
        } else {
            tv.tv_sec=sec;
            tv.tv_usec=1000*msec;
            tv_ptr=&tv;
        }
        retval=select((int)fds->max+1,
            fds->orfds, fds->owfds, fds->oxfds, tv_ptr);
    } while(retval<0 && get_last_socket_error()==S_EINTR);
    return retval;
}

NOEXPORT void s_poll_realloc(s_poll_set *fds) {
    fds->irfds=str_realloc(fds->irfds, FD_SIZE(fds));
    fds->iwfds=str_realloc(fds->iwfds, FD_SIZE(fds));
    fds->ixfds=str_realloc(fds->ixfds, FD_SIZE(fds));
    fds->orfds=str_realloc(fds->orfds, FD_SIZE(fds));
    fds->owfds=str_realloc(fds->owfds, FD_SIZE(fds));
    fds->oxfds=str_realloc(fds->oxfds, FD_SIZE(fds));
}

void s_poll_dump(s_poll_set *fds, int level) {
    SOCKET fd;
    int ir, iw, ix, or, ow, ox;

    for(fd=0; fd<fds->max; fd++) {
        ir=FD_ISSET(fd, fds->irfds);
        iw=FD_ISSET(fd, fds->iwfds);
        ix=FD_ISSET(fd, fds->ixfds);
        or=FD_ISSET(fd, fds->orfds);
        ow=FD_ISSET(fd, fds->owfds);
        ox=FD_ISSET(fd, fds->oxfds);
        if(ir || iw || ix || or || ow || ox)
            s_log(level, "fd=%d ifds=%c%c%c ofds=%c%c%c", fd,
                ir?'r':'-', iw?'w':'-', ix?'x':'-',
                or?'r':'-', ow?'w':'-', ox?'x':'-');
    }
}

#endif /* USE_POLL */

/**************************************** fd management */

int set_socket_options(SOCKET s, int type) {
    SOCK_OPT *ptr;
    extern SOCK_OPT sock_opts[];
    static char *type_str[3]={"accept", "local", "remote"};
    socklen_t opt_size;
    int retval=0; /* no error found */

    for(ptr=sock_opts; ptr->opt_str; ptr++) {
        if(!ptr->opt_val[type])
            continue; /* default */
        switch(ptr->opt_type) {
        case TYPE_LINGER:
            opt_size=sizeof(struct linger);
            break;
        case TYPE_TIMEVAL:
            opt_size=sizeof(struct timeval);
            break;
        case TYPE_STRING:
            opt_size=(socklen_t)strlen(ptr->opt_val[type]->c_val)+1;
            break;
        default:
            opt_size=sizeof(int);
        }
        if(setsockopt(s, ptr->opt_level, ptr->opt_name,
                (void *)ptr->opt_val[type], opt_size)) {
            if(get_last_socket_error()==S_EOPNOTSUPP) {
                /* most likely stdin/stdout or AF_UNIX socket */
                s_log(LOG_DEBUG,
                    "Option %s not supported on %s socket",
                    ptr->opt_str, type_str[type]);
            } else {
                sockerror(ptr->opt_str);
                retval=-1; /* failed to set this option */
            }
        }
#ifdef DEBUG_FD_ALLOC
        else {
            s_log(LOG_DEBUG, "Option %s set on %s socket",
                ptr->opt_str, type_str[type]);
        }
#endif /* DEBUG_FD_ALLOC */
    }
    return retval; /* returns 0 when all options succeeded */
}

NOEXPORT int get_socket_error(const SOCKET fd) {
    int err;
    socklen_t optlen=sizeof err;

    if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&err, &optlen))
        err=get_last_socket_error(); /* failed -> ask why */
    return err==S_ENOTSOCK ? 0 : err;
}

/**************************************** simulate blocking I/O */

int s_connect(CLI *c, SOCKADDR_UNION *addr, socklen_t addrlen) {
    int error;
    char *dst;

    dst=s_ntop(addr, addrlen);
    s_log(LOG_INFO, "s_connect: connecting %s", dst);

    if(!connect(c->fd, &addr->sa, addrlen)) {
        s_log(LOG_INFO, "s_connect: connected %s", dst);
        str_free(dst);
        return 0; /* no error -> success (on some OSes over the loopback) */
    }
    error=get_last_socket_error();
    if(error!=S_EINPROGRESS && error!=S_EWOULDBLOCK) {
        s_log(LOG_ERR, "s_connect: connect %s: %s (%d)",
            dst, s_strerror(error), error);
        str_free(dst);
        return -1;
    }

    s_log(LOG_DEBUG, "s_connect: s_poll_wait %s: waiting %d seconds",
        dst, c->opt->timeout_connect);
    s_poll_init(c->fds);
    s_poll_add(c->fds, c->fd, 1, 1);
    switch(s_poll_wait(c->fds, c->opt->timeout_connect, 0)) {
    case -1:
        error=get_last_socket_error();
        s_log(LOG_ERR, "s_connect: s_poll_wait %s: %s (%d)",
            dst, s_strerror(error), error);
        str_free(dst);
        return -1;
    case 0:
        s_log(LOG_ERR, "s_connect: s_poll_wait %s:"
            " TIMEOUTconnect exceeded", dst);
        str_free(dst);
        return -1;
    default:
        error=get_socket_error(c->fd);
        if(error) {
            s_log(LOG_ERR, "s_connect: connect %s: %s (%d)",
               dst, s_strerror(error), error);
            str_free(dst);
            return -1;
        }
        if(s_poll_canwrite(c->fds, c->fd)) {
            s_log(LOG_NOTICE, "s_connect: connected %s", dst);
            str_free(dst);
            return 0; /* success */
        }
        s_log(LOG_ERR, "s_connect: s_poll_wait %s: internal error",
            dst);
        str_free(dst);
        return -1;
    }
    return -1; /* should not be possible */
}

void s_write(CLI *c, SOCKET fd, const void *buf, size_t len) {
        /* simulate a blocking write */
    uint8_t *ptr=(uint8_t *)buf;
    ssize_t num;

    while(len>0) {
        s_poll_init(c->fds);
        s_poll_add(c->fds, fd, 0, 1); /* write */
        switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
        case -1:
            sockerror("s_write: s_poll_wait");
            longjmp(c->err, 1); /* error */
        case 0:
            s_log(LOG_INFO, "s_write: s_poll_wait:"
                " TIMEOUTbusy exceeded: sending reset");
            longjmp(c->err, 1); /* timeout */
        case 1:
            break; /* OK */
        default:
            s_log(LOG_ERR, "s_write: s_poll_wait: unknown result");
            longjmp(c->err, 1); /* error */
        }
        num=writesocket(fd, (void *)ptr, len);
        if(num==-1) { /* error */
            sockerror("writesocket (s_write)");
            longjmp(c->err, 1);
        }
        ptr+=(size_t)num;
        len-=(size_t)num;
    }
}

void s_read(CLI *c, SOCKET fd, void *ptr, size_t len) {
        /* simulate a blocking read */
    ssize_t num;

    while(len>0) {
        s_poll_init(c->fds);
        s_poll_add(c->fds, fd, 1, 0); /* read */
        switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
        case -1:
            sockerror("s_read: s_poll_wait");
            longjmp(c->err, 1); /* error */
        case 0:
            s_log(LOG_INFO, "s_read: s_poll_wait:"
                " TIMEOUTbusy exceeded: sending reset");
            longjmp(c->err, 1); /* timeout */
        case 1:
            break; /* OK */
        default:
            s_log(LOG_ERR, "s_read: s_poll_wait: unknown result");
            longjmp(c->err, 1); /* error */
        }
        num=readsocket(fd, ptr, len);
        switch(num) {
        case -1: /* error */
            sockerror("readsocket (s_read)");
            longjmp(c->err, 1);
        case 0: /* EOF */
            s_log(LOG_ERR, "Unexpected socket close (s_read)");
            longjmp(c->err, 1);
        }
        ptr=(uint8_t *)ptr+num;
        len-=(size_t)num;
    }
}

void fd_putline(CLI *c, SOCKET fd, const char *line) {
    char *tmpline;
    const char crlf[]="\r\n";
    size_t len;

    tmpline=str_printf("%s%s", line, crlf);
    len=strlen(tmpline);
    s_write(c, fd, tmpline, len);
    tmpline[len-2]='\0'; /* remove CRLF */
    s_log(LOG_DEBUG, " -> %s", tmpline);
    str_free(tmpline);
}

char *fd_getline(CLI *c, SOCKET fd) {
    char *line;
    size_t ptr=0, allocated=32;

    line=str_alloc(allocated);
    for(;;) {
        if(ptr>65536) { /* >64KB --> DoS protection */
            s_log(LOG_ERR, "fd_getline: Line too long");
            str_free(line);
            longjmp(c->err, 1);
        }
        if(allocated<ptr+1) {
            allocated*=2;
            line=str_realloc(line, allocated);
        }
        s_read(c, fd, line+ptr, 1);
        if(line[ptr]=='\r')
            continue;
        if(line[ptr]=='\n')
            break;
        if(line[ptr]=='\0')
            break;
        ++ptr;
    }
    line[ptr]='\0';
    s_log(LOG_DEBUG, " <- %s", line);
    return line;
}

void fd_printf(CLI *c, SOCKET fd, const char *format, ...) {
    va_list ap;
    char *line;

    va_start(ap, format);
    line=str_vprintf(format, ap);
    va_end(ap);
    if(!line) {
        s_log(LOG_ERR, "fd_printf: str_vprintf failed");
        longjmp(c->err, 1);
    }
    fd_putline(c, fd, line);
    str_free(line);
}

void s_ssl_write(CLI *c, const void *buf, int len) {
        /* simulate a blocking SSL_write */
    uint8_t *ptr=(uint8_t *)buf;
    int num;

    while(len>0) {
        s_poll_init(c->fds);
        s_poll_add(c->fds, c->ssl_wfd->fd, 0, 1); /* write */
        switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
        case -1:
            sockerror("s_write: s_poll_wait");
            longjmp(c->err, 1); /* error */
        case 0:
            s_log(LOG_INFO, "s_write: s_poll_wait:"
                " TIMEOUTbusy exceeded: sending reset");
            longjmp(c->err, 1); /* timeout */
        case 1:
            break; /* OK */
        default:
            s_log(LOG_ERR, "s_write: s_poll_wait: unknown result");
            longjmp(c->err, 1); /* error */
        }
        num=SSL_write(c->ssl, (void *)ptr, len);
        if(num==-1) { /* error */
            sockerror("SSL_write (s_ssl_write)");
            longjmp(c->err, 1);
        }
        ptr+=num;
        len-=num;
    }
}

void s_ssl_read(CLI *c, void *ptr, int len) {
        /* simulate a blocking SSL_read */
    int num;

    while(len>0) {
        if(!SSL_pending(c->ssl)) {
            s_poll_init(c->fds);
            s_poll_add(c->fds, c->ssl_rfd->fd, 1, 0); /* read */
            switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
            case -1:
                sockerror("s_read: s_poll_wait");
                longjmp(c->err, 1); /* error */
            case 0:
                s_log(LOG_INFO, "s_read: s_poll_wait:"
                    " TIMEOUTbusy exceeded: sending reset");
                longjmp(c->err, 1); /* timeout */
            case 1:
                break; /* OK */
            default:
                s_log(LOG_ERR, "s_read: s_poll_wait: unknown result");
                longjmp(c->err, 1); /* error */
            }
        }
        num=SSL_read(c->ssl, ptr, len);
        switch(num) {
        case -1: /* error */
            sockerror("SSL_read (s_ssl_read)");
            longjmp(c->err, 1);
        case 0: /* EOF */
            s_log(LOG_ERR, "Unexpected socket close (s_ssl_read)");
            longjmp(c->err, 1);
        }
        ptr=(uint8_t *)ptr+num;
        len-=num;
    }
}

char *ssl_getstring(CLI *c) { /* get null-terminated string */
    char *line;
    size_t ptr=0, allocated=32;

    line=str_alloc(allocated);
    for(;;) {
        if(ptr>65536) { /* >64KB --> DoS protection */
            s_log(LOG_ERR, "fd_getline: Line too long");
            str_free(line);
            longjmp(c->err, 1);
        }
        if(allocated<ptr+1) {
            allocated*=2;
            line=str_realloc(line, allocated);
        }
        s_ssl_read(c, line+ptr, 1);
        if(line[ptr]=='\0')
            break;
        ++ptr;
    }
    return line;
}

#define INET_SOCKET_PAIR

int make_sockets(SOCKET fd[2]) { /* make a pair of connected ipv4 sockets */
#ifdef INET_SOCKET_PAIR
    struct sockaddr_in addr;
    socklen_t addrlen;
    SOCKET s; /* temporary socket awaiting for connection */

    /* create two *blocking* sockets first */
    s=s_socket(AF_INET, SOCK_STREAM, 0, 0, "make_sockets: s_socket#1");
    if(s==INVALID_SOCKET)
        return 1;
    fd[1]=s_socket(AF_INET, SOCK_STREAM, 0, 0, "make_sockets: s_socket#2");
    if(fd[1]==INVALID_SOCKET) {
        closesocket(s);
        return 1;
    }

    addrlen=sizeof addr;
    memset(&addr, 0, sizeof addr);
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
    addr.sin_port=htons(0); /* dynamic port allocation */
    if(bind(s, (struct sockaddr *)&addr, addrlen))
        log_error(LOG_DEBUG, get_last_socket_error(), "make_sockets: bind#1");
    if(bind(fd[1], (struct sockaddr *)&addr, addrlen))
        log_error(LOG_DEBUG, get_last_socket_error(), "make_sockets: bind#2");

    if(listen(s, 1)) {
        sockerror("make_sockets: listen");
        closesocket(s);
        closesocket(fd[1]);
        return 1;
    }
    if(getsockname(s, (struct sockaddr *)&addr, &addrlen)) {
        sockerror("make_sockets: getsockname");
        closesocket(s);
        closesocket(fd[1]);
        return 1;
    }
    if(connect(fd[1], (struct sockaddr *)&addr, addrlen)) {
        sockerror("make_sockets: connect");
        closesocket(s);
        closesocket(fd[1]);
        return 1;
    }
    fd[0]=s_accept(s, (struct sockaddr *)&addr, &addrlen, 1,
        "make_sockets: s_accept");
    if(fd[0]==INVALID_SOCKET) {
        closesocket(s);
        closesocket(fd[1]);
        return 1;
    }
    closesocket(s); /* don't care about the result */
    set_nonblock(fd[0], 1);
    set_nonblock(fd[1], 1);
#else
    if(s_socketpair(AF_UNIX, SOCK_STREAM, 0, fd, 1, "make_sockets: socketpair"))
        return 1;
#endif
    return 0;
}

/* end of network.c */
