title: SSL_shutdown() returns -1 and errno is 0
body: <p>In my C++ application I use OpenSSL to connect to a server using nonblocking BIO. I am developing for mac OS X and iOS. </p>
  
  <p>The first call to <code>SSL_shutdown()</code> returns 0. Which means I have to call <code>SSL_shutdown()</code> again:</p>
  
  <blockquote>
    <p>The following return values can occur:</p>
    
    <p>0 The shutdown is not yet finished. Call SSL_shutdown() for a second time, if a bidirectional shutdown shall be performed. The output of SSL_get_error may be misleading, as an erroneous SSL_ERROR_SYSCALL may be flagged even though no error occurred. </p>
    
    <p>&lt;0
    The shutdown was not successful because a fatal error occurred either at the protocol level or a connection failure occurred. It can also occur if action is need to continue the operation for non-blocking BIOs. Call SSL_get_error with the return value ret to find out the reason.</p>
  </blockquote>
  
  <p><a href="https://www.openssl.org/docs/ssl/SSL_shutdown.html" rel="nofollow">https://www.openssl.org/docs/ssl/SSL_shutdown.html</a></p>
  
  <p>So far so god. The problem occurs on the second call to <code>SSL_shutdown()</code>. This returns -1 which means an error has occurred (see above). Now if I check with <code>SSL_get_error()</code> I get error <code>SSL_ERROR_SYSCALL</code> which in turn is supposed to mean a system error has occurred. But now the catch. If I check the <code>errno</code> it returns 0 -> unknown error. What I have read so far about the issue is, that it could mean that the server did just "hang up", but to be honest this does not satisfy me. </p>
  
  <p>Here is my implementation of the shutdown:</p>
  
  <pre><code>int result = 0;
  int shutdownResult;
  while ((shutdownResult = SSL_shutdown(sslHandle)) != 1) { //close connection 1 means everything is shut down ok
    if (shutdownResult == 0) { //we are supposed to call shutdown again
      continue;
    } else if (SSL_get_error(sslHandle, shutdownResult) == SSL_ERROR_WANT_READ) {
                  [...] //omitted want read code, in this case the application never reaches this point
    } else if (SSL_get_error(sslHandle, shutdownResult) == SSL_ERROR_WANT_WRITE) {
                  [...] //omitted want write code, in this case the application never reaches this point
    } else {
      logError("Error in ssl shutdown, ssl error: " + std::to_string(SSL_get_error(sslHandle, shutdownResult)) + ", system error: " + std::string(strerror(errno))); //something went wrong
      break;
    }
  } 
  </code></pre>
  
  <p>When run the application logs:</p>
  
  <blockquote>
    <p>ERROR:: Error in ssl shutdown, ssl error: 5, system error: Undefined error: 0</p>
  </blockquote>
  
  <p>So is here just the server shutting down the connection or is there a more critical issue? Am I just missing something really obvious?</p>