Bug 466317 - nss_compat_ossl doesn't support async I/O
nss_compat_ossl doesn't support async I/O
Status: ASSIGNED
Product: Fedora
Classification: Fedora
Component: nss_compat_ossl (Show other bugs)
rawhide
All Linux
medium Severity medium
: ---
: ---
Assigned To: Orphan Owner
Fedora Extras Quality Assurance
: FutureFeature
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2008-10-09 14:13 EDT by Dan Winship
Modified: 2015-05-26 11:33 EDT (History)
3 users (show)

See Also:
Fixed In Version:
Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed:
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Dan Winship 2008-10-09 14:13:40 EDT
openssl lets you do asynchronous I/O, but nss_compat_ossl doesn't. In particular:

    * nss_compat_ossl's SSL_read() and SSL_write() will never return
      SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, even if you set the fd
      to nonblocking.

    * You can't poll() for readability/writability of an SSL*, even if you
      know its underlying fd, because rehandshaking makes it impossible to
      know when you need to poll for readability and when you need to poll
      for writability.
Comment 1 John Poelstra 2008-10-09 18:09:00 EDT
This bug has been triaged
Comment 2 Rob Crittenden 2009-07-02 12:47:40 EDT
SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE don't apply to NSS since it hides the  SSL implementation from the caller in its NSPR layer. The first time you read or write an SSL connection it does all the work necessary for the handshake in the background.

It may be possible to sort of fake it by storing a couple of booleans that are set to TRUE until the first read/write occurs on the socket.

Do you have some code examples where this is causing problems?
Comment 3 Dan Winship 2009-07-02 16:17:53 EDT
(In reply to comment #2)
> The first time you
> read or write an SSL connection it does all the work necessary for the
> handshake in the background.

Right, that works fine for synchronous I/O, but if you're doing non-blocking I/O, then that first read or write is usually going to have to return partway through the handshake, and then you need to know whether to poll for readability or writability before continuing.

(And even ignoring the handshaking problem, SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE are also OpenSSL's equivalent of EAGAIN. If you call SSL_read() when no data is available to read, then it returns SSL_ERROR_WANT_READ. The fact that nss_compat_ossl never uses SSL_ERROR_WANT_READ/WRITE is therefore proof that it doesn't support non-blocking I/O.)

> Do you have some code examples where this is causing problems?

No. My existing code (libsoup, bug 347491) is using GNUTLS, and I haven't bothered to port it to OpenSSL (since it wouldn't work right with nss_compat_ossl) and I can't port it directly to NSS (since NSS has no async API that can integrate with the glib main loop).

Any program that uses OpenSSL with non-blocking sockets would run into this problem with nss_compat_ossl. Everything will still compile, but the socket won't behave non-blockingly, so the program's UI will freeze at random points, when SSL_read and SSL_write calls that should have returned right away instead end up blocking.
Comment 4 Fedora Admin XMLRPC Client 2011-08-24 14:22:47 EDT
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.
Comment 5 Dan Winship 2011-10-06 12:06:09 EDT
I figured out how to fix this at some point. In the PRIOMethods for the identity layer, override read/recv and write/send to notice when they get a PR_WOULD_BLOCK_ERROR from the lower level, and record either SSL_ERROR_WANT_READ (if it happened in read or recv) or SSL_ERROR_WANT_WRITE (if it happened in write/send) in ossl->error.

More or less. There might be other little bits and pieces.

Anyway, glib-networking will be using NSS directly (doing something very much like the above in order to make async I/O work), so this bug doesn't actually block it. (Though it may still be important to other potential nss_compat_ossl uses.)
Comment 6 Kamil Dudka 2014-04-25 10:10:22 EDT
(In reply to Dan Winship from comment #5)
> I figured out how to fix this at some point. In the PRIOMethods for the
> identity layer, override read/recv and write/send to notice when they get a
> PR_WOULD_BLOCK_ERROR from the lower level, and record either
> SSL_ERROR_WANT_READ (if it happened in read or recv) or SSL_ERROR_WANT_WRITE
> (if it happened in write/send) in ossl->error.

I have implemented something like this for libcurl:

https://github.com/bagder/curl/commit/9c941e92
Comment 7 Fedora Admin XMLRPC Client 2015-04-29 18:35:56 EDT
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.
Comment 8 Fedora Admin XMLRPC Client 2015-05-26 07:03:09 EDT
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.
Comment 9 Fedora Admin XMLRPC Client 2015-05-26 07:26:51 EDT
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.
Comment 10 Fedora Admin XMLRPC Client 2015-05-26 11:33:06 EDT
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.

Note You need to log in before you can comment on or make changes to this bug.