Commit b8c49611 authored by Matt Caswell's avatar Matt Caswell
Browse files

Provide a function to test whether we have unread records pending



Also updates SSL_has_pending() to use it. This actually fixes a bug in
SSL_has_pending() which is supposed to return 1 if we have any processed
or unprocessed data sitting in OpenSSL buffers. However it failed to return
1 if we had processed non-application data pending.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2875)
parent c1f84df2
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -77,11 +77,24 @@ void RECORD_LAYER_release(RECORD_LAYER *rl)
    SSL3_RECORD_release(rl->rrec, SSL_MAX_PIPELINES);
}

/* Checks if we have unprocessed read ahead data pending */
int RECORD_LAYER_read_pending(const RECORD_LAYER *rl)
{
    return SSL3_BUFFER_get_left(&rl->rbuf) != 0;
}

/* Checks if we have decrypted unread record data pending */
int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl)
{
    size_t curr_rec = 0, num_recs = RECORD_LAYER_get_numrpipes(rl);
    const SSL3_RECORD *rr = rl->rrec;

    while (curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec]))
        curr_rec++;

    return curr_rec < num_recs;
}

int RECORD_LAYER_write_pending(const RECORD_LAYER *rl)
{
    return (rl->numwpipes > 0)
+1 −0
Original line number Diff line number Diff line
@@ -207,6 +207,7 @@ void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s);
void RECORD_LAYER_clear(RECORD_LAYER *rl);
void RECORD_LAYER_release(RECORD_LAYER *rl);
int RECORD_LAYER_read_pending(const RECORD_LAYER *rl);
int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl);
int RECORD_LAYER_write_pending(const RECORD_LAYER *rl);
void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl);
void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl);
+1 −1
Original line number Diff line number Diff line
@@ -1323,7 +1323,7 @@ int SSL_has_pending(const SSL *s)
     * data. That data may not result in any application data, or we may fail
     * to parse the records for some reason.
     */
    if (SSL_pending(s))
    if (RECORD_LAYER_processed_read_pending(&s->rlayer))
        return 1;

    return RECORD_LAYER_read_pending(&s->rlayer);