Browse Source

Further update ssl-errors

Brian Aker 11 years ago
parent
commit
4cf83c7b79
4 changed files with 143 additions and 119 deletions
  1. 73 74
      libgearman-server/io.cc
  2. 2 8
      libgearman-server/log.cc
  3. 2 2
      libgearman-server/log.h
  4. 66 35
      libgearman/connection.cc

+ 73 - 74
libgearman-server/io.cc

@@ -123,51 +123,55 @@ static size_t _connection_read(gearman_server_con_st *con, void *data, size_t da
 #if defined(HAVE_SSL) && HAVE_SSL
     if (con->_ssl)
     {
-      int ssl_errno= 0;
 # if defined(HAVE_CYASSL) && HAVE_CYASSL
       read_size= CyaSSL_recv(con->_ssl, data, int(data_size), MSG_DONTWAIT);
 # else
       read_size= SSL_read(con->_ssl, data, int(data_size));
 # endif
       assert(HAVE_SSL); // Just to make sure if macro is aligned.
-      ssl_errno= errno;
-      if (read_size == 0)
-      { } // Socket has been closed
-      else if (read_size < 0)
+      int ssl_error;
+      switch ((ssl_error= SSL_get_error(con->_ssl, int(read_size))))
       {
-        int sendErr= SSL_get_error(con->_ssl, int(read_size));
-        switch (sendErr)
-        {
-          case SSL_ERROR_ZERO_RETURN:
-            {
-              read_size= 0; // Shutdown occured.
-              break;
+        case SSL_ERROR_NONE:
+          break;
+        case SSL_ERROR_ZERO_RETURN:
+          {
+            if (SSL_get_shutdown(con->_ssl) & SSL_RECEIVED_SHUTDOWN)
+            { // Client made a clean SSL shutdown.");
             }
-          case SSL_ERROR_WANT_READ:
+            else
             {
-              read_size= SOCKET_ERROR;
-              errno= EAGAIN;
-              break;
+              gearmand_log_gerror_warn(GEARMAN_DEFAULT_LOG_PARAM, GEARMAND_LOST_CONNECTION, "Client made a dirty SSL shutdown.");
             }
-          case SSL_ERROR_SYSCALL:
-            { // All other errors
-              char errorString[SSL_ERROR_SIZE];
-              ERR_error_string_n(sendErr, errorString, sizeof(errorString));
-              _connection_close(connection);
-              gearmand_log_perror(GEARMAN_DEFAULT_LOG_PARAM, ssl_errno, "SSL failure(%s)", errorString);
-
-              return 0;
-            }
-          default:
-            { // All other errors
-              char errorString[SSL_ERROR_SIZE];
-              ERR_error_string_n(sendErr, errorString, sizeof(errorString));
-              _connection_close(connection);
-              gearmand_log_warning(GEARMAN_DEFAULT_LOG_PARAM, "SSL failure(%s) errno:%d", errorString, ssl_errno);
+            read_size= 0; // Shutdown occured.
+            break;
+          }
+        case SSL_ERROR_WANT_READ:
+          {
+            read_size= SOCKET_ERROR;
+            errno= EAGAIN;
+            break;
+          }
+        case SSL_ERROR_WANT_WRITE:
+          {
+            read_size= SOCKET_ERROR;
+            errno= EAGAIN;
+            break;
+          }
+        case SSL_ERROR_SYSCALL:
+          if (errno) // If errno is really set, then let our normal error logic handle.
+          {
+            break;
+          }
+        default:
+          { // All other errors
+            char errorString[SSL_ERROR_SIZE];
+            ERR_error_string_n(ssl_error, errorString, sizeof(errorString));
+            _connection_close(connection);
+            gearmand_log_warning(GEARMAN_DEFAULT_LOG_PARAM, "SSL failure(%s) errno:%d", errorString);
 
-              return 0;
-            }
-        }
+            return 0;
+          }
       }
     }
     else
@@ -310,50 +314,47 @@ static gearmand_error_t _connection_flush(gearman_server_con_st *con)
           assert(HAVE_SSL); // Just to make sure if macro is aligned.
 
           // I consider this to be a bug in SSL_send()/SSL_write() that is uses a zero in this manner
-          if (write_size == 0)
+          int ssl_error;
+          switch ((ssl_error= SSL_get_error(con->_ssl, int(write_size))))
           {
-            if ((err= SSL_get_error(con->_ssl, int(write_size))) == SSL_ERROR_ZERO_RETURN)
-            {
-              _connection_close(connection);
-              if (SSL_get_shutdown(con->_ssl) & SSL_RECEIVED_SHUTDOWN)
-              {
-                return gearmand_log_gerror(GEARMAN_DEFAULT_LOG_PARAM, GEARMAND_LOST_CONNECTION, "Client made a clean SSL shutdown.");
-              }
+            case SSL_ERROR_NONE:
+              break;
 
-              return gearmand_log_gerror(GEARMAN_DEFAULT_LOG_PARAM, GEARMAND_LOST_CONNECTION, "Client made a dirty SSL shutdown.");
-            }
-          }
-          else (write_size <= 0)
-          {
-            int err;
-            switch ((err= SSL_get_error(con->_ssl, int(write_size))))
-            {
-              case SSL_ERROR_WANT_CONNECT:
-              case SSL_ERROR_WANT_ACCEPT:
-                write_size= SOCKET_ERROR;
-                errno= EAGAIN;
-                break;
+            case SSL_ERROR_ZERO_RETURN:
+              {
+                if (SSL_get_shutdown(con->_ssl) & SSL_RECEIVED_SHUTDOWN)
+                {
+                  _connection_close(connection);
+                  return gearmand_log_gerror(GEARMAN_DEFAULT_LOG_PARAM, GEARMAND_LOST_CONNECTION, "Client made a clean SSL shutdown during write.");
+                }
 
-              case SSL_ERROR_WANT_WRITE:
-              case SSL_ERROR_WANT_READ:
-                write_size= SOCKET_ERROR;
-                errno= EAGAIN;
                 break;
+              }
+            case SSL_ERROR_WANT_CONNECT:
+            case SSL_ERROR_WANT_ACCEPT:
+              write_size= SOCKET_ERROR;
+              errno= EAGAIN;
+              break;
 
-              case SSL_ERROR_SYSCALL:
-                { // errno error
-                  break;  
-                }
+            case SSL_ERROR_WANT_WRITE:
+            case SSL_ERROR_WANT_READ:
+              write_size= SOCKET_ERROR;
+              errno= EAGAIN;
+              break;
 
-              default:
-                {
-                  char errorString[SSL_ERROR_SIZE];
-                  ERR_error_string_n(err, errorString, sizeof(errorString));
-                  _connection_close(connection);
-                  return gearmand_log_gerror(GEARMAN_DEFAULT_LOG_PARAM, GEARMAND_LOST_CONNECTION, "SSL failure(%s)",
-                                             errorString);
-                }
-            }
+            case SSL_ERROR_SYSCALL:
+              if (errno) // If errno is really set, then let our normal error logic handle.
+              {
+                break;
+              }
+            default:
+              {
+                char errorString[SSL_ERROR_SIZE];
+                ERR_error_string_n(ssl_error, errorString, sizeof(errorString));
+                _connection_close(connection);
+                return gearmand_log_gerror(GEARMAN_DEFAULT_LOG_PARAM, GEARMAND_LOST_CONNECTION, "SSL failure(%s)",
+                                           errorString);
+              }
           }
         }
         else
@@ -739,9 +740,7 @@ gearmand_error_t gearman_io_send(gearman_server_con_st *con,
 }
 
 #pragma GCC diagnostic push
-#ifndef __INTEL_COMPILER
 #pragma GCC diagnostic ignored "-Wold-style-cast"
-#endif
 gearmand_error_t gearman_io_recv(gearman_server_con_st *con, bool recv_data)
 {
   gearmand_io_st *connection= &con->con;

+ 2 - 8
libgearman-server/log.cc

@@ -425,7 +425,7 @@ gearmand_error_t gearmand_log_perror(const char *position, const char *function,
   return __errno_to_gearmand_error_t(local_errno);
 }
 
-gearmand_error_t gearmand_log_perror_warn(const char *position, const char *function, const int local_errno, const char *format, ...)
+void gearmand_log_perror_warn(const char *position, const char *function, const int local_errno, const char *format, ...)
 {
   if (not Gearmand() or (Gearmand()->verbose >= GEARMAND_VERBOSE_WARN))
   {
@@ -461,8 +461,6 @@ gearmand_error_t gearmand_log_perror_warn(const char *position, const char *func
       gearmand_log_warning(position, function, "%s", errmsg_ptr);
     }
   }
-
-  return __errno_to_gearmand_error_t(local_errno);
 }
 
 gearmand_error_t gearmand_log_gerror(const char *position, const char *function, const gearmand_error_t rc, const char *format, ...)
@@ -484,7 +482,7 @@ gearmand_error_t gearmand_log_gerror(const char *position, const char *function,
   return rc;
 }
 
-gearmand_error_t gearmand_log_gerror_warn(const char *position, const char *function, const gearmand_error_t rc, const char *format, ...)
+void gearmand_log_gerror_warn(const char *position, const char *function, const gearmand_error_t rc, const char *format, ...)
 {
   if (gearmand_failed(rc) and rc != GEARMAND_IO_WAIT)
   {
@@ -497,10 +495,6 @@ gearmand_error_t gearmand_log_gerror_warn(const char *position, const char *func
       va_end(args);
     }
   }
-  else if (rc == GEARMAND_IO_WAIT)
-  { }
-
-  return rc;
 }
 
 gearmand_error_t gearmand_log_gai_error(const char *position, const char *function, const int rc, const char *message)

+ 2 - 2
libgearman-server/log.h

@@ -85,9 +85,9 @@ gearmand_error_t gearmand_log_perror(const char *position, const char *function,
 gearmand_error_t gearmand_log_gerror(const char *position, const char *function, const gearmand_error_t rc, const char *format, ...);
 #define gearmand_gerror(_mesg, _gearmand_errot_t) gearmand_log_gerror(GEARMAN_DEFAULT_LOG_PARAM, (_gearmand_errot_t), (_mesg))
 
-gearmand_error_t gearmand_log_perror_warn(const char *position, const char *function, const int local_errno, const char *format, ...);
+void gearmand_log_perror_warn(const char *position, const char *function, const int local_errno, const char *format, ...);
 
-gearmand_error_t gearmand_log_gerror_warn(const char *position, const char *function, const gearmand_error_t rc, const char *format, ...);
+void gearmand_log_gerror_warn(const char *position, const char *function, const gearmand_error_t rc, const char *format, ...);
 #define gearmand_gerror_warn(_mesg, _gearmand_errot_t) gearmand_log_gerror_warn(GEARMAN_DEFAULT_LOG_PARAM, (_gearmand_errot_t), (_mesg))
 
 gearmand_error_t gearmand_log_gai_error(const char *position, const char *function, const int rc, const char *message);

+ 66 - 35
libgearman/connection.cc

@@ -838,7 +838,6 @@ gearman_return_t gearman_connection_st::flush()
       {
         ssize_t write_size;
 #if defined(HAVE_SSL) && HAVE_SSL
-        write_size= 0;
         if (_ssl)
         {
 #if defined(HAVE_CYASSL) && HAVE_CYASSL
@@ -846,31 +845,39 @@ gearman_return_t gearman_connection_st::flush()
 #elif defined(HAVE_OPENSSL) && HAVE_OPENSSL
           write_size= SSL_write(_ssl, send_buffer_ptr, int(send_buffer_size));
 #endif
-          if (write_size <= 0)
+          int ssl_error;
+          switch ((ssl_error= SSL_get_error(_ssl, int(write_size))))
           {
-            int err;
-            switch ((err= SSL_get_error(_ssl, int(write_size))))
-            {
-              case SSL_ERROR_WANT_CONNECT:
-              case SSL_ERROR_WANT_ACCEPT:
-                write_size= SOCKET_ERROR;
-                errno= EAGAIN;
-                break;
-
-              case SSL_ERROR_WANT_WRITE:
-              case SSL_ERROR_WANT_READ:
-                write_size= SOCKET_ERROR;
-                errno= EAGAIN;
-                break;
-
-              default:
+            case SSL_ERROR_NONE:
+              break;
+            case SSL_ERROR_ZERO_RETURN:
+              {
+                if (SSL_get_shutdown(_ssl) & SSL_RECEIVED_SHUTDOWN)
                 {
-                  char errorString[80];
-                  ERR_error_string_n(err, errorString, sizeof(errorString));
                   close_socket();
-                  return gearman_universal_set_error(universal, GEARMAN_LOST_CONNECTION, GEARMAN_AT, "SSL failure(%s)", errorString);
+                  return gearman_universal_set_error(universal, GEARMAN_LOST_CONNECTION, GEARMAN_AT, "Client made a clean SSL shutdown during write.");
                 }
-            }
+              }
+
+            case SSL_ERROR_WANT_CONNECT:
+            case SSL_ERROR_WANT_ACCEPT:
+              write_size= SOCKET_ERROR;
+              errno= EAGAIN;
+              break;
+
+            case SSL_ERROR_WANT_WRITE:
+            case SSL_ERROR_WANT_READ:
+              write_size= SOCKET_ERROR;
+              errno= EAGAIN;
+              break;
+
+            default:
+              {
+                char errorString[80];
+                ERR_error_string_n(ssl_error, errorString, sizeof(errorString));
+                close_socket();
+                return gearman_universal_set_error(universal, GEARMAN_LOST_CONNECTION, GEARMAN_AT, "SSL failure(%s)", errorString);
+              }
           }
         }
         else
@@ -1141,20 +1148,44 @@ size_t gearman_connection_st::recv_socket(void *data, size_t data_size, gearman_
 # elif defined(HAVE_OPENSSL) && HAVE_OPENSSL
       read_size= SSL_read(_ssl, data, int(data_size));
 # endif
-      if (read_size == 0)
-      { } // Socket has been closed
-      else if (read_size < 0)
+      int ssl_error;
+      switch ((ssl_error= SSL_get_error(_ssl, int(read_size))))
       {
-        int sendErr= SSL_get_error(_ssl, int(read_size));
-        if (sendErr != SSL_ERROR_WANT_READ)
-        {
-          char errorString[80];
-          ERR_error_string_n(sendErr, errorString, sizeof(errorString));
-          close_socket();
-          ret= gearman_universal_set_error(universal, GEARMAN_LOST_CONNECTION, GEARMAN_AT,
-                                           "SSL failure(%s)", errorString);
-        }
-        errno= EAGAIN;
+        case SSL_ERROR_NONE:
+          break;
+
+        case SSL_ERROR_ZERO_RETURN:
+          {
+            if (SSL_get_shutdown(_ssl) & SSL_RECEIVED_SHUTDOWN)
+            { // Client made a clean SSL shutdown.");
+            }
+            else
+            {
+              gearman_log_info(universal, "Client made a dirty SSL shutdown.");
+            }
+            read_size= 0; // Shutdown occured.
+            break;
+          }
+
+        case SSL_ERROR_WANT_CONNECT:
+        case SSL_ERROR_WANT_ACCEPT:
+          read_size= SOCKET_ERROR;
+          errno= EAGAIN;
+          break;
+
+        case SSL_ERROR_WANT_WRITE:
+        case SSL_ERROR_WANT_READ:
+          read_size= SOCKET_ERROR;
+          errno= EAGAIN;
+          break;
+
+        default:
+          {
+            char errorString[80];
+            ERR_error_string_n(ssl_error, errorString, sizeof(errorString));
+            close_socket();
+            return gearman_universal_set_error(universal, GEARMAN_LOST_CONNECTION, GEARMAN_AT, "SSL failure(%s)", errorString);
+          }
       }
     }
     else