]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
CMake: add HTTP/3 support (ngtcp2+nghttp3, quiche)
authorPeter Wu <peter@lekensteyn.nl>
Fri, 8 May 2020 21:13:46 +0000 (23:13 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 10 May 2020 21:36:41 +0000 (23:36 +0200)
Add three new CMake Find modules (using the curl license, but I grant
others the right to apply the CMake BSD license instead).

This CMake config is simpler than the autotools one because it assumes
ngtcp2 and nghttp3 to be used together. Another difference is that this
CMake config checks whether QUIC is actually supported by the TLS
library (patched OpenSSL or boringssl) since this can be a common
configuration mistake that could result in build errors later.

Unlike autotools, CMake does not warn you that the features are
experimental. The user is supposed to already know that and read the
documentation. It requires a very special build environment anyway.

Tested with ngtcp2+OpenSSL+nghttp3 and quiche+boringssl, both built from
current git master. Use `LD_DEBUG=files src/curl |& grep need` to figure
out which features (libldap-2.4, libssh2) to disable due to conflicts
with boringssl.

Closes #5359

CMake/FindNGHTTP3.cmake [new file with mode: 0644]
CMake/FindNGTCP2.cmake [new file with mode: 0644]
CMake/FindQUICHE.cmake [new file with mode: 0644]
CMakeLists.txt
Makefile.am
lib/curl_config.h.cmake

diff --git a/CMake/FindNGHTTP3.cmake b/CMake/FindNGHTTP3.cmake
new file mode 100644 (file)
index 0000000..73ce9e1
--- /dev/null
@@ -0,0 +1,76 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindNGHTTP3
+----------
+
+Find the nghttp3 library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``NGHTTP3_FOUND``
+  System has nghttp3
+``NGHTTP3_INCLUDE_DIRS``
+  The nghttp3 include directories.
+``NGHTTP3_LIBRARIES``
+  The libraries needed to use nghttp3
+``NGHTTP3_VERSION``
+  version of nghttp3.
+#]=======================================================================]
+
+if(UNIX)
+  find_package(PkgConfig QUIET)
+  pkg_search_module(PC_NGHTTP3 libnghttp3)
+endif()
+
+find_path(NGHTTP3_INCLUDE_DIR nghttp3/nghttp3.h
+  HINTS
+    ${PC_NGHTTP3_INCLUDEDIR}
+    ${PC_NGHTTP3_INCLUDE_DIRS}
+)
+
+find_library(NGHTTP3_LIBRARY NAMES nghttp3
+  HINTS
+    ${PC_NGHTTP3_LIBDIR}
+    ${PC_NGHTTP3_LIBRARY_DIRS}
+)
+
+if(PC_NGHTTP3_VERSION)
+  set(NGHTTP3_VERSION ${PC_NGHTTP3_VERSION})
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NGHTTP3
+  REQUIRED_VARS
+    NGHTTP3_LIBRARY
+    NGHTTP3_INCLUDE_DIR
+  VERSION_VAR NGHTTP3_VERSION
+)
+
+if(NGHTTP3_FOUND)
+  set(NGHTTP3_LIBRARIES    ${NGHTTP3_LIBRARY})
+  set(NGHTTP3_INCLUDE_DIRS ${NGHTTP3_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(NGHTTP3_INCLUDE_DIRS NGHTTP3_LIBRARIES)
diff --git a/CMake/FindNGTCP2.cmake b/CMake/FindNGTCP2.cmake
new file mode 100644 (file)
index 0000000..a1ed8cd
--- /dev/null
@@ -0,0 +1,113 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindNGTCP2
+----------
+
+Find the ngtcp2 library
+
+This module accepts optional COMPONENTS to control the crypto library (these are
+mutually exclusive)::
+
+  OpenSSL:  Use libngtcp2_crypto_openssl
+  GnuTLS:   Use libngtcp2_crypto_gnutls
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``NGTCP2_FOUND``
+  System has ngtcp2
+``NGTCP2_INCLUDE_DIRS``
+  The ngtcp2 include directories.
+``NGTCP2_LIBRARIES``
+  The libraries needed to use ngtcp2
+``NGTCP2_VERSION``
+  version of ngtcp2.
+#]=======================================================================]
+
+if(UNIX)
+  find_package(PkgConfig QUIET)
+  pkg_search_module(PC_NGTCP2 libngtcp2)
+endif()
+
+find_path(NGTCP2_INCLUDE_DIR ngtcp2/ngtcp2.h
+  HINTS
+    ${PC_NGTCP2_INCLUDEDIR}
+    ${PC_NGTCP2_INCLUDE_DIRS}
+)
+
+find_library(NGTCP2_LIBRARY NAMES ngtcp2
+  HINTS
+    ${PC_NGTCP2_LIBDIR}
+    ${PC_NGTCP2_LIBRARY_DIRS}
+)
+
+if(PC_NGTCP2_VERSION)
+  set(NGTCP2_VERSION ${PC_NGTCP2_VERSION})
+endif()
+
+if(NGTCP2_FIND_COMPONENTS)
+  set(NGTCP2_CRYPTO_BACKEND "")
+  foreach(component IN LISTS NGTCP2_FIND_COMPONENTS)
+    if(component MATCHES "^(OpenSSL|GnuTLS)")
+      if(NGTCP2_CRYPTO_BACKEND)
+        message(FATAL_ERROR "NGTCP2: Only one crypto library can be selected")
+      endif()
+      set(NGTCP2_CRYPTO_BACKEND ${component})
+    endif()
+  endforeach()
+
+  if(NGTCP2_CRYPTO_BACKEND)
+    string(TOLOWER "ngtcp2_crypto_${NGTCP2_CRYPTO_BACKEND}" _crypto_library)
+    if(UNIX)
+      pkg_search_module(PC_${_crypto_library} lib${_crypto_library})
+    endif()
+    find_library(${_crypto_library}_LIBRARY
+      NAMES
+        ${_crypto_library}
+      HINTS
+        ${PC_${_crypto_library}_LIBDIR}
+        ${PC_${_crypto_library}_LIBRARY_DIRS}
+    )
+    if(${_crypto_library}_LIBRARY)
+      set(NGTCP2_${NGTCP2_CRYPTO_BACKEND}_FOUND TRUE)
+      set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library}_LIBRARY})
+    endif()
+  endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NGTCP2
+  REQUIRED_VARS
+    NGTCP2_LIBRARY
+    NGTCP2_INCLUDE_DIR
+  VERSION_VAR NGTCP2_VERSION
+  HANDLE_COMPONENTS
+)
+
+if(NGTCP2_FOUND)
+  set(NGTCP2_LIBRARIES    ${NGTCP2_LIBRARY} ${NGTCP2_CRYPTO_LIBRARY})
+  set(NGTCP2_INCLUDE_DIRS ${NGTCP2_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(NGTCP2_INCLUDE_DIRS NGTCP2_LIBRARIES)
diff --git a/CMake/FindQUICHE.cmake b/CMake/FindQUICHE.cmake
new file mode 100644 (file)
index 0000000..01d1758
--- /dev/null
@@ -0,0 +1,68 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindQUICHE
+----------
+
+Find the quiche library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``QUICHE_FOUND``
+  System has quiche
+``QUICHE_INCLUDE_DIRS``
+  The quiche include directories.
+``QUICHE_LIBRARIES``
+  The libraries needed to use quiche
+#]=======================================================================]
+if(UNIX)
+  find_package(PkgConfig QUIET)
+  pkg_search_module(PC_QUICHE quiche)
+endif()
+
+find_path(QUICHE_INCLUDE_DIR quiche.h
+  HINTS
+    ${PC_QUICHE_INCLUDEDIR}
+    ${PC_QUICHE_INCLUDE_DIRS}
+)
+
+find_library(QUICHE_LIBRARY NAMES quiche
+  HINTS
+    ${PC_QUICHE_LIBDIR}
+    ${PC_QUICHE_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(QUICHE
+  REQUIRED_VARS
+    QUICHE_LIBRARY
+    QUICHE_INCLUDE_DIR
+)
+
+if(QUICHE_FOUND)
+  set(QUICHE_LIBRARIES    ${QUICHE_LIBRARY})
+  set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(QUICHE_INCLUDE_DIRS QUICHE_LIBRARIES)
index b8061d14d7f89f4f1720c4f953e0c4d35cfec0d6..616a70db641d7dfc8e28ac2f43d4ea24d6f7dc5a 100644 (file)
@@ -438,6 +438,56 @@ if(USE_NGHTTP2)
   list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
 endif()
 
+function(CheckQuicSupportInOpenSSL)
+  # Be sure that the OpenSSL library actually supports QUIC.
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_INCLUDES   "${OPENSSL_INCLUDE_DIR}")
+  set(CMAKE_REQUIRED_LIBRARIES  "${OPENSSL_LIBRARIES}")
+  check_symbol_exists(SSL_CTX_set_quic_method "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD)
+  if(NOT HAVE_SSL_CTX_SET_QUIC_METHOD)
+    message(FATAL_ERROR "QUIC support is missing in OpenSSL/boringssl. Try setting -DOPENSSL_ROOT_DIR")
+  endif()
+  cmake_pop_check_state()
+endfunction()
+
+option(USE_NGTCP2 "Use ngtcp2 and nghttp3 libraries for HTTP/3 support" OFF)
+if(USE_NGTCP2)
+  if(USE_OPENSSL)
+    find_package(NGTCP2 REQUIRED OpenSSL)
+    CheckQuicSupportInOpenSSL()
+  elseif(USE_GNUTLS)
+    # TODO add GnuTLS support as vtls library.
+    find_package(NGTCP2 REQUIRED GnuTLS)
+  else()
+    message(FATAL_ERROR "ngtcp2 requires OpenSSL or GnuTLS")
+  endif()
+  set(USE_NGTCP2 ON)
+  include_directories(${NGTCP2_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${NGTCP2_LIBRARIES})
+
+  find_package(NGHTTP3 REQUIRED)
+  set(USE_NGHTTP3 ON)
+  include_directories(${NGHTTP3_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${NGHTTP3_LIBRARIES})
+endif()
+
+option(USE_QUICHE "Use quiche library for HTTP/3 support" OFF)
+if(USE_QUICHE)
+  if(USE_NGTCP2)
+    message(FATAL_ERROR "Only one HTTP/3 backend can be selected!")
+  endif()
+  find_package(QUICHE REQUIRED)
+  CheckQuicSupportInOpenSSL()
+  set(USE_QUICHE ON)
+  include_directories(${QUICHE_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${QUICHE_LIBRARIES})
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_INCLUDES   "${QUICHE_INCLUDE_DIRS}")
+  set(CMAKE_REQUIRED_LIBRARIES  "${QUICHE_LIBRARIES}")
+  check_symbol_exists(quiche_conn_set_qlog_fd "quiche.h" HAVE_QUICHE_CONN_SET_QLOG_FD)
+  cmake_pop_check_state()
+endif()
+
 if(WIN32)
   set(USE_WIN32_CRYPTO ON)
 endif()
@@ -1276,6 +1326,7 @@ _add_if("NTLM_WB"     use_ntlm AND NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
 _add_if("TLS-SRP"       USE_TLS_SRP)
 # TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header
 _add_if("HTTP2"         USE_NGHTTP2)
+_add_if("HTTP3"         USE_NGTCP2 OR USE_QUICHE)
 _add_if("HTTPS-proxy"   SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS OR USE_NSS))
 string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
 message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
index 2f70980335d11e9171840fbe75a6cab0cc36aa67..b9632770dd7cbb077b6c7bfe3ca58a46e2c18c32 100644 (file)
@@ -36,6 +36,9 @@ CMAKE_DIST =                                    \
  CMake/FindLibSSH2.cmake                        \
  CMake/FindMbedTLS.cmake                        \
  CMake/FindNGHTTP2.cmake                        \
+ CMake/FindNGHTTP3.cmake                        \
+ CMake/FindNGTCP2.cmake                         \
+ CMake/FindQUICHE.cmake                         \
  CMake/FindWolfSSL.cmake                        \
  CMake/Macros.cmake                             \
  CMake/OtherTests.cmake                         \
index 57a86e50ac918d58632a0319a0164bf4e30de4ce..7a77e94829c3b8a4ec2f90043ffe5c02b495e91c 100644 (file)
@@ -990,6 +990,18 @@ ${SIZEOF_TIME_T_CODE}
 /* to enable NGHTTP2  */
 #cmakedefine USE_NGHTTP2 1
 
+/* to enable NGTCP2 */
+#cmakedefine USE_NGTCP2 1
+
+/* to enable NGHTTP3  */
+#cmakedefine USE_NGHTTP3 1
+
+/* to enable quiche */
+#cmakedefine USE_QUICHE 1
+
+/* Define to 1 if you have the quiche_conn_set_qlog_fd function. */
+#cmakedefine HAVE_QUICHE_CONN_SET_QLOG_FD 1
+
 /* if Unix domain sockets are enabled  */
 #cmakedefine USE_UNIX_SOCKETS