On 2009-06-19 15:01 PDT, Rich Megginson wrote:
> Nelson B Bolyard wrote:
>> On 2009-06-19 12:48 PDT, Rich Megginson wrote:

> Yes.  This is an implementation of a PRIOMethods stack.  So what I mean 
> is "this is the function that implements the PR_Recv functionality for 
> this layer".

OK, we call that the "IO layer recv method".

>>> In the particular stack trace I'm looking at, this is called via
>>>
>>> ssl_DefRecv 
>>> ssl3_GatherData
>>> ssl3_GatherCompleteHandshake 
>>> ssl_GatherRecord1stHandshake
>> I'm guessing the rest of the stack resembles this
>>
>>   ssl_Do1stHandshake
>>   ssl_SecureRecv
>>   PR_Recv
> 
> No.
> 
>      ssl_Do1stHandshake
>      SSL_ForceHandshake
>      my_accept
> 
> This is a server accepting an SSL connection.

OK.
That doesn't really change anything.  SSL_ForceHandshake is like a PR_Read
or PR_Write call except that it transfers to data.  When done on a
non-blocking socket, it can return SECFailure with PR_WOULD_BLOCK_ERROR
just like a PR_Read or PR_Write can.  It's not a call that simulates
blocking behavior on a non-blocking socket.

> Ok.  The problem is that, in the above code, realfd is set to 
> non-blocking, and my_real_read_function is returning rc == -1 with errno 
> set to EAGAIN.  This means that the read operation would block.  If I 
> simply set the error to PR_WOULD_BLOCK_ERROR and pass the error 
> condition back up through the SSL layer, SSL interprets this as a hard 
> error - FAIL.

What makes you think that?
Does some subsequent operation fail that should succeed?

>>> Because when it returns rv = SECFailure, this goes up to the caller, 
>>> ssl3_GatherCompleteHandshake, which just returns it:
>> Correct.  It should be returned all the way out to the caller of PR_Recv.
> 
> So then to SSL_ForceHandshake and my_accept() function.

Yes, exactly.  That's what non-blocking sockets do (as you know).

>>> If so, what am I doing wrong?
>> Since you haven't told us what the problem is, what its symptoms are,
>> I can only guess.  I would guess that the problem is in the caller of
>> PR_Recv.  I would guess that it is expecting to get back SECWouldBlock
>> from PR_Recv, and when it gets PR_FAILURE, it doesn't check the error
>> code for PR_WOULD_BLOCK_ERROR, and then call PR_Poll to wait for IO
>> completion.  Or, maybe, it calls PR_Poll, but gets the "wrong answer"
>> due to a problem in some IO layer's poll method.
> 
> The problem is that my read_function(realfd) is returning EAGAIN, and I 
> need to somehow propagate that back up to the SSL layer (via setting the 
> pr error to PR_WOULD_BLOCK_ERROR) to tell the SSL layer that data is not 
> yet available.

It appears to me that your code is doing exactly that.

> Or, my_PR_Recv function needs to do a poll() to wait until all of the 
> requested data has been read, and not return until that happens, or some 
> real error condition has occurred.

You think your IO layer recv method should simulate blocking behavior on
a non-blocking socket?

I gather that you think that some part of this SSL socket stack is supposed
to emulate blocking behavior on top of a non-blocking socket.  But there
are no functions in SSL or NSPR that are defined to do that.

As you probably know, NSPR sockets have their own flag for recording if
the NSPR socket is to have blocking or non-blocking NSPR socket semantics.
It is possible for the bottom layer for an NSPR socket (the layer that
interfaces to the OSes own sockets implementation) to use non-blocking OS
sockets while providing blocking semantics to NSPR.  That is, it appears
to be a blocking socket to NSPR, but actually uses a non-blocking socket
under the hood.   NSPR's own reference implementation for Unix does exactly
that.  Your IO layer could do that, but I don't think that's what you're
really trying to accomplish.

I'm guessing that your my_accept function simply wasn't expecting
SSL_ForceHandshake to have non-blocking semantics.  When you call it on a
non-blocking socket, it may return SECFailure with PR_WOULD_BLOCK_ERROR
and in that case, your caller should go back to using PR_Poll to wait
for it to be ready for the next step (which is typically calling
SSL_ForceHandshake again).



-- 
12345678901234567890123456789012345678901234567890123456789012345678901234567890
00000000011111111112222222222333333333344444444445555555555666666666677777777778
-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to