Browse Source

Implemented initialisation of connection's GnuTLS data

Evgeny Grin (Karlson2k) 1 năm trước cách đây
mục cha
commit
ca88e99ffd

+ 8 - 3
src/include/microhttpd2.h

@@ -1284,7 +1284,12 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
   /**
    * Failed to initialise TLS context for the daemon
    */
-  MHD_SC_DAEMON_TLS_INIT_FAILED = 51200
+  MHD_SC_TLS_DAEMON_INIT_FAILED = 51200
+  ,
+  /**
+   * Failed to initialise TLS context for the new connection
+   */
+  MHD_SC_TLS_CONNECTION_INIT_FAILED = 51201
   ,
   /**
    * Something wrong in the internal MHD logic.
@@ -4707,8 +4712,8 @@ MHD_FN_PAR_NONNULL_ (1);
  * @param addrlen number of bytes in @a addr
  * @param connection_cntx meta data the application wants to
  *        associate with the new connection object
- * @return #MHD_SC_OK on success
- *         error on failure
+ * @return #MHD_SC_OK on success,
+ *         error on failure (the @a client_socket is closed)
  * @ingroup specialized
  */
 MHD_EXTERN_ enum MHD_StatusCode

+ 2 - 2
src/include/microhttpd2_main.h.in

@@ -259,8 +259,8 @@ MHD_FN_PAR_NONNULL_ (1);
  * @param addrlen number of bytes in @a addr
  * @param connection_cntx meta data the application wants to
  *        associate with the new connection object
- * @return #MHD_SC_OK on success
- *         error on failure
+ * @return #MHD_SC_OK on success,
+ *         error on failure (the @a client_socket is closed)
  * @ingroup specialized
  */
 MHD_EXTERN_ enum MHD_StatusCode

+ 6 - 1
src/include/microhttpd2_preamble.h.in

@@ -1284,7 +1284,12 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
   /**
    * Failed to initialise TLS context for the daemon
    */
-  MHD_SC_DAEMON_TLS_INIT_FAILED = 51200
+  MHD_SC_TLS_DAEMON_INIT_FAILED = 51200
+  ,
+  /**
+   * Failed to initialise TLS context for the new connection
+   */
+  MHD_SC_TLS_CONNECTION_INIT_FAILED = 51201
   ,
   /**
    * Something wrong in the internal MHD logic.

+ 130 - 52
src/mhd2/daemon_add_conn.c

@@ -67,6 +67,10 @@
 #include "response_destroy.h"
 #include "conn_mark_ready.h"
 
+#ifdef MHD_ENABLE_HTTPS
+#  include "mhd_tls_funcs.h"
+#endif
+
 #include "mhd_public_api.h"
 
 
@@ -139,12 +143,14 @@ notify_app_conn (struct MHD_Daemon *restrict daemon,
  * @param sk_spipe_supprs indicate that the @a client_socket has
  *                         set SIGPIPE suppression
  * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket
- * @return pointer to the connection on success, NULL if this daemon could
- *        not handle the connection (i.e. malloc failed, etc).
- *        The socket will be closed in case of error; 'errno' is
- *        set to indicate further details about the error.
+ * @param[out] conn_out the pointer to variable to be set to the address
+ *                      of newly allocated connection structure
+ * @return #MHD_SC_OK on success,
+ *         error on failure (the @a client_socket is closed)
  */
-static enum MHD_StatusCode
+static MHD_FN_MUST_CHECK_RESULT_
+MHD_FN_PAR_NONNULL_ (1)
+MHD_FN_PAR_NONNULL_ (9) MHD_FN_PAR_OUT_ (9) enum MHD_StatusCode
 new_connection_prepare_ (struct MHD_Daemon *restrict daemon,
                          MHD_Socket client_socket,
                          const struct sockaddr_storage *restrict addr,
@@ -155,62 +161,117 @@ new_connection_prepare_ (struct MHD_Daemon *restrict daemon,
                          enum mhd_Tristate sk_is_nonip,
                          struct MHD_Connection **restrict conn_out)
 {
-  struct MHD_Connection *connection;
+  struct MHD_Connection *c;
+  enum MHD_StatusCode ret;
+  size_t tls_data_size;
+
+  ret = MHD_SC_OK;
   *conn_out = NULL;
 
-  if (NULL == (connection = mhd_calloc (1, sizeof (struct MHD_Connection))))
-  {
-    mhd_LOG_MSG (daemon, MHD_SC_CONNECTION_MALLOC_FAILURE,
-                 "Failed to allocate memory for the new connection");
-    mhd_socket_close (client_socket);
-    return MHD_SC_CONNECTION_MALLOC_FAILURE;
-  }
+  tls_data_size = 0;
+#ifdef MHD_ENABLE_HTTPS
+  if (mhd_D_HAS_TLS (daemon))
+    tls_data_size = mhd_tls_conn_get_tls_size ();
+#endif
 
-  if (! external_add)
+  c = mhd_calloc (1, sizeof (struct MHD_Connection) + tls_data_size);
+  if (NULL == c)
   {
-    connection->sk.state.corked = mhd_T_NO;
-    connection->sk.state.nodelay = mhd_T_NO;
+    mhd_LOG_MSG (daemon, \
+                 MHD_SC_CONNECTION_MALLOC_FAILURE, \
+                 "Failed to allocate memory for the new connection");
+    ret = MHD_SC_CONNECTION_MALLOC_FAILURE;
   }
   else
   {
-    connection->sk.state.corked = mhd_T_MAYBE;
-    connection->sk.state.nodelay = mhd_T_MAYBE;
-  }
+#ifdef MHD_ENABLE_HTTPS
+    if (0 != tls_data_size)
+      c->tls = (struct mhd_TlsConnData *) (c + 1);
+#  ifndef HAVE_NULL_PTR_ALL_ZEROS
+    else
+      c->tls = NULL;
+#  endif
+#endif
 
-  if (0 < addrlen)
-  {
-    if (NULL == (connection->sk.addr.data = malloc (addrlen)))
+    if (! external_add)
     {
-      mhd_LOG_MSG (daemon, MHD_SC_CONNECTION_MALLOC_FAILURE,
-                   "Failed to allocate memory for the new connection");
-      mhd_socket_close (client_socket);
-      free (connection);
-      return MHD_SC_CONNECTION_MALLOC_FAILURE;
+      c->sk.state.corked = mhd_T_NO;
+      c->sk.state.nodelay = mhd_T_NO;
     }
-    memcpy (connection->sk.addr.data,
-            addr,
-            addrlen);
-  }
-  else
-    connection->sk.addr.data = NULL;
-  connection->sk.addr.size = addrlen;
-  connection->sk.fd = client_socket;
-  connection->sk.props.is_nonblck = non_blck;
-  connection->sk.props.is_nonip = sk_is_nonip;
-  connection->sk.props.has_spipe_supp = sk_spipe_supprs;
+    else
+    {
+      c->sk.state.corked = mhd_T_MAYBE;
+      c->sk.state.nodelay = mhd_T_MAYBE;
+    }
+
+    if (0 < addrlen)
+    {
+      c->sk.addr.data = (struct sockaddr_storage *) malloc (addrlen);
+      if (NULL == c->sk.addr.data)
+      {
+        mhd_LOG_MSG (daemon, \
+                     MHD_SC_CONNECTION_MALLOC_FAILURE, \
+                     "Failed to allocate memory for the new connection");
+        ret = MHD_SC_CONNECTION_MALLOC_FAILURE;
+      }
+      else
+        memcpy (c->sk.addr.data,
+                addr,
+                addrlen);
+    }
+    else
+      c->sk.addr.data = NULL;
+
+    if (MHD_SC_OK == ret)
+    {
+      c->sk.addr.size = addrlen;
+      c->sk.fd = client_socket;
+      c->sk.props.is_nonblck = non_blck;
+      c->sk.props.is_nonip = sk_is_nonip;
+      c->sk.props.has_spipe_supp = sk_spipe_supprs;
 #ifdef MHD_USE_THREADS
-  mhd_thread_handle_ID_set_invalid (&connection->tid);
+      mhd_thread_handle_ID_set_invalid (&c->tid);
 #endif /* MHD_USE_THREADS */
-  connection->daemon = daemon;
-  connection->connection_timeout_ms = daemon->conns.cfg.timeout;
-  connection->event_loop_info = MHD_EVENT_LOOP_INFO_RECV;
-  if (0 != connection->connection_timeout_ms)
-    connection->last_activity = mhd_monotonic_msec_counter ();
+      c->daemon = daemon;
+      c->connection_timeout_ms = daemon->conns.cfg.timeout;
+      c->event_loop_info = MHD_EVENT_LOOP_INFO_RECV;
+
+      if (0 != tls_data_size)
+      {
+        if (! mhd_tls_conn_init (daemon->tls,
+                                 &(c->sk),
+                                 c->tls))
+        {
+          mhd_LOG_MSG (daemon, \
+                       MHD_SC_TLS_CONNECTION_INIT_FAILED, \
+                       "Failed to initialise TLS context for " \
+                       "the new connection");
+          ret = MHD_SC_TLS_CONNECTION_INIT_FAILED;
+        }
+#ifndef NDEBUG
+        else
+          c->dbg.tls_inited = true;
+#endif
+      }
+
+      if (MHD_SC_OK == ret)
+      {
+        if (0 != c->connection_timeout_ms)
+          c->last_activity = mhd_monotonic_msec_counter ();
+        *conn_out = c;
 
-  // TODO: init TLS
-  *conn_out = connection;
+        return MHD_SC_OK; /* Success exit point */
+      }
 
-  return MHD_SC_OK;
+      /* Below is a cleanup path */
+      if (NULL != c->sk.addr.data)
+        free (c->sk.addr.data);
+    }
+    free (c);
+  }
+  mhd_socket_close (client_socket);
+  mhd_assert (MHD_SC_OK != ret);
+  return ret; /* Failure exit point */
 }
 
 
@@ -356,7 +417,10 @@ new_connection_process_ (struct MHD_Daemon *restrict daemon,
   }
   /* Free resources allocated before the call of this functions */
 
-  // TODO: TLS support
+#ifdef MHD_ENABLE_HTTPS
+  if (mhd_C_HAS_TLS (connection))
+    mhd_tls_conn_deinit (connection->tls);
+#endif
 
   // TODO: per IP limit
 
@@ -385,10 +449,8 @@ new_connection_process_ (struct MHD_Daemon *restrict daemon,
  * @param sk_spipe_supprs indicate that the @a client_socket has
  *                         set SIGPIPE suppression
  * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket
- * @return #MHD_YES on success, #MHD_NO if this daemon could
- *        not handle the connection (i.e. malloc failed, etc).
- *        The socket will be closed in any case; 'errno' is
- *        set to indicate further details about the error.
+ * @return #MHD_SC_OK on success,
+ *         error on failure (the @a client_socket is closed)
  */
 static enum MHD_StatusCode
 internal_add_connection (struct MHD_Daemon *daemon,
@@ -975,6 +1037,22 @@ mhd_conn_close_final (struct MHD_Connection *restrict c)
   mhd_assert (c != mhd_DLINKEDL_GET_FIRST (&(c->daemon->conns), all_conn));
   mhd_assert (c != mhd_DLINKEDL_GET_LAST (&(c->daemon->conns), all_conn));
 
+#ifdef MHD_ENABLE_HTTPS
+  if (mhd_C_HAS_TLS (c))
+  {
+    mhd_assert (mhd_D_HAS_TLS (c->daemon));
+    mhd_assert (c->dbg.tls_inited);
+    mhd_tls_conn_deinit (c->tls);
+  }
+#  ifndef NDEBUG
+  else
+  {
+    mhd_assert (! mhd_D_HAS_TLS (c->daemon));
+    mhd_assert (! c->dbg.tls_inited);
+  }
+#  endif
+#endif
+
   if (NULL != c->sk.addr.data)
     free (c->sk.addr.data);
   mhd_socket_close (c->sk.fd);

+ 26 - 0
src/mhd2/mhd_connection.h

@@ -56,6 +56,10 @@
 
 #include "mhd_public_api.h"
 
+#ifdef MHD_ENABLE_HTTPS
+#  include "mhd_tls_choice.h" /* For the TLS struct forward declaration */
+#endif
+
 /**
  * Minimum reasonable size by which MHD tries to increment read/write buffers.
  * We usually begin with half the available pool space for the
@@ -356,6 +360,7 @@ struct mhd_ConnDebugData
   bool closing_started;
   bool pre_cleaned;
   bool removed_from_daemon;
+  bool tls_inited;
 };
 
 /**
@@ -400,6 +405,16 @@ struct MHD_Connection
    */
   struct mhd_ConnSocket sk;
 
+#ifdef MHD_ENABLE_HTTPS
+  /**
+   * Connection-specific TLS data.
+   * NULL if TLS is not used (plain HTTP connection).
+   * Allocated (and freed) together with struct MHD_Connection, cannot be
+   * deallocated separately.
+   */
+  struct mhd_TlsConnData *tls;
+#endif
+
   /**
    * 'true' if connection is in 'process ready' list,
    * 'false' otherwise
@@ -596,5 +611,16 @@ struct MHD_Connection
 #endif
 };
 
+#ifdef MHD_ENABLE_HTTPS
+/**
+ * Returns non-zero if connection has TLS enabled or zero otherwise
+ */
+#  define mhd_C_HAS_TLS(c) (((c)->tls) ? (! 0) : (0))
+#else
+/**
+ * Returns non-zero if connection has TLS enabled or zero otherwise
+ */
+#  define mhd_C_HAS_TLS(c) (0)
+#endif
 
 #endif /* ! MHD_CONNECTION_H */

+ 31 - 0
src/mhd2/mhd_tls_funcs.h

@@ -87,6 +87,37 @@
         mhd_TLS_FUNC (_daemon_deinit)((d_tls))
 
 
+/* ** Connection initialisation / de-initialisation ** */
+
+/**
+ * Get size size of the connection's TLS settings
+ */
+#define mhd_tls_conn_get_tls_size()     \
+        mhd_TLS_FUNC (_conn_get_tls_size)()
+
+/**
+ * Initialise connection TLS settings
+ * @param d_tls the daemon TLS settings
+ * @param sk data about the socket for the connection
+ * @param[out] c_tls the pointer to the allocated space for
+ *                   the connection TLS settings
+ * @return 'true' on success,
+ *         'false' otherwise
+ */
+#define mhd_tls_conn_init(d_tls,sk,c_tls)       \
+        mhd_TLS_FUNC (_conn_init)((d_tls),(sk),(c_tls))
+
+/**
+ * De-initialise connection TLS settings.
+ * The provided pointer is not freed/deallocated.
+ * @param c_tls the initialised connection TLS settings
+ */
+#define mhd_tls_conn_deinit(c_tls)       \
+        mhd_TLS_FUNC (_conn_deinit)((c_tls))
+
+
+/* ** General information function ** */
+
 /**
  * Result of TLS backend availability check
  */

+ 133 - 6
src/mhd2/tls_gnu_funcs.c

@@ -31,7 +31,9 @@
 
 #include <string.h>
 
+#include "mhd_socket_type.h"
 #include "mhd_str_types.h"
+
 #include "mhd_str_macros.h"
 #include "mhd_arr_num_elems.h"
 
@@ -39,9 +41,12 @@
 #include "sys_malloc.h"
 #include "mhd_assert.h"
 
+#include "mhd_conn_socket.h"
+
 #include "tls_gnu_tls_lib.h"
 
 #include "tls_gnu_daemon_data.h"
+#include "tls_gnu_conn_data.h"
 #include "tls_gnu_funcs.h"
 
 #include "daemon_options.h"
@@ -207,9 +212,9 @@ daemon_init_credentials (struct MHD_Daemon *restrict d,
   if (GNUTLS_E_SUCCESS !=
       gnutls_certificate_allocate_credentials (&(d_tls->cred)))
   {
-    mhd_LOG_MSG (d, MHD_SC_DAEMON_TLS_INIT_FAILED, \
+    mhd_LOG_MSG (d, MHD_SC_TLS_DAEMON_INIT_FAILED, \
                  "Failed to initialise TLS credentials for the daemon");
-    return MHD_SC_DAEMON_TLS_INIT_FAILED;
+    return MHD_SC_TLS_DAEMON_INIT_FAILED;
   }
 
   // TODO: Support multiple certificates
@@ -247,10 +252,10 @@ daemon_init_credentials (struct MHD_Daemon *restrict d,
     {
       if (! daemon_init_dh_data (d_tls))
       {
-        mhd_LOG_MSG (d, MHD_SC_DAEMON_TLS_INIT_FAILED, \
+        mhd_LOG_MSG (d, MHD_SC_TLS_DAEMON_INIT_FAILED, \
                      "Failed to initialise Diffie-Hellman parameters " \
                      "for the daemon");
-        ret = MHD_SC_DAEMON_TLS_INIT_FAILED;
+        ret = MHD_SC_TLS_DAEMON_INIT_FAILED;
       }
       else
         return MHD_SC_OK;
@@ -337,9 +342,9 @@ daemon_init_priorities_cache (struct MHD_Daemon *restrict d,
   if (i < mhd_ARR_NUM_ELEMS (tlsgnulib_base_priorities))
     return MHD_SC_OK; /* Success exit point */
 
-  mhd_LOG_MSG (d, MHD_SC_DAEMON_TLS_INIT_FAILED, \
+  mhd_LOG_MSG (d, MHD_SC_TLS_DAEMON_INIT_FAILED, \
                "Failed to initialise TLS priorities cache");
-  return MHD_SC_DAEMON_TLS_INIT_FAILED;
+  return MHD_SC_TLS_DAEMON_INIT_FAILED;
 }
 
 
@@ -409,3 +414,125 @@ mhd_tls_gnu_daemon_deinit (struct mhd_TlsGnuDaemonData *restrict d_tls)
   daemon_deinit_credentials (d_tls);
   free (d_tls);
 }
+
+
+/* ** Connection initialisation ** */
+
+MHD_INTERNAL size_t
+mhd_tls_gnu_conn_get_tls_size (void)
+{
+  return sizeof (struct mhd_TlsGnuConnData);
+}
+
+
+MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_OUT_ (3) bool
+mhd_tls_gnu_conn_init (const struct mhd_TlsGnuDaemonData *restrict d_tls,
+                       const struct mhd_ConnSocket *sk,
+                       struct mhd_TlsGnuConnData *restrict c_tls)
+{
+  unsigned int c_flags;
+  int res;
+
+  c_flags = GNUTLS_SERVER;
+#if GNUTLS_VERSION_NUMBER >= 0x030000
+  /* Note: the proper support for the blocking sockets may require use of
+     gnutls_handshake_set_timeout() and
+     gnutls_transport_set_pull_timeout_function() (the latter is not actually
+     required for the modern GnuTLS versions at least) */
+  if (sk->props.is_nonblck)
+    c_flags |= GNUTLS_NONBLOCK;
+#endif
+#ifdef mhd_TLS_GNU_HAS_NO_SIGNAL
+  c_flags |= GNUTLS_NO_SIGNAL;
+#endif
+
+  if (GNUTLS_E_SUCCESS !=
+      gnutls_init (&(c_tls->sess),
+                   c_flags))
+    return false;
+
+#if GNUTLS_VERSION_NUMBER >= 0x030100
+  if (! sk->props.is_nonblck)
+    gnutls_handshake_set_timeout (c_tls->sess,
+                                  GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
+#endif
+#if ! defined(mhd_TLS_GNU_NULL_PRIO_CACHE_MEANS_DEF_PRIORITY)
+  mhd_assert (NULL != d_tls->pri_cache);
+#else
+  if (NULL == d_tls->pri_cache)
+    res = gnutls_set_default_priority (c_tls->sess);
+  else
+#endif
+  res = gnutls_priority_set (c_tls->sess,
+                             d_tls->pri_cache);
+
+  if (GNUTLS_E_SUCCESS == res)
+  {
+    if (GNUTLS_E_SUCCESS ==
+        gnutls_credentials_set (c_tls->sess,
+                                GNUTLS_CRD_CERTIFICATE,
+                                d_tls->cred))
+    {
+#ifdef mhd_TLS_GNU_HAS_TRANSP_SET_INT
+      if (sizeof(int) == sizeof(MHD_Socket))
+        gnutls_transport_set_int (c_tls->sess,
+                                  (int) sk->fd);
+#endif /* mhd_TLS_GNU_HAS_TRANSP_SET_INT */
+      gnutls_transport_set_ptr (c_tls->sess,
+                                (void *) sk->fd);
+
+      /* The basic TLS session properties has been set.
+         The rest is optional settings. */
+#ifdef mhd_TLS_GNU_HAS_ALPN
+      if (1)
+      {
+        static const char alpn_http_1_0[] = "http/1.0"; /* Registered value for HTTP/1.0 */
+        static const char alpn_http_1_1[] = "http/1.1"; /* Registered value for HTTP/1.1 */
+#  if 0 /* Disabled code */
+        static const char alpn_http_2[] = "h2"; /* Registered value for HTTP/2 over TLS */
+        static const char alpn_http_3[] = "h3"; /* Registered value for HTTP/3 */
+#  endif
+        gnutls_datum_t prots[] = {
+          { mhd_DROP_CONST (alpn_http_1_1), mhd_SSTR_LEN (alpn_http_1_1) }
+          ,
+          { mhd_DROP_CONST (alpn_http_1_0), mhd_SSTR_LEN (alpn_http_1_0) }
+        };
+        unsigned int alpn_flags;
+        int alpn_res;
+
+        alpn_flags = 0;
+#  if 0
+        alpn_flags |= GNUTLS_ALPN_SERVER_PRECEDENCE;
+#  endif
+
+        alpn_res =
+          gnutls_alpn_set_protocols (c_tls->sess,
+                                     prots,
+                                     (unsigned int) mhd_ARR_NUM_ELEMS (prots),
+                                     alpn_flags);
+        (void) alpn_res; /* Ignore any possible ALPN set errors */
+      }
+#endif /* mhd_TLS_GNU_HAS_ALPN */
+
+      return true; /* Success exit point */
+    }
+    /* Below is a clean-up code path */
+  }
+
+  gnutls_deinit (c_tls->sess);
+  return false; /* Failure exit point */
+}
+
+
+/**
+ * De-initialise connection TLS settings.
+ * The provided pointer is not freed/deallocated.
+ * @param c_tls the initialised connection TLS settings
+ */
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void
+mhd_tls_gnu_conn_deinit (struct mhd_TlsGnuConnData *restrict c_tls)
+{
+  mhd_assert (NULL != c_tls->sess);
+  gnutls_deinit (c_tls->sess);
+}

+ 38 - 0
src/mhd2/tls_gnu_funcs.h

@@ -33,6 +33,9 @@
 #error This header can be used only if GnuTLS is enabled
 #endif
 
+#include "sys_bool_type.h"
+#include "sys_base_types.h"
+
 #include "mhd_status_code_int.h"
 
 /**
@@ -102,4 +105,39 @@ MHD_INTERNAL void
 mhd_tls_gnu_daemon_deinit (struct mhd_TlsGnuDaemonData *restrict d_tls)
 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1);
 
+
+/* ** Connection initialisation / de-initialisation ** */
+
+struct mhd_ConnSocket; /* Forward declaration */
+
+/**
+ * Get size size of the connection's TLS settings
+ */
+MHD_INTERNAL size_t
+mhd_tls_gnu_conn_get_tls_size (void);
+
+/**
+ * Initialise connection TLS settings
+ * @param d_tls the daemon TLS settings
+ * @param sk data about the socket for the connection
+ * @param[out] c_tls the pointer to the allocated space for
+ *                   the connection TLS settings
+ * @return 'true' on success,
+ *         'false' otherwise
+ */
+MHD_INTERNAL bool
+mhd_tls_gnu_conn_init (const struct mhd_TlsGnuDaemonData *restrict d_tls,
+                       const struct mhd_ConnSocket *sk,
+                       struct mhd_TlsGnuConnData *restrict c_tls)
+MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_ (3);
+
+/**
+ * De-initialise connection TLS settings.
+ * The provided pointer is not freed/deallocated.
+ * @param c_tls the initialised connection TLS settings
+ */
+MHD_INTERNAL void
+mhd_tls_gnu_conn_deinit (struct mhd_TlsGnuConnData *restrict c_tls)
+MHD_FN_PAR_NONNULL_ALL_;
+
 #endif /* ! MHD_TLS_GNU_FUNCS_H */

+ 22 - 0
src/mhd2/tls_gnu_tls_lib.h

@@ -100,4 +100,26 @@
 #  define mhd_TLS_GNU_SUPPORTS_MULTI_KEYWORDS_PRIORITY  1
 #endif
 
+#if GNUTLS_VERSION_NUMBER >= 0x030402
+/**
+ * Defined if GNUTLS_NO_SIGNAL flag is available for gnutls_init() function
+ */
+#  define mhd_TLS_GNU_HAS_NO_SIGNAL     1
+#endif
+
+#if GNUTLS_VERSION_NUMBER >= 0x030109
+/**
+ * Defined if transport_set_int() function is available
+ */
+#  define mhd_TLS_GNU_HAS_TRANSP_SET_INT        1
+#endif
+
+#if GNUTLS_VERSION_NUMBER >= 0x030200
+/**
+ * Defined if gnutls_alpn_set_protocols() and
+ * gnutls_alpn_get_selected_protocol() function are available
+ */
+#  define mhd_TLS_GNU_HAS_ALPN        1
+#endif
+
 #endif /* ! MHD_TLS_GNU_TLS_LIB_H */