예제 #1
0
/*
    Return the number of bytes read. Return -1 on errors and EOF.
 */
PUBLIC ssize sslRead(Webs *wp, void *buf, ssize len)
{
    Nano        *np;
    WebsSocket  *sp;
    sbyte4      nbytes, count;
    int         rc;

    np = (Nano*) wp->ssl;
    assert(np);

    if (!np->connected && (rc = nanoHandshake(wp)) <= 0) {
        return rc;
    }
    while (1) {
        /*
            This will do the actual blocking I/O
         */
        rc = SSL_recv(np->handle, buf, (sbyte4) len, &nbytes, 0);
        logmsg(5, "NanoSSL: ssl_read %d", rc);
        if (rc < 0) {
            if (rc != ERR_TCP_READ_ERROR) {
                sp = socketPtr(wp->sid);
                sp->flags |= SOCKET_EOF;
            }
            return -1;
        }
        break;
    }
    SSL_recvPending(np->handle, &count);
    if (count > 0) {
        socketReservice(wp->wid);
    }
    return nbytes;
}
예제 #2
0
파일: openssl.c 프로젝트: JasonCC/goahead
PUBLIC ssize sslRead(Webs *wp, void *buf, ssize len)
{
    WebsSocket      *sp;
    char            ebuf[BIT_GOAHEAD_LIMIT_STRING];
    ulong           serror;
    int             rc, error, retries, i;

    if (wp->ssl == 0 || len <= 0) {
        assert(0);
        return -1;
    }
    /*  
        Limit retries on WANT_READ. If non-blocking and no data, then this can spin forever.
     */
    sp = socketPtr(wp->sid);
    retries = 5;
    for (i = 0; i < retries; i++) {
        rc = SSL_read(wp->ssl, buf, (int) len);
        if (rc < 0) {
            error = SSL_get_error(wp->ssl, rc);
            if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_CONNECT || error == SSL_ERROR_WANT_ACCEPT) {
                continue;
            }
            serror = ERR_get_error();
            ERR_error_string_n(serror, ebuf, sizeof(ebuf) - 1);
            trace(5, "SSL_read %s", ebuf);
        }
        break;
    }
    if (rc <= 0) {
        error = SSL_get_error(wp->ssl, rc);
        if (error == SSL_ERROR_WANT_READ) {
            rc = 0;
        } else if (error == SSL_ERROR_WANT_WRITE) {
            sleep(0);
            rc = 0;
        } else if (error == SSL_ERROR_ZERO_RETURN) {
            sp->flags |= SOCKET_EOF;
            rc = -1;
        } else if (error == SSL_ERROR_SYSCALL) {
            sp->flags |= SOCKET_EOF;
            rc = -1;
        } else if (error != SSL_ERROR_ZERO_RETURN) {
            /* SSL_ERROR_SSL */
            serror = ERR_get_error();
            ERR_error_string_n(serror, ebuf, sizeof(ebuf) - 1);
            trace(4, "OpenSSL: connection with protocol error: %s", ebuf);
            rc = -1;
            sp->flags |= SOCKET_EOF;
        }
    } else if (SSL_pending(wp->ssl) > 0) {
        sp->flags |= SOCKET_BUFFERED_READ;
        socketReservice(wp->sid);
    }
    return rc;
}
예제 #3
0
PUBLIC void socketHiddenData(WebsSocket *sp, ssize len, int dir)
{
    if (len > 0) {
        sp->flags |= (dir == SOCKET_READABLE) ? SOCKET_BUFFERED_READ : SOCKET_BUFFERED_WRITE;
        if (sp->handler) {
            socketReservice(sp->sid);
        }
    } else {
        sp->flags &= ~((dir == SOCKET_READABLE) ? SOCKET_BUFFERED_READ : SOCKET_BUFFERED_WRITE);
    }
}
예제 #4
0
/*
    Return number of bytes read. Return -1 on errors and EOF.
 */
PUBLIC ssize sslRead(Webs *wp, void *buf, ssize len)
{
    Ms      *ms;
    ssize   bytes;

    if (len <= 0) {
        return -1;
    }
    bytes = innerRead(wp, buf, len);
    ms = (Ms*) wp->ssl;
    if (ms->more) {
        wp->flags |= SOCKET_BUFFERED_READ;
        socketReservice(wp->sid);
    }
    return bytes;
}
예제 #5
0
/*
    Write data. Return the number of bytes written or -1 on errors.
 */
PUBLIC ssize sslWrite(Webs *wp, void *buf, ssize len)
{
    Nano        *np;
    WebsSocket  *sp;
    ssize       totalWritten;
    int         rc, count, sent;

    np = (Nano*) wp->ssl;
    if (len <= 0) {
        assert(0);
        return -1;
    }
    if (!np->connected && (rc = nanoHandshake(wp)) <= 0) {
        return rc;
    }
    totalWritten = 0;
    do {
        rc = sent = SSL_send(np->handle, (sbyte*) buf, (int) len);
        logmsg(7, "NanoSSL: written %d, requested len %d", sent, len);
        if (rc <= 0) {
            logmsg(0, "NanoSSL: SSL_send failed sent %d", rc);
            sp = socketPtr(wp->sid);
            sp->flags |= SOCKET_EOF;
            return -1;
        }
        totalWritten += sent;
        buf = (void*) ((char*) buf + sent);
        len -= sent;
        logmsg(7, "NanoSSL: write: len %d, written %d, total %d", len, sent, totalWritten);
    } while (len > 0);

    SSL_sendPending(np->handle, &count);
    if (count > 0) {
        socketReservice(wp->sid);
    }
    return totalWritten;
}