stream-ssl: Flush OpenSSL error queue after calling SSL_shutdown().
authorBen Pfaff <blp@nicira.com>
Thu, 13 May 2010 23:08:14 +0000 (16:08 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 13 May 2010 23:08:14 +0000 (16:08 -0700)
commit3d47699cdf86ee68120f97814349099457b48242
treec4e674433054a0dd2936ac538796961c4e4b3f50
parent3fbd517acfd8dba2cd75fa234b0eb3337d202d33
stream-ssl: Flush OpenSSL error queue after calling SSL_shutdown().

The OpenSSL manpage for SSL_get_error() says this:

   In addition to ssl and ret, SSL_get_error() inspects the current
   thread's OpenSSL error queue.  Thus, SSL_get_error() must be used in
   the same thread that performed the TLS/SSL I/O operation, and no other
   OpenSSL function calls should appear in between.  The current thread's
   error queue must be empty before the TLS/SSL I/O operation is
   attempted, or SSL_get_error() will not work reliably.

We weren't taking this advice literally enough, which meant that this
would happen:

   1. Call SSL_shutdown() on one connection.
   2. Call SSL_read() on another connection, returning 0 bytes.  (This is
      normal.  It just means that no more data has arrived yet.)
   3. Call SSL_get_error() for that second connection to check whether
      the 0-byte return value was a real error.  (This should return
      SSL_ERROR_WANT_READ to indicate that more data is needed.)
   4. Actually get some other error indicating that the SSL_shutdown()
      call returned an error.

This commit fixes the problem by flushing the OpenSSL error queue after
calling SSL_shutdown().

Without this commit, starting an ovsdb-server with two active SSL remotes,
running two ovsdb-clients listening for connections from the ovsdb-server
remotes, then killing one of the ovsdb-clients (with e.g. Control+C), will
cause ovsdb-server to drop the other ovsdb-client connnection the next time
that SSL_read() is called on it.  With this commit, this scenario works
correctly (e.g. ovsdb-server keeps the remaining connection up).

CC: Jeremy Stribling <strib@nicira.com>
lib/stream-ssl.c