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