From e0a91f631bfe02c3e36f77ed01daef206bf14594 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Wed, 19 Feb 2025 13:49:30 -0800 Subject: [PATCH] src: gate all quic behind disabled-by-default compile flag Due to https://github.com/quictls/openssl/commit/93ae85bd193cfe8d19cfbfb75159a8c8ae003b8d it is clear that we will need to revert back to using OpenSSL's official releases. This means we will be forced to re-implement at least part of the underlying QUIC implementation to use different crypto APIs. For that reason, this PR disables building any of the QUIC support by default and introduces a new compile time flag. PR-URL: https://github.com/nodejs/node/pull/57142 Reviewed-By: Yagiz Nizipli Reviewed-By: Jordan Harband Reviewed-By: Marco Ippolito Reviewed-By: Michael Dawson Reviewed-By: Chengzhong Wu Reviewed-By: Richard Lau Reviewed-By: Trivikram Kamat Reviewed-By: Stephen Belanger Reviewed-By: Matteo Collina Reviewed-By: Joyee Cheung --- configure.py | 17 +++++++------- node.gyp | 6 ++++- src/node_options.cc | 6 +++++ src/node_options.h | 2 ++ test/common/index.js | 2 +- ...rocess-env-allowed-flags-are-documented.js | 4 +++- tools/getsharedopensslhasquic.py | 23 ------------------- 7 files changed, 26 insertions(+), 34 deletions(-) delete mode 100644 tools/getsharedopensslhasquic.py diff --git a/configure.py b/configure.py index 8baf075384671e..f2dac8aab26555 100755 --- a/configure.py +++ b/configure.py @@ -38,7 +38,6 @@ sys.path.insert(0, 'tools') import getmoduleversion import getnapibuildversion -import getsharedopensslhasquic from gyp_node import run_gyp from utils import SearchFiles @@ -847,6 +846,12 @@ # End dummy list. +parser.add_argument('--with-quic', + action='store_true', + dest='quic', + default=None, + help='build with QUIC support') + parser.add_argument('--without-ssl', action='store_true', dest='without_ssl', @@ -1743,6 +1748,7 @@ def configure_openssl(o): variables['node_shared_ngtcp2'] = b(options.shared_ngtcp2) variables['node_shared_nghttp3'] = b(options.shared_nghttp3) variables['openssl_is_fips'] = b(options.openssl_is_fips) + variables['node_quic'] = b(options.quic) variables['node_fipsinstall'] = b(False) if options.openssl_no_asm: @@ -1804,13 +1810,8 @@ def without_ssl_error(option): if options.openssl_is_fips and not options.shared_openssl: variables['node_fipsinstall'] = b(True) - if options.shared_openssl: - has_quic = getsharedopensslhasquic.get_has_quic(options.__dict__['shared_openssl_includes']) - else: - has_quic = getsharedopensslhasquic.get_has_quic('deps/openssl/openssl/include') - - variables['openssl_quic'] = b(has_quic) - if has_quic: + variables['openssl_quic'] = b(options.quic) + if options.quic: o['defines'] += ['NODE_OPENSSL_HAS_QUIC'] configure_library('openssl', o) diff --git a/node.gyp b/node.gyp index ba1f50d7541cca..42a1160ad4af7b 100644 --- a/node.gyp +++ b/node.gyp @@ -927,12 +927,16 @@ [ 'node_use_openssl=="true"', { 'sources': [ '<@(node_crypto_sources)', - '<@(node_quic_sources)', ], 'dependencies': [ 'deps/ncrypto/ncrypto.gyp:ncrypto', ], }], + [ 'node_quic=="true"', { + 'sources': [ + '<@(node_quic_sources)', + ], + }], [ 'OS in "linux freebsd mac solaris" and ' 'target_arch=="x64" and ' 'node_target_type=="executable"', { diff --git a/src/node_options.cc b/src/node_options.cc index 8b0d7b0fdfdcbe..1d54b1ddf0987e 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -443,7 +443,13 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { true); AddOption("--experimental-quic", "" /* undocumented until its development */, +#ifdef NODE_OPENSSL_HAS_QUIC &EnvironmentOptions::experimental_quic, +#else + // Option is a no-op if the NODE_OPENSSL_HAS_QUIC + // compile flag is not enabled + NoOp{}, +#endif kAllowedInEnvvar); AddOption("--experimental-webstorage", "experimental Web Storage API", diff --git a/src/node_options.h b/src/node_options.h index 3c4d2f853f2b35..6b8e812321c1ae 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -127,7 +127,9 @@ class EnvironmentOptions : public Options { bool experimental_websocket = true; bool experimental_sqlite = true; bool experimental_webstorage = false; +#ifdef NODE_OPENSSL_HAS_QUIC bool experimental_quic = false; +#endif std::string localstorage_file; bool experimental_global_navigator = true; bool experimental_global_web_crypto = true; diff --git a/test/common/index.js b/test/common/index.js index e27603cda8741e..cf920fcc49d258 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -54,7 +54,7 @@ const noop = () => {}; const hasCrypto = Boolean(process.versions.openssl) && !process.env.NODE_SKIP_CRYPTO; -const hasQuic = hasCrypto && !!process.config.variables.openssl_quic; +const hasQuic = hasCrypto && !!process.config.variables.node_quic; function parseTestFlags(filename = process.argv[1]) { // The copyright notice is relatively big and the flags could come afterwards. diff --git a/test/parallel/test-process-env-allowed-flags-are-documented.js b/test/parallel/test-process-env-allowed-flags-are-documented.js index 4706cc018220ea..1522e5b865cbcd 100644 --- a/test/parallel/test-process-env-allowed-flags-are-documented.js +++ b/test/parallel/test-process-env-allowed-flags-are-documented.js @@ -130,7 +130,9 @@ assert(undocumented.delete('--no-verify-base-objects')); assert(undocumented.delete('--trace-promises')); assert(undocumented.delete('--no-trace-promises')); assert(undocumented.delete('--experimental-quic')); -assert(undocumented.delete('--no-experimental-quic')); +if (common.hasQuic) { + assert(undocumented.delete('--no-experimental-quic')); +} // Remove negated versions of the flags. for (const flag of undocumented) { diff --git a/tools/getsharedopensslhasquic.py b/tools/getsharedopensslhasquic.py deleted file mode 100644 index f4349285e2f125..00000000000000 --- a/tools/getsharedopensslhasquic.py +++ /dev/null @@ -1,23 +0,0 @@ -from __future__ import print_function -import os -import re - -def get_has_quic(include_path): - if include_path: - openssl_quic_h = os.path.join( - include_path, - 'openssl', - 'quic.h') - - try: - f = open(openssl_quic_h) - except OSError: - return False - - regex = r'^#\s*define OPENSSL_INFO_QUIC' - - for line in f: - if (re.match(regex, line)): - return True - - return False