gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] branch master updated (7ef7bab3 -> 331bc629)


From: gnunet
Subject: [libmicrohttpd] branch master updated (7ef7bab3 -> 331bc629)
Date: Tue, 01 Dec 2020 17:12:34 +0100

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

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from 7ef7bab3 mhd_send: improved setting of sk_cork_on
     new 727be7d2 mhd_send: use MSG_MORE only if it functions
     new 578f5e42 mhd_send: prepare for removal of gnutls_record_cork() call
     new 8435c616 mhd_send: fixed compatibility with platforms without TCP_CORK 
and TCP_NOPUSH
     new 958d8704 Removed gnutls_record_(un)cork() usage.
     new 34593987 mhd_send: fixed for C90 compilers
     new 331bc629 mhd_send: renamed functions and parameters to reflect the key 
purpose.

The 6 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:
 configure.ac                 |  15 ----
 src/microhttpd/daemon.c      |   2 +-
 src/microhttpd/mhd_send.c    | 196 ++++++++++++++++++++-----------------------
 src/microhttpd/mhd_sockets.h |   8 ++
 src/microhttpd/response.c    |  44 ++--------
 5 files changed, 108 insertions(+), 157 deletions(-)

diff --git a/configure.ac b/configure.ac
index b874ee68..456650c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -843,21 +843,6 @@ AC_SEARCH_LIBS(sendmsg, socket, 
AC_DEFINE([HAVE_SENDMSG],1,[Define if your platf
 AC_MSG_CHECKING([whether writev is available])
 AC_CHECK_FUNCS([writev])
 
-# check MSG_MORE defined
-AC_MSG_CHECKING([whether MSG_MORE is defined])
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include <sys/types.h>
-#include <sys/socket.h>
-]],[[return MSG_MORE;]]
-    )],
-    [
-      AC_MSG_RESULT(yes)
-      AC_DEFINE(HAVE_MSG_MORE, [1], [have MSG_MORE])
-    ],
-    [
-      AC_MSG_RESULT(no)
-    ])
-
 # set GCC options
 # use '-fno-strict-aliasing', but only if the compiler
 # and linker can take it
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index d02f0258..62e981e6 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -3507,7 +3507,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
     }
     return MHD_NO;
   }
-#if defined(MHD_TCP_CORK_NOPUSH) || defined(HAVE_MSG_MORE)
+#if defined(MHD_TCP_CORK_NOPUSH) || defined(MHD_USE_MSG_MORE)
   /* We will use TCP_CORK or TCP_NOPUSH or MSG_MORE to control
      transmission, disable Nagle's algorithm (always) */
   if ( (0 != MHD_socket_set_nodelay_ (s,
diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c
index 441f7e7d..4c937078 100644
--- a/src/microhttpd/mhd_send.c
+++ b/src/microhttpd/mhd_send.c
@@ -49,6 +49,7 @@
 /* For FreeBSD version identification */
 #include <sys/param.h>
 #endif /* HAVE_SYS_PARAM_H */
+#include "mhd_assert.h"
 
 
 /**
@@ -106,31 +107,43 @@ MHD_send_init_static_vars_ (void)
 
 
 /**
- * Handle setsockopt calls.
+ * Handle pre-send setsockopt calls.
  *
  * @param connection the MHD_Connection structure
- * @param want_cork cork state, boolean
+ * @param plain_send set to true if plain send() or sendmsg() will be called,
+ *                   set to false if TLS socket send(), sendfile() or
+ *                   writev() will be called.
+ * @param push_data whether to push data to the network from buffers after
+ *                  the next call of send function.
  */
 static void
-pre_cork_setsockopt (struct MHD_Connection *connection,
-                     bool want_cork)
+pre_send_setopt (struct MHD_Connection *connection,
+                 bool plain_send,
+                 bool push_data)
 {
-#if HAVE_MSG_MORE
-  /* We use the MSG_MORE option for corking, no need for extra syscalls! */
-
-  (void) connection; /* Mute compiler warning. */
-  (void) want_cork;  /* Mute compiler warning. */
-
-#elif defined(MHD_TCP_CORK_NOPUSH)
   int ret;
+  /* Try to buffer data if not sending the final piece.
+   * Final piece is indicated by push_data == true. */
+  const bool buffer_data = (! push_data);
+
+#ifdef MHD_USE_MSG_MORE
+  if (plain_send)
+  {
+    /* MSG_MORE is used, no need for extra syscalls! */
+    return;
+  }
+#else  /* ! MHD_USE_MSG_MORE */
+  (void) plain_send; /* Mute compiler warning. */
+#endif /* ! MHD_USE_MSG_MORE */
 
+#if defined(MHD_TCP_CORK_NOPUSH)
   /* If sk_cork_on is already what we pass in, return. */
-  if (connection->sk_cork_on == want_cork)
+  if (connection->sk_cork_on == buffer_data)
   {
     /* nothing to do, success! */
     return;
   }
-  if (! want_cork)
+  if (push_data)
     return; /* nothing to do *pre* syscall! */
   ret = MHD_socket_cork_ (connection->socket_fd,
                           true);
@@ -178,48 +191,59 @@ pre_cork_setsockopt (struct MHD_Connection *connection,
     break;
   }
 #else
-  /* CORK/NOPUSH/MSG_MORE do not exist on this platform,
-     so we must toggle Naggle's algorithm on/off instead
+  /* CORK/NOPUSH do not exist on this platform,
+     Turning on/off of Naggle's algorithm
      (otherwise we keep it always off) */
-  if (connection->sk_cork_on == want_cork)
+  if (connection->sk_cork_on == buffer_data)
   {
     /* nothing to do, success! */
     return;
   }
-  if ( (want_cork) &&
-       (0 == MHD_socket_set_nodelay_ (connection->socket_fd,
-                                      false)) )
-    connection->sk_cork_on = true;
+  if (0 == MHD_socket_set_nodelay_ (connection->socket_fd,
+                                    (push_data)))
+    connection->sk_cork_on = !push_data;
 #endif
 }
 
 
 /**
- * Handle setsockopt calls.
+ * Handle post-send setsockopt calls.
  *
  * @param connection the MHD_Connection structure
- * @param want_cork cork state, boolean
+ * @param plain_send set to true if plain send() or sendmsg() have been
+ *                   called,
+ *                   set to false if TLS socket send(), sendfile() or
+ *                   writev() has been called.
+ * @param push_data whether to push data to the network from buffers
  */
 static void
-post_cork_setsockopt (struct MHD_Connection *connection,
-                      bool want_cork)
+post_send_setopt (struct MHD_Connection *connection,
+                  bool plain_send,
+                  bool push_data)
 {
-#if HAVE_MSG_MORE
-  /* We use the MSG_MORE option for corking, no need for extra syscalls! */
-
-  (void) connection; /* Mute compiler warning. */
-  (void) want_cork;  /* Mute compiler warning. */
-
-#elif defined(MHD_TCP_CORK_NOPUSH)
   int ret;
+  /* Try to buffer data if not sending the final piece.
+   * Final piece is indicated by push_data == true. */
+  const bool buffer_data = (! push_data);
 
+#ifdef MHD_USE_MSG_MORE
+  if (plain_send)
+  {
+    /* MSG_MORE is used, no need for extra syscalls! */
+    return;
+  }
+#else  /* ! MHD_USE_MSG_MORE */
+  (void) plain_send; /* Mute compiler warning. */
+#endif /* ! MHD_USE_MSG_MORE */
+
+#if defined(MHD_TCP_CORK_NOPUSH)
   /* If sk_cork_on is already what we pass in, return. */
-  if (connection->sk_cork_on == want_cork)
+  if (connection->sk_cork_on == buffer_data)
   {
     /* nothing to do, success! */
     return;
   }
-  if (want_cork)
+  if (buffer_data)
     return; /* nothing to do *post* syscall (in fact, we should never
                get here, as sk_cork_on should have succeeded in the
                pre-syscall) */
@@ -268,19 +292,6 @@ post_cork_setsockopt (struct MHD_Connection *connection,
     /* any others? man page does not list more... */
     break;
   }
-#else
-  /* CORK/NOPUSH/MSG_MORE do not exist on this platform,
-     so we must toggle Naggle's algorithm on/off instead
-     (otherwise we keep it always off) */
-  if (connection->sk_cork_on == want_cork)
-  {
-    /* nothing to do, success! */
-    return;
-  }
-  if ( (! want_cork) &&
-       (0 == MHD_socket_set_nodelay_ (connection->socket_fd,
-                                      true)) )
-    connection->sk_cork_on = false;
 #endif
 }
 
@@ -310,9 +321,14 @@ MHD_send_on_connection_ (struct MHD_Connection *connection,
                          size_t buffer_size,
                          enum MHD_SendSocketOptions options)
 {
-  bool want_cork;
+  bool push_data;
   MHD_socket s = connection->socket_fd;
   ssize_t ret;
+#ifdef HTTPS_SUPPORT
+  const bool tls_conn = (connection->daemon->options & MHD_USE_TLS);
+#else  /* ! HTTPS_SUPPORT */
+  const bool tls_conn = false;
+#endif /* ! HTTPS_SUPPORT */
 
   /* error handling from send_param_adapter() */
   if ( (MHD_INVALID_SOCKET == s) ||
@@ -330,30 +346,22 @@ MHD_send_on_connection_ (struct MHD_Connection 
*connection,
   {
   /* No corking */
   case MHD_SSO_PUSH_DATA:
-    want_cork = false;
+    push_data = true;
     break;
   /* Do corking, consider MSG_MORE instead if available. */
   case MHD_SSO_PREFER_BUFF:
-    want_cork = true;
+    push_data = false;
     break;
   /* Cork the header. */
   case MHD_SSO_HDR_CORK:
-    want_cork = (buffer_size <= 1024);
+    push_data = (buffer_size > 1024);
     break;
   }
 
-#ifdef HTTPS_SUPPORT
-  if (0 != (connection->daemon->options & MHD_USE_TLS))
+  pre_send_setopt (connection, (! tls_conn), push_data);
+  if (tls_conn)
   {
-    bool have_cork = connection->sk_cork_on;
-
-#if GNUTLS_VERSION_NUMBER >= 0x030109
-    if (want_cork && ! have_cork)
-    {
-      gnutls_record_cork (connection->tls_session);
-      connection->sk_cork_on = true;
-    }
-#endif /* GNUTLS_VERSION_NUMBER >= 0x030109 */
+#ifdef HTTPS_SUPPORT
     if (buffer_size > SSIZE_MAX)
       buffer_size = SSIZE_MAX;
     ret = gnutls_record_send (connection->tls_session,
@@ -379,30 +387,17 @@ MHD_send_on_connection_ (struct MHD_Connection 
*connection,
      * sent amount smaller than provided amount, as TLS
      * connections may break data into smaller parts for sending. */
 #endif /* EPOLL_SUPPORT */
-
-#if GNUTLS_VERSION_NUMBER >= 0x030109
-    if (! want_cork && have_cork)
-    {
-      int err = gnutls_record_uncork (connection->tls_session, 0);
-
-      if (0 > err)
-        return MHD_ERR_AGAIN_;
-      connection->sk_cork_on = false;
-    }
-#endif /* GNUTLS_VERSION_NUMBER >= 0x030109 */
+#endif /* HTTPS_SUPPORT  */
+    (void) 0; /* Mute compiler warning for non-TLS builds. */
   }
   else
-#endif /* HTTPS_SUPPORT  */
   {
     /* plaintext transmission */
-    bool new_cork_state;
-
-    pre_cork_setsockopt (connection, want_cork);
-#if HAVE_MSG_MORE
+#ifdef MHD_USE_MSG_MORE
     ret = send (s,
                 buffer,
                 buffer_size,
-                MSG_NOSIGNAL_OR_ZERO | (want_cork ? MSG_MORE : 0));
+                MSG_NOSIGNAL_OR_ZERO | (push_data ? 0 : MSG_MORE));
 #else
     ret = send (connection->socket_fd,
                 buffer,
@@ -433,10 +428,9 @@ MHD_send_on_connection_ (struct MHD_Connection *connection,
     else if (buffer_size > (size_t) ret)
       connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
 #endif /* EPOLL_SUPPORT */
-    new_cork_state = want_cork ? (buffer_size == (size_t) ret) : false;
-    post_cork_setsockopt (connection, new_cork_state);
-    connection->sk_cork_on = new_cork_state;
   }
+  post_send_setopt (connection, tls_conn,
+                        (push_data && (buffer_size == (size_t) ret)) );
 
   return ret;
 }
@@ -466,8 +460,17 @@ MHD_send_on_connection2_ (struct MHD_Connection 
*connection,
                           const char *buffer,
                           size_t buffer_size)
 {
+  MHD_socket s = connection->socket_fd;
+  ssize_t ret;
+  struct iovec vector[2];
+#ifdef HTTPS_SUPPORT
+  const bool tls_conn = (connection->daemon->options & MHD_USE_TLS);
+#else  /* ! HTTPS_SUPPORT */
+  const bool tls_conn = false;
+#endif /* ! HTTPS_SUPPORT */
+
 #ifdef HTTPS_SUPPORT
-  if (0 != (connection->daemon->options & MHD_USE_TLS))
+  if (tls_conn)
   {
     ssize_t ret;
 
@@ -475,30 +478,13 @@ MHD_send_on_connection2_ (struct MHD_Connection 
*connection,
                                    header,
                                    header_size,
                                    MHD_SSO_HDR_CORK);
-#if GNUTLS_VERSION_NUMBER >= 0x030109
-    if ( (header_size == (size_t) ret) &&
-         (0 == buffer_size) &&
-         connection->sk_cork_on)
-    {
-      int err;
-
-      err = gnutls_record_uncork (connection->tls_session, 0);
-      if (0 > err)
-        return ret;
-      connection->sk_cork_on = false;
-    }
-#endif /* GNUTLS_VERSION_NUMBER >= 0x030109 */
     return ret;
   }
 #endif
 #if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
-  MHD_socket s = connection->socket_fd;
-  ssize_t ret;
-  struct iovec vector[2];
-
   /* Since we generally give the fully answer, we do not want
      corking to happen */
-  pre_cork_setsockopt (connection, false);
+  pre_send_setopt (connection, (! tls_conn), true);
 
   vector[0].iov_base = (void *) header;
   vector[0].iov_len = header_size;
@@ -532,8 +518,8 @@ MHD_send_on_connection2_ (struct MHD_Connection *connection,
 
   /* Only if we succeeded sending the full buffer, we need to make sure that
      the OS flushes at the end */
-  if (header_size + buffer_size == (size_t) ret)
-    post_cork_setsockopt (connection, false);
+  post_send_setopt (connection, (! tls_conn),
+                    (header_size + buffer_size == (size_t) ret));
 
   return ret;
 
@@ -585,8 +571,9 @@ MHD_send_sendfile_ (struct MHD_Connection *connection)
                             MHD_SENFILE_CHUNK_;
   size_t send_size = 0;
   mhd_assert (MHD_resp_sender_sendfile == connection->resp_sender);
+  mhd_assert (0 == (connection->daemon->options & MHD_USE_TLS));
 
-  pre_cork_setsockopt (connection, false);
+  pre_send_setopt (connection, false, true);
 
   offsetu64 = connection->response_write_position
               + connection->response->fd_off;
@@ -730,8 +717,7 @@ MHD_send_sendfile_ (struct MHD_Connection *connection)
 
   /* Make sure we send the data without delay ONLY if we
      provided the complete response (not on partial write) */
-  if (left == (uint64_t) ret)
-    post_cork_setsockopt (connection, false);
+  post_send_setopt (connection, false, (left == (uint64_t) ret));
 
   return ret;
 }
diff --git a/src/microhttpd/mhd_sockets.h b/src/microhttpd/mhd_sockets.h
index 4dfc1ca3..25286e5e 100644
--- a/src/microhttpd/mhd_sockets.h
+++ b/src/microhttpd/mhd_sockets.h
@@ -219,6 +219,14 @@ typedef SOCKET MHD_socket;
 #define MHD_TCP_CORK_NOPUSH TCP_NOPUSH
 #endif /* TCP_NOPUSH */
 
+#ifdef MSG_MORE
+#ifdef __linux__
+/* MSG_MORE signal kernel to buffer outbond data and works like
+ * TCP_CORK per call without actually setting TCP_CORK value.
+ * It's known to work on Linux. Add more OSes if they are compatible. */
+#define MHD_USE_MSG_MORE 1
+#endif /* __linux__ */
+#endif /* MSG_MORE */
 
 /**
  * MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt()
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index dc04cab5..489be718 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -894,53 +894,25 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
   case MHD_UPGRADE_ACTION_CORK_ON:
     if (connection->sk_cork_on)
       return MHD_YES;
-#ifdef HTTPS_SUPPORT
-    if (0 != (daemon->options & MHD_USE_TLS) )
+    if (0 !=
+        MHD_socket_cork_ (connection->socket_fd,
+                          true))
     {
-      gnutls_record_cork (connection->tls_session);
       connection->sk_cork_on = true;
       return MHD_YES;
     }
-    else
-#endif
-    {
-      if (0 !=
-          MHD_socket_cork_ (connection->socket_fd,
-                            true))
-      {
-        connection->sk_cork_on = true;
-        return MHD_YES;
-      }
-      return MHD_NO;
-    }
+    return MHD_NO;
   case MHD_UPGRADE_ACTION_CORK_OFF:
     if (! connection->sk_cork_on)
       return MHD_YES;
-#ifdef HTTPS_SUPPORT
-    if (0 != (daemon->options & MHD_USE_TLS) )
+    if (0 !=
+        MHD_socket_cork_ (connection->socket_fd,
+                          false))
     {
-      int err;
-
-      err = gnutls_record_uncork (connection->tls_session, 0);
-      if (0 > err)
-        return MHD_NO;
       connection->sk_cork_on = false;
       return MHD_YES;
     }
-    else
-#endif
-    {
-      if (! connection->sk_cork_on)
-        return MHD_YES;
-      if (0 !=
-          MHD_socket_cork_ (connection->socket_fd,
-                            false))
-      {
-        connection->sk_cork_on = false;
-        return MHD_YES;
-      }
-      return MHD_NO;
-    }
+    return MHD_NO;
   default:
     /* we don't understand this one */
     return MHD_NO;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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