I'm running into a problem while using NSS with non-blocking sockets. I have my own PR_Recv function that does something like this:

static int PR_CALLBACK
my_PR_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, PRIntervalTime timeout)
{
...
        rc = my_real_read_function( realfd, buf, len );
        if (rc <= 0) {
                if ( errno == EAGAIN || errno == EWOULDBLOCK ) {
                        PR_SetError( PR_WOULD_BLOCK_ERROR, errno );
                }
        }

        return rc;
}

In the particular stack trace I'm looking at, this is called via

ssl_DefRecv -> ssl3_GatherData -> ssl3_GatherCompleteHandshake -> ssl_GatherRecord1stHandshake

I think the problem is that ssl3_GatherData does not check for WOULD_BLOCK:

        nb = ssl_DefRecv(ss, bp, gs->remainder, flags);

        if (nb > 0) {
            PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
        } else if (nb == 0) {
            /* EOF */
            SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
            rv = 0;
            break;
        } else /* if (nb < 0) */ {
            SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
                     PR_GetError()));
            rv = SECFailure;
This is the problem here. I think it should check to see if ssl_SocketIsBlocking(), then check to see if the error is WOULD_BLOCK, then return rv = SECWouldBlock
            break;
        }

Because when it returns rv = SECFailure, this goes up to the caller, which just returns it:
        rv = ssl3_GatherData(ss, &ss->gs, flags);
        if (rv <= 0) {
            return rv;
        }

ssl_GatherRecord1stHandshake gets rv SECFailure instead of SECWouldBlock. It looks as though it can properly handle SECWouldBlock, but ssl3_GatherData -> ssl3_GatherCompleteHandshake do not return that rv in this case.

Note that even if my PR_Recv function returned 0 here, the NSS code would interpret that as a closed socket:
        if (rv == 0) {
            /* EOF. Loser  */
            PORT_SetError(PR_END_OF_FILE_ERROR);
        }
        return SECFailure;      /* rv is < 0 here. */

Is NSS supposed to support non-blocking sockets? If so, what am I doing wrong?
--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to