/*
 * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "cert.h"
#include "ssl.h"
#include "sslimpl.h"

#if defined(WIN32)
#define MAP_ERROR(from, to) \
    if (err == from) {      \
        PORT_SetError(to);  \
    }
#define DEFINE_ERROR PRErrorCode err = PR_GetError();
#else
#define MAP_ERROR(from, to)
#define DEFINE_ERROR
#endif

int
ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
{
    PRFileDesc *lower = ss->fd->lower;
    int rv;

    rv = lower->methods->connect(lower, sa, ss->cTimeout);
    return rv;
}

int
ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
{
    PRFileDesc *lower = ss->fd->lower;
    int rv;

    rv = lower->methods->bind(lower, addr);
    return rv;
}

int
ssl_DefListen(sslSocket *ss, int backlog)
{
    PRFileDesc *lower = ss->fd->lower;
    int rv;

    rv = lower->methods->listen(lower, backlog);
    return rv;
}

int
ssl_DefShutdown(sslSocket *ss, int how)
{
    PRFileDesc *lower = ss->fd->lower;
    int rv;

    rv = lower->methods->shutdown(lower, how);
    return rv;
}

int
ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
{
    PRFileDesc *lower = ss->fd->lower;
    int rv;

    PORT_Assert(buf && len > 0);

    rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout);
    if (rv < 0) {
        DEFINE_ERROR
        MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
    } else if (rv > len) {
        PORT_Assert(rv <= len);
        PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
        rv = SECFailure;
    }
    return rv;
}

/* Default (unencrypted) send.
 * For blocking sockets, always returns len or SECFailure, no short writes.
 * For non-blocking sockets:
 *   Returns positive count if any data was written, else returns SECFailure.
 *   Short writes may occur.  Does not return SECWouldBlock.
 */
int
ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
{
    PRFileDesc *lower = ss->fd->lower;
    int sent = 0;

#if NSS_DISABLE_NAGLE_DELAYS
    /* Although this is overkill, we disable Nagle delays completely for
    ** SSL sockets.
    */
    if (ss->opt.useSecurity && !ss->delayDisabled) {
        ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */
        ss->delayDisabled = 1;
    }
#endif
    do {
        int rv = lower->methods->send(lower, (const void *)(buf + sent),
                                      len - sent, flags, ss->wTimeout);
        if (rv < 0) {
            PRErrorCode err = PR_GetError();
            if (err == PR_WOULD_BLOCK_ERROR) {
                ss->lastWriteBlocked = 1;
                return sent ? sent : SECFailure;
            }
            ss->lastWriteBlocked = 0;
            MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
            /* Loser */
            return rv;
        }
        sent += rv;

        if (IS_DTLS(ss) && (len > sent)) {
            /* We got a partial write so just return it */
            return sent;
        }
    } while (len > sent);
    ss->lastWriteBlocked = 0;
    return sent;
}

int
ssl_DefRead(sslSocket *ss, unsigned char *buf, int len)
{
    PRFileDesc *lower = ss->fd->lower;
    int rv;

    rv = lower->methods->read(lower, (void *)buf, len);
    if (rv < 0) {
        DEFINE_ERROR
        MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
    }
    return rv;
}

int
ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len)
{
    PRFileDesc *lower = ss->fd->lower;
    int sent = 0;

    do {
        int rv = lower->methods->write(lower, (const void *)(buf + sent),
                                       len - sent);
        if (rv < 0) {
            PRErrorCode err = PR_GetError();
            if (err == PR_WOULD_BLOCK_ERROR) {
                ss->lastWriteBlocked = 1;
                return sent ? sent : SECFailure;
            }
            ss->lastWriteBlocked = 0;
            MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
            /* Loser */
            return rv;
        }
        sent += rv;
    } while (len > sent);
    ss->lastWriteBlocked = 0;
    return sent;
}

int
ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
{
    PRFileDesc *lower = ss->fd->lower;
    int rv;

    rv = lower->methods->getpeername(lower, name);
    return rv;
}

int
ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
{
    PRFileDesc *lower = ss->fd->lower;
    int rv;

    rv = lower->methods->getsockname(lower, name);
    return rv;
}

int
ssl_DefClose(sslSocket *ss)
{
    PRFileDesc *fd;
    PRFileDesc *popped;
    int rv;

    fd = ss->fd;

    /* First, remove the SSL layer PRFileDesc from the socket's stack,
    ** then invoke the SSL layer's PRFileDesc destructor.
    ** This must happen before the next layer down is closed.
    */
    PORT_Assert(fd->higher == NULL);
    if (fd->higher) {
        PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
        return SECFailure;
    }
    ss->fd = NULL;

    /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on
    ** the stack, and then remove the second one.  This way, the address
    ** of the PRFileDesc on the top of the stack doesn't change.
    */
    popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
    popped->dtor(popped);

    /* fd is now the PRFileDesc for the next layer down.
    ** Now close the underlying socket.
    */
    rv = fd->methods->close(fd);

    ssl_FreeSocket(ss);

    SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d",
                SSL_GETPID(), fd, rv, PORT_GetError()));
    return rv;
}
