On Thu, 15 Jan 2004 16:58, Rocco Caputo wrote;
> Can you investigate this some more? I originally tried to use
> Net::SSLeay's accept() and connect() in non-blocking mode, but that
> broke the SSL session negotiation.
From SSL_accept(3ssl):
If the underlying BIO is non-blocking, SSL_accept() will also
return when the underlying BIO could not satisfy the needs of
SSL_accept() to continue the handshake. In this case a call to
SSL_get_error() with the return value of SSL_accept() will
yield SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. The calling
process then must repeat the call after taking appropriate
action to satisfy the needs of SSL_accept(). The action
depends on the underlying BIO. When using a non-blocking
socket, nothing is to be done, but select() can be used to
check for the required condition. When using a buffering BIO,
like a BIO pair, data must be written into or retrieved out of
the BIO before being able to continue.
Like I said, it looks like the library has this all covered. If
Net::SSLeay isn't coded for non-blocking use then it needs fixing...
According to BIO_s_fd(3ssl),
The behaviour of BIO_read() and BIO_write() depends on the
behavior of the platforms read() and write() calls on the
descriptor. If the underlying file descriptor is in a non
blocking mode then the BIO will behave in the manner described
in the BIO_read(3) and BIO_should_retry(3) manual pages.
So, passing in an O_NONBLOCK *should* work, but I think I have found a
better way... read on.
> While accept() and connect() follow the BSD sockets interface,
> Net::SSLeay expects them to send and receive data before they return.
> In O_NONBLOCK mode, accept() and connect() return before the SSL
session
> is fully established, and I don't know how to resume that.
In theory, you should just have to call the function that calls
SSL_accept() again.
> All of the blocking issues would be taken care of it we can drive that
> process with select().
Yes - let POE's IO drivers work. I was interested by
BIO_f_buffer(3ssl); this returns a BIO like above that doesn't have a
real file descriptor underneath, which I think would let you do this.
> Net::SSLeay already wraps openssl. Is there a better option?
It might be necessary to wrap just the critical SSL functions with a
seperate wrapper if the original module hasn't considered the
non-blocking case well enough, was all I was saying...
We want it to do this:
- call to BIO_new(BIO_f_buffer()) to set up the buffers
- call to SSL_CTX_new() to set up ssl options structure...
- a call to SSL_new() to set up the SSL structure
- a call to SSL_set_bio() to connect the SSL structure to the
buffers
- calls to BIO_write() and BIO_read() to stuff and unstuff the
buffers...
- then use SSL_accept(), SSL_read(), SSL_write(), etc.
Hey, maybe it's even possible to enact this using Net::SSLeay in its
current state...
</me looks>
Yes, I think that the section in the manual page called "BIO
interface" will let you set up a SSL processor disconnected from a
filesystem handle; something like this:
$rbio = Net::SSLeay::BIO_new(BIO_s_mem());
$wbio = Net::SSLeay::BIO_new(BIO_s_mem());
Net::SSLeay::set_bio($ssl, $rbio, $wbio);
# put blocks in
Net::SSLeay::BIO_write($rbio, $buffer, length($buffer));
# do appropriate SSL command for current state of filter
Net::SSLeay::accept($ssl);
# put blocks in
Net::SSLeay::BIO_write($rbio, $buffer, length($buffer));
That way, there is nothing tangible for SSLeay to block on. Does this
give anyone out there enough material to write
POE::Component::Filter::SSLeay ?
--
Sam Vilain, [EMAIL PROTECTED]
A politician's most important ability is to foretell what will happen
tomorrow and next month and next year - and to explain afterwards why
it didn't happen.
- anon.