Exemplo n.º 1
0
static int ssl_io_hook_writev(BUFF *fb, const struct iovec *iov, int iovcnt)
{
    SSL *ssl;
    conn_rec *c;
    int rc;

    if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) {
        rc = SSL_writev(ssl, iov, iovcnt);
        /*
         * Simulate an EINTR in case OpenSSL wants to write more.
         */
        if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE)
            errno = EINTR;
        /*
         * Log SSL errors
         */
        if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_SSL) {
            c = (conn_rec *)SSL_get_app_data(ssl);
            ssl_log(c->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
                    "SSL error on writing data");
        }
        /*
         * writev(2) returns only the generic error number -1
         */
        if (rc < 0)
            rc = -1;
    }
    else
        rc = writev(fb->fd, iov, iovcnt);
    return rc;
}
Exemplo n.º 2
0
int calipso_reply_send_writev(calipso_reply_t *reply)
{
    struct iovec *iovv, iov[IOV_MAX];
    cpo_array_t arr;

    dllist_t *l;
    struct chunk_ctx *cc;
    chunks_t *cf = reply->out_filter;
    calipso_client_t *client;
    int prev_send, sent = 0;
    int send = 0;

    //int complete = 0;
    int nw, block;

    arr.elem_size = sizeof(struct iovec);
    arr.max = IOV_MAX;
    arr.v = iov;

    client = calipso_reply_get_client(reply);

    for (;;) {
        arr.num = 0;
        iovv = NULL;
        prev_send = send;

        for (l = cf->list; l && (cc = l->data); l = l->next) {
            if (arr.num == IOV_MAX) {
                break;
            }

            if (cc->size) {
                send += cc->size;
                iovv = cpo_array_push(&arr);
                iovv->iov_base = cc->b;
                iovv->iov_len = cc->size;
            }
        }

#ifdef USE_SSL

        if (client->ssl)
            nw = SSL_writev(client->ssl, arr.v, arr.num);
        else

#endif
            nw = writev(client->csocket, arr.v, arr.num);

        if (nw < 0) {
            if (nw == -1 && errno == EWOULDBLOCK) {
                break;
            } else {
                reply->bytes_to_send = reply->bytes_sent;
                reply->out_filter->total_bytes = 0;
                TRACE("writev error %s\n", strerror(errno));
                cpo_log_error(calipso->log, "writev error %s\n",
                              strerror(errno));
                break;
            }
        }

        sent = nw > 0 ? nw : 0;

        if (send - prev_send == sent) {
            printf("Complete %d\n", send - prev_send);
            //complete =1;
        }

        //printf("nwritten %d bytes_sent %d\n", nw , reply->bytes_sent);
        reply->bytes_sent += sent;
        reply->out_filter->total_bytes -= sent;

        if (!reply->out_filter->total_bytes) {
            //printf("Break loop\n");
            break;
        }

        block = 0;

        FOREACH_CHUNK_CTX(l,cf,cc) {
            //dllist_t *ll = l;

            block += cc->size;
            if (block <= sent) {

                cc->b += cc->size;
                cc->size -= cc->size;

                //ll = dllist_find_release(ll, cc);
                //l = ll;
            }
            if (block > sent) {
                int last = block - sent;
                int len = cc->size - last;

                cc->b += len;
                cc->size -= len;
                reply->out_filter = cf;
                return 1;
            }
        }

    } //for;;