From 595362ef2c16bbca684a5d8e9fd6c416894444b0 Mon Sep 17 00:00:00 2001 From: Jacob Champion Date: Tue, 4 Feb 2025 11:37:44 -0800 Subject: [PATCH v47 05/11] fixup! Add OAUTHBEARER SASL mechanism --- config/programs.m4 | 23 ++++++++++ configure | 53 +++++++++++++++++++++++ meson.build | 34 +++++++++++++++ src/interfaces/libpq/fe-auth-oauth-curl.c | 15 ++----- 4 files changed, 114 insertions(+), 11 deletions(-) diff --git a/config/programs.m4 b/config/programs.m4 index 86a3750f9e5..ead427046f5 100644 --- a/config/programs.m4 +++ b/config/programs.m4 @@ -315,4 +315,27 @@ AC_DEFUN([PGAC_CHECK_LIBCURL], AC_DEFINE(HAVE_THREADSAFE_CURL_GLOBAL_INIT, 1, [Define to 1 if curl_global_init() is guaranteed to be threadsafe.]) fi + + # Warn if a thread-friendly DNS resolver isn't built. + AC_CACHE_CHECK([for curl support for asynchronous DNS], [pgac_cv__libcurl_async_dns], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([ +#include +],[ + curl_version_info_data *info; + + if (curl_global_init(CURL_GLOBAL_ALL)) + return -1; + + info = curl_version_info(CURLVERSION_NOW); + return (info->features & CURL_VERSION_ASYNCHDNS) ? 0 : 1; +])], + [pgac_cv__libcurl_async_dns=yes], + [pgac_cv__libcurl_async_dns=no], + [pgac_cv__libcurl_async_dns=unknown])]) + if test x"$pgac_cv__libcurl_async_dns" != xyes ; then + AC_MSG_WARN([ +*** The installed version of libcurl does not support asynchronous DNS +*** lookups. Connection timeouts will not be honored during DNS resolution, +*** which may lead to hangs in client programs.]) + fi ])# PGAC_CHECK_LIBCURL diff --git a/configure b/configure index 33422d24112..93fddd69981 100755 --- a/configure +++ b/configure @@ -12493,6 +12493,59 @@ $as_echo "#define HAVE_THREADSAFE_CURL_GLOBAL_INIT 1" >>confdefs.h fi + # Warn if a thread-friendly DNS resolver isn't built. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curl support for asynchronous DNS" >&5 +$as_echo_n "checking for curl support for asynchronous DNS... " >&6; } +if ${pgac_cv__libcurl_async_dns+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + pgac_cv__libcurl_async_dns=unknown +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + + curl_version_info_data *info; + + if (curl_global_init(CURL_GLOBAL_ALL)) + return -1; + + info = curl_version_info(CURLVERSION_NOW); + return (info->features & CURL_VERSION_ASYNCHDNS) ? 0 : 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + pgac_cv__libcurl_async_dns=yes +else + pgac_cv__libcurl_async_dns=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__libcurl_async_dns" >&5 +$as_echo "$pgac_cv__libcurl_async_dns" >&6; } + if test x"$pgac_cv__libcurl_async_dns" != xyes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +*** The installed version of libcurl does not support asynchronous DNS +*** lookups. Connection timeouts will not be honored during DNS resolution, +*** which may lead to hangs in client programs." >&5 +$as_echo "$as_me: WARNING: +*** The installed version of libcurl does not support asynchronous DNS +*** lookups. Connection timeouts will not be honored during DNS resolution, +*** which may lead to hangs in client programs." >&2;} + fi + fi if test "$with_gssapi" = yes ; then diff --git a/meson.build b/meson.build index 80a6b1d57d6..96e5f0f6434 100644 --- a/meson.build +++ b/meson.build @@ -907,6 +907,40 @@ if not libcurlopt.disabled() if libcurl_threadsafe_init cdata.set('HAVE_THREADSAFE_CURL_GLOBAL_INIT', 1) endif + + # Warn if a thread-friendly DNS resolver isn't built. + libcurl_async_dns = false + + if not meson.is_cross_build() + r = cc.run(''' + #include + + int main(void) + { + curl_version_info_data *info; + + if (curl_global_init(CURL_GLOBAL_ALL)) + return -1; + + info = curl_version_info(CURLVERSION_NOW); + return (info->features & CURL_VERSION_ASYNCHDNS) ? 0 : 1; + }''', + name: 'test for curl support for asynchronous DNS', + dependencies: libcurl, + ) + + assert(r.compiled()) + if r.returncode() == 0 + libcurl_async_dns = true + endif + endif + + if not libcurl_async_dns + warning(''' +*** The installed version of libcurl does not support asynchronous DNS +*** lookups. Connection timeouts will not be honored during DNS resolution, +*** which may lead to hangs in client programs.''') + endif endif else diff --git a/src/interfaces/libpq/fe-auth-oauth-curl.c b/src/interfaces/libpq/fe-auth-oauth-curl.c index dc47a7bdf11..b6255834f00 100644 --- a/src/interfaces/libpq/fe-auth-oauth-curl.c +++ b/src/interfaces/libpq/fe-auth-oauth-curl.c @@ -1339,8 +1339,6 @@ debug_callback(CURL *handle, curl_infotype type, char *data, size_t size, static bool setup_curl_handles(struct async_ctx *actx) { - curl_version_info_data *curl_info; - /* * Create our multi handle. This encapsulates the entire conversation with * libcurl for this connection. @@ -1353,11 +1351,6 @@ setup_curl_handles(struct async_ctx *actx) return false; } - /* - * Extract information about the libcurl we are linked against. - */ - curl_info = curl_version_info(CURLVERSION_NOW); - /* * The multi handle tells us what to wait on using two callbacks. These * will manipulate actx->mux as needed. @@ -1382,12 +1375,12 @@ setup_curl_handles(struct async_ctx *actx) * Multi-threaded applications must set CURLOPT_NOSIGNAL. This requires us * to handle the possibility of SIGPIPE ourselves using pq_block_sigpipe; * see pg_fe_run_oauth_flow(). + * + * NB: If libcurl is not built against a friendly DNS resolver (c-ares or + * threaded), setting this option prevents DNS lookups from timing out + * correctly. We warn about this situation at configure time. */ CHECK_SETOPT(actx, CURLOPT_NOSIGNAL, 1L, return false); - if (!curl_info->ares_num) - { - /* No alternative resolver, TODO: warn about timeouts */ - } if (actx->debugging) { -- 2.34.1