Skip to content

How to correctly use SSL_read() in loop to fetch data which is larger than provided buffer size? #340

@rakeshcpp

Description

@rakeshcpp

When I use ssl_read in loop, when there is no data left on the server it hangs for few min or infinitely and then returns -1
I am new to socket programming, and know I am missing something very basic, but I have tried a whole day for solution and found nothing similar.

Consider in the following code which will make the issue clear:

// Initialize SSL and create SSL context

SSL_library_init();
SSL_CTX *ctx = SSL_CTX_new(TLS_method());

// Create SSL connection
SSL *ssl = SSL_new(ctx);

// Set socket file descriptor
SSL_set_fd(ssl, sockfd);

// sending message to server
ssize_t sent_size = SSL_write(ssl, request, strlen(request));

// error checking code

// Perform SSL_read operations
while (1) 
{
    char buffer[BUFFER_SIZE];
    int bytes_read = SSL_read(ssl, buffer, BUFFER_SIZE - 1);

    if (bytes_read > 0)
    {
        // no problem until we are here
        // Process received data
        
    }
    else if (bytes_read == 0)
    {
        // Here I got stuck, at some point I will always reach here, so does this really mean a connection closed or
        // there is no data left to read, and if there is no data left and I will continue to read it will return -1
        // which mean SSL error while I  was just trying to complete my loop

        // SSL connection closed by peer
        break;
    }
    else
    {
        // Handle SSL read error
    }
}

While there is data available there is no issue everything is going fine but as soon as data is complete, it goes hanging on SSL_read() operation it just waiting for few min to hour and then return -1. While I expect it will return 0 and I will simply break out of while loop.

I used timeout and thought of using non-blocking socket but that will just be hiding the original problem.
Please tell what might be wrong regarding my SSL code. I have not set any specific option while creating SSL connection, just used default behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions