Hi list,

I am developing a XPCOM component to wrap input/output stream pairs
into ssl for server or client communication. I am not familiar with
NSS and I don't know how to write proper xpcom components in C but I
have a working implementation.

I have one problem though. I do not know how to deal with non-blocking
input and output streams. If I create a blocking stream the handshake
and everything else works just fine. However, if I am working in non-
blocking mode, my PRFileDesc IO layer recv function could fail with
PR_WOULD_BLOCK_ERROR upon which the NSS fails as well. I am not sure
how NSS works in nonblocking mode.

This is how my recv implementation looks like:

static PRInt32 PR_CALLBACK sslpipe_layer_recv(PRFileDesc *fd, void
*buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout)
{
        printf("sslpipe_layer_recv\n");

        SslPipeSecret *secret = (SslPipeSecret *)fd->secret;
        PRUint32 bytesRead;

        nsresult rv = secret->sslPipe->inputStream->Read((char *)buf,
(PRUint32)amount, &bytesRead);

        if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
                PR_SetError(PR_WOULD_BLOCK_ERROR, errno);

                return PR_WOULD_BLOCK_ERROR;
        }

        return bytesRead;
}

And this is how I am handling options to inform that the socket is
nonblocking or blocking:

static PRStatus PR_CALLBACK sslpipe_layer_getsocketoption(PRFileDesc
*fd, PRSocketOptionData *data)
{
        printf("sslpipe_layer_getsocketoption\n");

        if (data->option == PR_SockOpt_Nonblocking) {
                SslPipeSecret *secret = (SslPipeSecret *)fd->secret;
                PRBool isInputNonBlocking = PR_FALSE;
                PRBool isOutputNonBlocking = PR_FALSE;

                
secret->sslPipe->inputStream->IsNonBlocking(&isInputNonBlocking);
                
secret->sslPipe->outputStream->IsNonBlocking(&isOutputNonBlocking);

                data->value.non_blocking = isInputNonBlocking &&
isOutputNonBlocking;

                return PR_SUCCESS;
        }

        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, errno);

        return PR_FAILURE;
}

I might be doing something fundamentally wrong in here.

I am also thinking that the PR_WOULD_BLOCK_ERROR should escalate back
to my PR_Recv caller where I can capture it and react on it
respectively. However, I am not sure what needs to be done at this
stage. How do I continue the handshake process on the next available
block of data?
-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to