gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [libmicrohttpd] branch master updated (1b71798d -> 35be224f


From: gnunet
Subject: [GNUnet-SVN] [libmicrohttpd] branch master updated (1b71798d -> 35be224f)
Date: Mon, 05 Jun 2017 21:21:51 +0200

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from 1b71798d Missing part of ddac6d53713141068625b074da18dc306e0bd6fa
     new 243e8fcd Used separate 'state' for TLS layer (independent of state of 
HTTP process)
     new 73013405 Replace usage of MHD_Connection::tls_closed with 
MHD_Connection::tls_state
     new 35be224f run_tls_handshake(): refactoring: return false if data send 
is not (yet) allowed

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ChangeLog                         | 12 ++++++++
 src/microhttpd/connection.c       | 42 +++++++++++++++++----------
 src/microhttpd/connection_https.c | 61 +++++++++++++++++++++++++++------------
 src/microhttpd/daemon.c           |  2 +-
 src/microhttpd/internal.h         | 41 +++++++++++++++-----------
 5 files changed, 106 insertions(+), 52 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 657dc286..7d44bd2b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Mon Jun 05 22:20:00 MSK 2017
+       Internal refactoring:
+       used TCP sockets directly with GnuTLS (performance improvement),
+       moved some connection-related code from daemon.c to 
+       connection.c/connection_https.c,
+       removed hacks around sendfile() and implemented correct support of
+       sendfile(),
+       removed do_read() and do_write() to reduce number of layer around send()
+       and recv() and to improve readability and maintainability of code,
+       implemented separate tracking of TLS layer state, independent of HTTP
+       connection stage. -EG
+
 Sun Jun 04 15:02:00 MSK 2017
        Improved thread-safety of MHD_add_connection() and
        internal_add_connection(), minor optimisations. -EG
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 21fe9aac..cd8b5b04 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1648,6 +1648,25 @@ MHD_connection_update_event_loop_info (struct 
MHD_Connection *connection)
   /* Do not update states of suspended connection */
   if (connection->suspended)
     return; /* States will be updated after resume. */
+#ifdef HTTPS_SUPPORT
+  if (MHD_TLS_CONN_NO_TLS != connection->tls_state)
+    { /* HTTPS connection. */
+      switch (connection->tls_state)
+        {
+          case MHD_TLS_CONN_INIT:
+            connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+            return;
+          case MHD_TLS_CONN_HANDSHAKING:
+            if (0 == gnutls_record_get_direction (connection->tls_session))
+              connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+            else
+              connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+            return;
+          default:
+            break;
+        }
+    }
+#endif /* HTTPS_SUPPORT */
   while (1)
     {
 #if DEBUG_STATES
@@ -1658,14 +1677,6 @@ MHD_connection_update_event_loop_info (struct 
MHD_Connection *connection)
 #endif
       switch (connection->state)
         {
-#ifdef HTTPS_SUPPORT
-       case MHD_TLS_CONNECTION_INIT:
-         if (0 == gnutls_record_get_direction (connection->tls_session))
-            connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
-         else
-            connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
-         break;
-#endif /* HTTPS_SUPPORT */
         case MHD_CONNECTION_INIT:
         case MHD_CONNECTION_URL_RECEIVED:
         case MHD_CONNECTION_HEADER_PART_RECEIVED:
@@ -2959,9 +2970,6 @@ MHD_connection_handle_write (struct MHD_Connection 
*connection)
           break;
         case MHD_CONNECTION_CLOSED:
           return MHD_YES;
-        case MHD_TLS_CONNECTION_INIT:
-          EXTRA_CHECK (0);
-          break;
         case MHD_CONNECTION_IN_CLEANUP:
           EXTRA_CHECK (0);
           break;
@@ -3072,6 +3080,14 @@ MHD_connection_handle_idle (struct MHD_Connection 
*connection)
   connection->in_idle = true;
   while (! connection->suspended)
     {
+#ifdef HTTPS_SUPPORT
+      if (MHD_TLS_CONN_NO_TLS != connection->tls_state)
+        { /* HTTPS connection. */
+          if ((MHD_TLS_CONN_INIT <= connection->tls_state) &&
+              (MHD_TLS_CONN_CONNECTED > connection->tls_state))
+            break;
+        }
+#endif /* HTTPS_SUPPORT */
 #if DEBUG_STATES
       MHD_DLOG (daemon,
                 _("In function %s handling connection at state: %s\n"),
@@ -3080,10 +3096,6 @@ MHD_connection_handle_idle (struct MHD_Connection 
*connection)
 #endif
       switch (connection->state)
         {
-#ifdef HTTPS_SUPPORT
-        case MHD_TLS_CONNECTION_INIT:
-          break;
-#endif /* HTTPS_SUPPORT */
         case MHD_CONNECTION_INIT:
           line = get_next_header_line (connection,
                                        &line_len);
diff --git a/src/microhttpd/connection_https.c 
b/src/microhttpd/connection_https.c
index e87aca56..d345b9aa 100644
--- a/src/microhttpd/connection_https.c
+++ b/src/microhttpd/connection_https.c
@@ -138,41 +138,45 @@ send_tls_adapter (struct MHD_Connection *connection,
  * Give gnuTLS chance to work on the TLS handshake.
  *
  * @param connection connection to handshake on
- * @return #MHD_YES on error or if the handshake is progressing
- *         #MHD_NO if the handshake has completed successfully
- *         and we should start to read/write data
+ * @return true if the handshake has completed successfully
+ *         and we should start to read/write data,
+ *         false is handshake in progress or in case
+ *         of error
  */
-static int
+static bool
 run_tls_handshake (struct MHD_Connection *connection)
 {
   int ret;
 
-  if (MHD_TLS_CONNECTION_INIT == connection->state)
+  if ((MHD_TLS_CONN_INIT == connection->tls_state) ||
+      (MHD_TLS_CONN_HANDSHAKING == connection->tls_state))
     {
       ret = gnutls_handshake (connection->tls_session);
       if (ret == GNUTLS_E_SUCCESS)
        {
-         /* set connection state to enable HTTP processing */
-         connection->state = MHD_CONNECTION_INIT;
+         /* set connection TLS state to enable HTTP processing */
+         connection->tls_state = MHD_TLS_CONN_CONNECTED;
          MHD_update_last_activity_ (connection);
-         return MHD_NO;
+         return true;
        }
       if ( (GNUTLS_E_AGAIN == ret) ||
           (GNUTLS_E_INTERRUPTED == ret) )
        {
+          connection->tls_state = MHD_TLS_CONN_HANDSHAKING;
          /* handshake not done */
-         return MHD_YES;
+         return false;
        }
       /* handshake failed */
+      connection->tls_state = MHD_TLS_CONN_TLS_FAILED;
 #ifdef HAVE_MESSAGES
       MHD_DLOG (connection->daemon,
                _("Error: received handshake message out of context\n"));
 #endif
       MHD_connection_close_ (connection,
                              MHD_REQUEST_TERMINATED_WITH_ERROR);
-      return MHD_YES;
+      return false;
     }
-  return MHD_NO;
+  return true;
 }
 
 
@@ -195,8 +199,11 @@ run_tls_handshake (struct MHD_Connection *connection)
 static int
 MHD_tls_connection_handle_read (struct MHD_Connection *connection)
 {
-  if (MHD_YES == run_tls_handshake (connection))
-    return MHD_YES;
+  if (MHD_TLS_CONN_CONNECTED > connection->tls_state)
+    {
+      if (!run_tls_handshake(connection))
+        return MHD_YES;
+    }
   return MHD_connection_handle_read (connection);
 }
 
@@ -212,8 +219,11 @@ MHD_tls_connection_handle_read (struct MHD_Connection 
*connection)
 static int
 MHD_tls_connection_handle_write (struct MHD_Connection *connection)
 {
-  if (MHD_YES == run_tls_handshake (connection))
-    return MHD_YES;
+  if (MHD_TLS_CONN_CONNECTED > connection->tls_state)
+    {
+      if (!run_tls_handshake(connection))
+        return MHD_YES;
+    }
   return MHD_connection_handle_write (connection);
 }
 
@@ -243,12 +253,25 @@ MHD_set_https_callbacks (struct MHD_Connection 
*connection)
 bool
 MHD_tls_connection_shutdown (struct MHD_Connection *connection)
 {
-  if (! connection->tls_closed)
+  if (MHD_TLS_CONN_WR_CLOSED > connection->tls_state)
     {
-      connection->tls_closed =
-          (GNUTLS_E_SUCCESS == gnutls_bye(connection->tls_session, 
GNUTLS_SHUT_WR));
+      const int res =
+          gnutls_bye(connection->tls_session, GNUTLS_SHUT_WR);
+      if (GNUTLS_E_SUCCESS == ret)
+        {
+          connection->tls_state = MHD_TLS_CONN_WR_CLOSED;
+          return true;
+        }
+      if ((GNUTLS_E_AGAIN == ret) ||
+          (GNUTLS_E_INTERRUPTED == ret))
+        {
+          connection->tls_state = MHD_TLS_CONN_WR_CLOSING;
+          return true;
+        }
+      else
+        connection->tls_state = MHD_TLS_CONN_TLS_FAILED;
     }
-  return connection->tls_closed ? MHD_YES : MHD_NO;;
+  return false;
 }
 
 /* end of connection_https.c */
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 0fd478c2..48fe6856 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -2258,7 +2258,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
   else
     {
 #ifdef HTTPS_SUPPORT
-      connection->state = MHD_TLS_CONNECTION_INIT;
+      connection->tls_state = MHD_TLS_CONN_INIT;
       MHD_set_https_callbacks (connection);
       gnutls_init (&connection->tls_session,
                    GNUTLS_SERVER);
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 72a8f7f9..eaed1580 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -510,27 +510,34 @@ enum MHD_CONNECTION_STATE
    */
   MHD_CONNECTION_IN_CLEANUP = MHD_CONNECTION_CLOSED + 1,
 
-  /*
-   *  SSL/TLS connection states
-   */
-
-  /**
-   * The initial connection state for all secure connectoins
-   * Handshake messages will be processed in this state & while
-   * in the #MHD_TLS_HELLO_REQUEST state
-   */
-  MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1,
-
 #ifdef UPGRADE_SUPPORT
   /**
    * Connection was "upgraded" and socket is now under the
    * control of the application.
    */
-  MHD_CONNECTION_UPGRADE = MHD_TLS_CONNECTION_INIT + 1,
+  MHD_CONNECTION_UPGRADE
 #endif /* UPGRADE_SUPPORT */
 
 };
 
+
+/**
+ * States of TLS transport layer.
+ */
+enum MHD_TLS_CONN_STATE
+{
+  MHD_TLS_CONN_NO_TLS = 0,  /**< Not a TLS connection (plain socket).   */
+  MHD_TLS_CONN_INIT,        /**< TLS connection is not established yet. */
+  MHD_TLS_CONN_HANDSHAKING, /**< TLS is in handshake process.           */
+  MHD_TLS_CONN_CONNECTED,   /**< TLS is established.                    */
+  MHD_TLS_CONN_WR_CLOSING,  /**< Closing WR side of TLS layer.          */
+  MHD_TLS_CONN_WR_CLOSED,   /**< WR side of TLS layer is closed.        */
+  MHD_TLS_CONN_TLS_CLOSING, /**< TLS session is terminating.            */
+  MHD_TLS_CONN_TLS_CLOSED,  /**< TLS session is terminated.             */
+  MHD_TLS_CONN_TLS_FAILED,  /**< TLS session failed.                    */
+  MHD_TLS_CONN_INVALID_STATE/**< Sentinel. Not a valid value.           */
+};
+
 /**
  * Should all state transitions be printed to stderr?
  */
@@ -973,15 +980,15 @@ struct MHD_Connection
   int cipher;
 
   /**
-   * Could it be that we are ready to read due to TLS buffers
-   * even though the socket is not?
+   * State of connection's TLS layer
    */
-  bool tls_read_ready;
+  enum MHD_TLS_CONN_STATE tls_state;
 
   /**
-   * TLS layer was shut down?
+   * Could it be that we are ready to read due to TLS buffers
+   * even though the socket is not?
    */
-  bool tls_closed;
+  bool tls_read_ready;
 #endif /* HTTPS_SUPPORT */
 
   /**

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]