113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci 2513498266Sopenharmony_ci#include "curl_setup.h" 2613498266Sopenharmony_ci 2713498266Sopenharmony_ci#ifdef USE_NGHTTP2 2813498266Sopenharmony_ci#include <nghttp2/nghttp2.h> 2913498266Sopenharmony_ci#endif 3013498266Sopenharmony_ci 3113498266Sopenharmony_ci#include <curl/curl.h> 3213498266Sopenharmony_ci#include "urldata.h" 3313498266Sopenharmony_ci#include "vtls/vtls.h" 3413498266Sopenharmony_ci#include "http2.h" 3513498266Sopenharmony_ci#include "vssh/ssh.h" 3613498266Sopenharmony_ci#include "vquic/vquic.h" 3713498266Sopenharmony_ci#include "curl_printf.h" 3813498266Sopenharmony_ci#include "easy_lock.h" 3913498266Sopenharmony_ci 4013498266Sopenharmony_ci#ifdef USE_ARES 4113498266Sopenharmony_ci# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ 4213498266Sopenharmony_ci defined(_WIN32) 4313498266Sopenharmony_ci# define CARES_STATICLIB 4413498266Sopenharmony_ci# endif 4513498266Sopenharmony_ci# include <ares.h> 4613498266Sopenharmony_ci#endif 4713498266Sopenharmony_ci 4813498266Sopenharmony_ci#ifdef USE_LIBIDN2 4913498266Sopenharmony_ci#include <idn2.h> 5013498266Sopenharmony_ci#endif 5113498266Sopenharmony_ci 5213498266Sopenharmony_ci#ifdef USE_LIBPSL 5313498266Sopenharmony_ci#include <libpsl.h> 5413498266Sopenharmony_ci#endif 5513498266Sopenharmony_ci 5613498266Sopenharmony_ci#ifdef USE_LIBRTMP 5713498266Sopenharmony_ci#include <librtmp/rtmp.h> 5813498266Sopenharmony_ci#endif 5913498266Sopenharmony_ci 6013498266Sopenharmony_ci#ifdef HAVE_LIBZ 6113498266Sopenharmony_ci#include <zlib.h> 6213498266Sopenharmony_ci#endif 6313498266Sopenharmony_ci 6413498266Sopenharmony_ci#ifdef HAVE_BROTLI 6513498266Sopenharmony_ci#if defined(__GNUC__) 6613498266Sopenharmony_ci/* Ignore -Wvla warnings in brotli headers */ 6713498266Sopenharmony_ci#pragma GCC diagnostic push 6813498266Sopenharmony_ci#pragma GCC diagnostic ignored "-Wvla" 6913498266Sopenharmony_ci#endif 7013498266Sopenharmony_ci#include <brotli/decode.h> 7113498266Sopenharmony_ci#if defined(__GNUC__) 7213498266Sopenharmony_ci#pragma GCC diagnostic pop 7313498266Sopenharmony_ci#endif 7413498266Sopenharmony_ci#endif 7513498266Sopenharmony_ci 7613498266Sopenharmony_ci#ifdef HAVE_ZSTD 7713498266Sopenharmony_ci#include <zstd.h> 7813498266Sopenharmony_ci#endif 7913498266Sopenharmony_ci 8013498266Sopenharmony_ci#ifdef USE_GSASL 8113498266Sopenharmony_ci#include <gsasl.h> 8213498266Sopenharmony_ci#endif 8313498266Sopenharmony_ci 8413498266Sopenharmony_ci#ifdef USE_OPENLDAP 8513498266Sopenharmony_ci#include <ldap.h> 8613498266Sopenharmony_ci#endif 8713498266Sopenharmony_ci 8813498266Sopenharmony_ci#ifdef HAVE_BROTLI 8913498266Sopenharmony_cistatic void brotli_version(char *buf, size_t bufsz) 9013498266Sopenharmony_ci{ 9113498266Sopenharmony_ci uint32_t brotli_version = BrotliDecoderVersion(); 9213498266Sopenharmony_ci unsigned int major = brotli_version >> 24; 9313498266Sopenharmony_ci unsigned int minor = (brotli_version & 0x00FFFFFF) >> 12; 9413498266Sopenharmony_ci unsigned int patch = brotli_version & 0x00000FFF; 9513498266Sopenharmony_ci (void)msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch); 9613498266Sopenharmony_ci} 9713498266Sopenharmony_ci#endif 9813498266Sopenharmony_ci 9913498266Sopenharmony_ci#ifdef HAVE_ZSTD 10013498266Sopenharmony_cistatic void zstd_version(char *buf, size_t bufsz) 10113498266Sopenharmony_ci{ 10213498266Sopenharmony_ci unsigned long zstd_version = (unsigned long)ZSTD_versionNumber(); 10313498266Sopenharmony_ci unsigned int major = (unsigned int)(zstd_version / (100 * 100)); 10413498266Sopenharmony_ci unsigned int minor = (unsigned int)((zstd_version - 10513498266Sopenharmony_ci (major * 100 * 100)) / 100); 10613498266Sopenharmony_ci unsigned int patch = (unsigned int)(zstd_version - 10713498266Sopenharmony_ci (major * 100 * 100) - (minor * 100)); 10813498266Sopenharmony_ci (void)msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch); 10913498266Sopenharmony_ci} 11013498266Sopenharmony_ci#endif 11113498266Sopenharmony_ci 11213498266Sopenharmony_ci/* 11313498266Sopenharmony_ci * curl_version() returns a pointer to a static buffer. 11413498266Sopenharmony_ci * 11513498266Sopenharmony_ci * It is implemented to work multi-threaded by making sure repeated invokes 11613498266Sopenharmony_ci * generate the exact same string and never write any temporary data like 11713498266Sopenharmony_ci * zeros in the data. 11813498266Sopenharmony_ci */ 11913498266Sopenharmony_ci 12013498266Sopenharmony_ci#define VERSION_PARTS 16 /* number of substrings we can concatenate */ 12113498266Sopenharmony_ci 12213498266Sopenharmony_cichar *curl_version(void) 12313498266Sopenharmony_ci{ 12413498266Sopenharmony_ci static char out[300]; 12513498266Sopenharmony_ci char *outp; 12613498266Sopenharmony_ci size_t outlen; 12713498266Sopenharmony_ci const char *src[VERSION_PARTS]; 12813498266Sopenharmony_ci#ifdef USE_SSL 12913498266Sopenharmony_ci char ssl_version[200]; 13013498266Sopenharmony_ci#endif 13113498266Sopenharmony_ci#ifdef HAVE_LIBZ 13213498266Sopenharmony_ci char z_version[40]; 13313498266Sopenharmony_ci#endif 13413498266Sopenharmony_ci#ifdef HAVE_BROTLI 13513498266Sopenharmony_ci char br_version[40] = "brotli/"; 13613498266Sopenharmony_ci#endif 13713498266Sopenharmony_ci#ifdef HAVE_ZSTD 13813498266Sopenharmony_ci char zst_version[40] = "zstd/"; 13913498266Sopenharmony_ci#endif 14013498266Sopenharmony_ci#ifdef USE_ARES 14113498266Sopenharmony_ci char cares_version[40]; 14213498266Sopenharmony_ci#endif 14313498266Sopenharmony_ci#if defined(USE_LIBIDN2) 14413498266Sopenharmony_ci char idn_version[40]; 14513498266Sopenharmony_ci#endif 14613498266Sopenharmony_ci#ifdef USE_LIBPSL 14713498266Sopenharmony_ci char psl_version[40]; 14813498266Sopenharmony_ci#endif 14913498266Sopenharmony_ci#ifdef USE_SSH 15013498266Sopenharmony_ci char ssh_version[40]; 15113498266Sopenharmony_ci#endif 15213498266Sopenharmony_ci#ifdef USE_NGHTTP2 15313498266Sopenharmony_ci char h2_version[40]; 15413498266Sopenharmony_ci#endif 15513498266Sopenharmony_ci#ifdef ENABLE_QUIC 15613498266Sopenharmony_ci char h3_version[40]; 15713498266Sopenharmony_ci#endif 15813498266Sopenharmony_ci#ifdef USE_LIBRTMP 15913498266Sopenharmony_ci char rtmp_version[40]; 16013498266Sopenharmony_ci#endif 16113498266Sopenharmony_ci#ifdef USE_HYPER 16213498266Sopenharmony_ci char hyper_buf[30]; 16313498266Sopenharmony_ci#endif 16413498266Sopenharmony_ci#ifdef USE_GSASL 16513498266Sopenharmony_ci char gsasl_buf[30]; 16613498266Sopenharmony_ci#endif 16713498266Sopenharmony_ci#ifdef USE_OPENLDAP 16813498266Sopenharmony_ci char ldap_buf[30]; 16913498266Sopenharmony_ci#endif 17013498266Sopenharmony_ci int i = 0; 17113498266Sopenharmony_ci int j; 17213498266Sopenharmony_ci 17313498266Sopenharmony_ci#ifdef DEBUGBUILD 17413498266Sopenharmony_ci /* Override version string when environment variable CURL_VERSION is set */ 17513498266Sopenharmony_ci const char *debugversion = getenv("CURL_VERSION"); 17613498266Sopenharmony_ci if(debugversion) { 17713498266Sopenharmony_ci strncpy(out, debugversion, sizeof(out)-1); 17813498266Sopenharmony_ci out[sizeof(out)-1] = '\0'; 17913498266Sopenharmony_ci return out; 18013498266Sopenharmony_ci } 18113498266Sopenharmony_ci#endif 18213498266Sopenharmony_ci 18313498266Sopenharmony_ci src[i++] = LIBCURL_NAME "/" LIBCURL_VERSION; 18413498266Sopenharmony_ci#ifdef USE_SSL 18513498266Sopenharmony_ci Curl_ssl_version(ssl_version, sizeof(ssl_version)); 18613498266Sopenharmony_ci src[i++] = ssl_version; 18713498266Sopenharmony_ci#endif 18813498266Sopenharmony_ci#ifdef HAVE_LIBZ 18913498266Sopenharmony_ci msnprintf(z_version, sizeof(z_version), "zlib/%s", zlibVersion()); 19013498266Sopenharmony_ci src[i++] = z_version; 19113498266Sopenharmony_ci#endif 19213498266Sopenharmony_ci#ifdef HAVE_BROTLI 19313498266Sopenharmony_ci brotli_version(&br_version[7], sizeof(br_version) - 7); 19413498266Sopenharmony_ci src[i++] = br_version; 19513498266Sopenharmony_ci#endif 19613498266Sopenharmony_ci#ifdef HAVE_ZSTD 19713498266Sopenharmony_ci zstd_version(&zst_version[5], sizeof(zst_version) - 5); 19813498266Sopenharmony_ci src[i++] = zst_version; 19913498266Sopenharmony_ci#endif 20013498266Sopenharmony_ci#ifdef USE_ARES 20113498266Sopenharmony_ci msnprintf(cares_version, sizeof(cares_version), 20213498266Sopenharmony_ci "c-ares/%s", ares_version(NULL)); 20313498266Sopenharmony_ci src[i++] = cares_version; 20413498266Sopenharmony_ci#endif 20513498266Sopenharmony_ci#ifdef USE_LIBIDN2 20613498266Sopenharmony_ci msnprintf(idn_version, sizeof(idn_version), 20713498266Sopenharmony_ci "libidn2/%s", idn2_check_version(NULL)); 20813498266Sopenharmony_ci src[i++] = idn_version; 20913498266Sopenharmony_ci#elif defined(USE_WIN32_IDN) 21013498266Sopenharmony_ci src[i++] = (char *)"WinIDN"; 21113498266Sopenharmony_ci#endif 21213498266Sopenharmony_ci 21313498266Sopenharmony_ci#ifdef USE_LIBPSL 21413498266Sopenharmony_ci { 21513498266Sopenharmony_ci int num = psl_check_version_number(0); 21613498266Sopenharmony_ci msnprintf(psl_version, sizeof(psl_version), "libpsl/%d.%d.%d", 21713498266Sopenharmony_ci num >> 16, (num >> 8) & 0xff, num & 0xff); 21813498266Sopenharmony_ci src[i++] = psl_version; 21913498266Sopenharmony_ci } 22013498266Sopenharmony_ci#endif 22113498266Sopenharmony_ci 22213498266Sopenharmony_ci#ifdef USE_SSH 22313498266Sopenharmony_ci Curl_ssh_version(ssh_version, sizeof(ssh_version)); 22413498266Sopenharmony_ci src[i++] = ssh_version; 22513498266Sopenharmony_ci#endif 22613498266Sopenharmony_ci#ifdef USE_NGHTTP2 22713498266Sopenharmony_ci Curl_http2_ver(h2_version, sizeof(h2_version)); 22813498266Sopenharmony_ci src[i++] = h2_version; 22913498266Sopenharmony_ci#endif 23013498266Sopenharmony_ci#ifdef ENABLE_QUIC 23113498266Sopenharmony_ci Curl_quic_ver(h3_version, sizeof(h3_version)); 23213498266Sopenharmony_ci src[i++] = h3_version; 23313498266Sopenharmony_ci#endif 23413498266Sopenharmony_ci#ifdef USE_LIBRTMP 23513498266Sopenharmony_ci { 23613498266Sopenharmony_ci char suff[2]; 23713498266Sopenharmony_ci if(RTMP_LIB_VERSION & 0xff) { 23813498266Sopenharmony_ci suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1; 23913498266Sopenharmony_ci suff[1] = '\0'; 24013498266Sopenharmony_ci } 24113498266Sopenharmony_ci else 24213498266Sopenharmony_ci suff[0] = '\0'; 24313498266Sopenharmony_ci 24413498266Sopenharmony_ci msnprintf(rtmp_version, sizeof(rtmp_version), "librtmp/%d.%d%s", 24513498266Sopenharmony_ci RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff, 24613498266Sopenharmony_ci suff); 24713498266Sopenharmony_ci src[i++] = rtmp_version; 24813498266Sopenharmony_ci } 24913498266Sopenharmony_ci#endif 25013498266Sopenharmony_ci#ifdef USE_HYPER 25113498266Sopenharmony_ci msnprintf(hyper_buf, sizeof(hyper_buf), "Hyper/%s", hyper_version()); 25213498266Sopenharmony_ci src[i++] = hyper_buf; 25313498266Sopenharmony_ci#endif 25413498266Sopenharmony_ci#ifdef USE_GSASL 25513498266Sopenharmony_ci msnprintf(gsasl_buf, sizeof(gsasl_buf), "libgsasl/%s", 25613498266Sopenharmony_ci gsasl_check_version(NULL)); 25713498266Sopenharmony_ci src[i++] = gsasl_buf; 25813498266Sopenharmony_ci#endif 25913498266Sopenharmony_ci#ifdef USE_OPENLDAP 26013498266Sopenharmony_ci { 26113498266Sopenharmony_ci LDAPAPIInfo api; 26213498266Sopenharmony_ci api.ldapai_info_version = LDAP_API_INFO_VERSION; 26313498266Sopenharmony_ci 26413498266Sopenharmony_ci if(ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) == LDAP_OPT_SUCCESS) { 26513498266Sopenharmony_ci unsigned int patch = api.ldapai_vendor_version % 100; 26613498266Sopenharmony_ci unsigned int major = api.ldapai_vendor_version / 10000; 26713498266Sopenharmony_ci unsigned int minor = 26813498266Sopenharmony_ci ((api.ldapai_vendor_version - major * 10000) - patch) / 100; 26913498266Sopenharmony_ci msnprintf(ldap_buf, sizeof(ldap_buf), "%s/%u.%u.%u", 27013498266Sopenharmony_ci api.ldapai_vendor_name, major, minor, patch); 27113498266Sopenharmony_ci src[i++] = ldap_buf; 27213498266Sopenharmony_ci ldap_memfree(api.ldapai_vendor_name); 27313498266Sopenharmony_ci ber_memvfree((void **)api.ldapai_extensions); 27413498266Sopenharmony_ci } 27513498266Sopenharmony_ci } 27613498266Sopenharmony_ci#endif 27713498266Sopenharmony_ci 27813498266Sopenharmony_ci DEBUGASSERT(i <= VERSION_PARTS); 27913498266Sopenharmony_ci 28013498266Sopenharmony_ci outp = &out[0]; 28113498266Sopenharmony_ci outlen = sizeof(out); 28213498266Sopenharmony_ci for(j = 0; j < i; j++) { 28313498266Sopenharmony_ci size_t n = strlen(src[j]); 28413498266Sopenharmony_ci /* we need room for a space, the string and the final zero */ 28513498266Sopenharmony_ci if(outlen <= (n + 2)) 28613498266Sopenharmony_ci break; 28713498266Sopenharmony_ci if(j) { 28813498266Sopenharmony_ci /* prepend a space if not the first */ 28913498266Sopenharmony_ci *outp++ = ' '; 29013498266Sopenharmony_ci outlen--; 29113498266Sopenharmony_ci } 29213498266Sopenharmony_ci memcpy(outp, src[j], n); 29313498266Sopenharmony_ci outp += n; 29413498266Sopenharmony_ci outlen -= n; 29513498266Sopenharmony_ci } 29613498266Sopenharmony_ci *outp = 0; 29713498266Sopenharmony_ci 29813498266Sopenharmony_ci return out; 29913498266Sopenharmony_ci} 30013498266Sopenharmony_ci 30113498266Sopenharmony_ci/* data for curl_version_info 30213498266Sopenharmony_ci 30313498266Sopenharmony_ci Keep the list sorted alphabetically. It is also written so that each 30413498266Sopenharmony_ci protocol line has its own #if line to make things easier on the eye. 30513498266Sopenharmony_ci */ 30613498266Sopenharmony_ci 30713498266Sopenharmony_cistatic const char * const supported_protocols[] = { 30813498266Sopenharmony_ci#ifndef CURL_DISABLE_DICT 30913498266Sopenharmony_ci "dict", 31013498266Sopenharmony_ci#endif 31113498266Sopenharmony_ci#ifndef CURL_DISABLE_FILE 31213498266Sopenharmony_ci "file", 31313498266Sopenharmony_ci#endif 31413498266Sopenharmony_ci#ifndef CURL_DISABLE_FTP 31513498266Sopenharmony_ci "ftp", 31613498266Sopenharmony_ci#endif 31713498266Sopenharmony_ci#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) 31813498266Sopenharmony_ci "ftps", 31913498266Sopenharmony_ci#endif 32013498266Sopenharmony_ci#ifndef CURL_DISABLE_GOPHER 32113498266Sopenharmony_ci "gopher", 32213498266Sopenharmony_ci#endif 32313498266Sopenharmony_ci#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER) 32413498266Sopenharmony_ci "gophers", 32513498266Sopenharmony_ci#endif 32613498266Sopenharmony_ci#ifndef CURL_DISABLE_HTTP 32713498266Sopenharmony_ci "http", 32813498266Sopenharmony_ci#endif 32913498266Sopenharmony_ci#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) 33013498266Sopenharmony_ci "https", 33113498266Sopenharmony_ci#endif 33213498266Sopenharmony_ci#ifndef CURL_DISABLE_IMAP 33313498266Sopenharmony_ci "imap", 33413498266Sopenharmony_ci#endif 33513498266Sopenharmony_ci#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP) 33613498266Sopenharmony_ci "imaps", 33713498266Sopenharmony_ci#endif 33813498266Sopenharmony_ci#ifndef CURL_DISABLE_LDAP 33913498266Sopenharmony_ci "ldap", 34013498266Sopenharmony_ci#if !defined(CURL_DISABLE_LDAPS) && \ 34113498266Sopenharmony_ci ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ 34213498266Sopenharmony_ci (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) 34313498266Sopenharmony_ci "ldaps", 34413498266Sopenharmony_ci#endif 34513498266Sopenharmony_ci#endif 34613498266Sopenharmony_ci#ifndef CURL_DISABLE_MQTT 34713498266Sopenharmony_ci "mqtt", 34813498266Sopenharmony_ci#endif 34913498266Sopenharmony_ci#ifndef CURL_DISABLE_POP3 35013498266Sopenharmony_ci "pop3", 35113498266Sopenharmony_ci#endif 35213498266Sopenharmony_ci#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3) 35313498266Sopenharmony_ci "pop3s", 35413498266Sopenharmony_ci#endif 35513498266Sopenharmony_ci#ifdef USE_LIBRTMP 35613498266Sopenharmony_ci "rtmp", 35713498266Sopenharmony_ci "rtmpe", 35813498266Sopenharmony_ci "rtmps", 35913498266Sopenharmony_ci "rtmpt", 36013498266Sopenharmony_ci "rtmpte", 36113498266Sopenharmony_ci "rtmpts", 36213498266Sopenharmony_ci#endif 36313498266Sopenharmony_ci#ifndef CURL_DISABLE_RTSP 36413498266Sopenharmony_ci "rtsp", 36513498266Sopenharmony_ci#endif 36613498266Sopenharmony_ci#if defined(USE_SSH) && !defined(USE_WOLFSSH) 36713498266Sopenharmony_ci "scp", 36813498266Sopenharmony_ci#endif 36913498266Sopenharmony_ci#ifdef USE_SSH 37013498266Sopenharmony_ci "sftp", 37113498266Sopenharmony_ci#endif 37213498266Sopenharmony_ci#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) 37313498266Sopenharmony_ci "smb", 37413498266Sopenharmony_ci# ifdef USE_SSL 37513498266Sopenharmony_ci "smbs", 37613498266Sopenharmony_ci# endif 37713498266Sopenharmony_ci#endif 37813498266Sopenharmony_ci#ifndef CURL_DISABLE_SMTP 37913498266Sopenharmony_ci "smtp", 38013498266Sopenharmony_ci#endif 38113498266Sopenharmony_ci#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP) 38213498266Sopenharmony_ci "smtps", 38313498266Sopenharmony_ci#endif 38413498266Sopenharmony_ci#ifndef CURL_DISABLE_TELNET 38513498266Sopenharmony_ci "telnet", 38613498266Sopenharmony_ci#endif 38713498266Sopenharmony_ci#ifndef CURL_DISABLE_TFTP 38813498266Sopenharmony_ci "tftp", 38913498266Sopenharmony_ci#endif 39013498266Sopenharmony_ci#ifdef USE_WEBSOCKETS 39113498266Sopenharmony_ci "ws", 39213498266Sopenharmony_ci#endif 39313498266Sopenharmony_ci#if defined(USE_SSL) && defined(USE_WEBSOCKETS) 39413498266Sopenharmony_ci "wss", 39513498266Sopenharmony_ci#endif 39613498266Sopenharmony_ci 39713498266Sopenharmony_ci NULL 39813498266Sopenharmony_ci}; 39913498266Sopenharmony_ci 40013498266Sopenharmony_ci/* 40113498266Sopenharmony_ci * Feature presence run-time check functions. 40213498266Sopenharmony_ci * 40313498266Sopenharmony_ci * Warning: the value returned by these should not change between 40413498266Sopenharmony_ci * curl_global_init() and curl_global_cleanup() calls. 40513498266Sopenharmony_ci */ 40613498266Sopenharmony_ci 40713498266Sopenharmony_ci#if defined(USE_LIBIDN2) 40813498266Sopenharmony_cistatic int idn_present(curl_version_info_data *info) 40913498266Sopenharmony_ci{ 41013498266Sopenharmony_ci return info->libidn != NULL; 41113498266Sopenharmony_ci} 41213498266Sopenharmony_ci#else 41313498266Sopenharmony_ci#define idn_present NULL 41413498266Sopenharmony_ci#endif 41513498266Sopenharmony_ci 41613498266Sopenharmony_ci#if defined(USE_SSL) && !defined(CURL_DISABLE_PROXY) && \ 41713498266Sopenharmony_ci !defined(CURL_DISABLE_HTTP) 41813498266Sopenharmony_cistatic int https_proxy_present(curl_version_info_data *info) 41913498266Sopenharmony_ci{ 42013498266Sopenharmony_ci (void) info; 42113498266Sopenharmony_ci return Curl_ssl_supports(NULL, SSLSUPP_HTTPS_PROXY); 42213498266Sopenharmony_ci} 42313498266Sopenharmony_ci#endif 42413498266Sopenharmony_ci 42513498266Sopenharmony_ci/* 42613498266Sopenharmony_ci * Features table. 42713498266Sopenharmony_ci * 42813498266Sopenharmony_ci * Keep the features alphabetically sorted. 42913498266Sopenharmony_ci * Use FEATURE() macro to define an entry: this allows documentation check. 43013498266Sopenharmony_ci */ 43113498266Sopenharmony_ci 43213498266Sopenharmony_ci#define FEATURE(name, present, bitmask) {(name), (present), (bitmask)} 43313498266Sopenharmony_ci 43413498266Sopenharmony_cistruct feat { 43513498266Sopenharmony_ci const char *name; 43613498266Sopenharmony_ci int (*present)(curl_version_info_data *info); 43713498266Sopenharmony_ci int bitmask; 43813498266Sopenharmony_ci}; 43913498266Sopenharmony_ci 44013498266Sopenharmony_cistatic const struct feat features_table[] = { 44113498266Sopenharmony_ci#ifndef CURL_DISABLE_ALTSVC 44213498266Sopenharmony_ci FEATURE("alt-svc", NULL, CURL_VERSION_ALTSVC), 44313498266Sopenharmony_ci#endif 44413498266Sopenharmony_ci#ifdef CURLRES_ASYNCH 44513498266Sopenharmony_ci FEATURE("AsynchDNS", NULL, CURL_VERSION_ASYNCHDNS), 44613498266Sopenharmony_ci#endif 44713498266Sopenharmony_ci#ifdef HAVE_BROTLI 44813498266Sopenharmony_ci FEATURE("brotli", NULL, CURL_VERSION_BROTLI), 44913498266Sopenharmony_ci#endif 45013498266Sopenharmony_ci#ifdef DEBUGBUILD 45113498266Sopenharmony_ci FEATURE("Debug", NULL, CURL_VERSION_DEBUG), 45213498266Sopenharmony_ci#endif 45313498266Sopenharmony_ci#ifdef USE_GSASL 45413498266Sopenharmony_ci FEATURE("gsasl", NULL, CURL_VERSION_GSASL), 45513498266Sopenharmony_ci#endif 45613498266Sopenharmony_ci#ifdef HAVE_GSSAPI 45713498266Sopenharmony_ci FEATURE("GSS-API", NULL, CURL_VERSION_GSSAPI), 45813498266Sopenharmony_ci#endif 45913498266Sopenharmony_ci#ifndef CURL_DISABLE_HSTS 46013498266Sopenharmony_ci FEATURE("HSTS", NULL, CURL_VERSION_HSTS), 46113498266Sopenharmony_ci#endif 46213498266Sopenharmony_ci#if defined(USE_NGHTTP2) 46313498266Sopenharmony_ci FEATURE("HTTP2", NULL, CURL_VERSION_HTTP2), 46413498266Sopenharmony_ci#endif 46513498266Sopenharmony_ci#if defined(ENABLE_QUIC) 46613498266Sopenharmony_ci FEATURE("HTTP3", NULL, CURL_VERSION_HTTP3), 46713498266Sopenharmony_ci#endif 46813498266Sopenharmony_ci#if defined(USE_SSL) && !defined(CURL_DISABLE_PROXY) && \ 46913498266Sopenharmony_ci !defined(CURL_DISABLE_HTTP) 47013498266Sopenharmony_ci FEATURE("HTTPS-proxy", https_proxy_present, CURL_VERSION_HTTPS_PROXY), 47113498266Sopenharmony_ci#endif 47213498266Sopenharmony_ci#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) 47313498266Sopenharmony_ci FEATURE("IDN", idn_present, CURL_VERSION_IDN), 47413498266Sopenharmony_ci#endif 47513498266Sopenharmony_ci#ifdef ENABLE_IPV6 47613498266Sopenharmony_ci FEATURE("IPv6", NULL, CURL_VERSION_IPV6), 47713498266Sopenharmony_ci#endif 47813498266Sopenharmony_ci#ifdef USE_KERBEROS5 47913498266Sopenharmony_ci FEATURE("Kerberos", NULL, CURL_VERSION_KERBEROS5), 48013498266Sopenharmony_ci#endif 48113498266Sopenharmony_ci#if (SIZEOF_CURL_OFF_T > 4) && \ 48213498266Sopenharmony_ci ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) ) 48313498266Sopenharmony_ci FEATURE("Largefile", NULL, CURL_VERSION_LARGEFILE), 48413498266Sopenharmony_ci#endif 48513498266Sopenharmony_ci#ifdef HAVE_LIBZ 48613498266Sopenharmony_ci FEATURE("libz", NULL, CURL_VERSION_LIBZ), 48713498266Sopenharmony_ci#endif 48813498266Sopenharmony_ci#ifdef CURL_WITH_MULTI_SSL 48913498266Sopenharmony_ci FEATURE("MultiSSL", NULL, CURL_VERSION_MULTI_SSL), 49013498266Sopenharmony_ci#endif 49113498266Sopenharmony_ci#ifdef USE_NTLM 49213498266Sopenharmony_ci FEATURE("NTLM", NULL, CURL_VERSION_NTLM), 49313498266Sopenharmony_ci#endif 49413498266Sopenharmony_ci#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ 49513498266Sopenharmony_ci defined(NTLM_WB_ENABLED) 49613498266Sopenharmony_ci FEATURE("NTLM_WB", NULL, CURL_VERSION_NTLM_WB), 49713498266Sopenharmony_ci#endif 49813498266Sopenharmony_ci#if defined(USE_LIBPSL) 49913498266Sopenharmony_ci FEATURE("PSL", NULL, CURL_VERSION_PSL), 50013498266Sopenharmony_ci#endif 50113498266Sopenharmony_ci#ifdef USE_SPNEGO 50213498266Sopenharmony_ci FEATURE("SPNEGO", NULL, CURL_VERSION_SPNEGO), 50313498266Sopenharmony_ci#endif 50413498266Sopenharmony_ci#ifdef USE_SSL 50513498266Sopenharmony_ci FEATURE("SSL", NULL, CURL_VERSION_SSL), 50613498266Sopenharmony_ci#endif 50713498266Sopenharmony_ci#ifdef USE_WINDOWS_SSPI 50813498266Sopenharmony_ci FEATURE("SSPI", NULL, CURL_VERSION_SSPI), 50913498266Sopenharmony_ci#endif 51013498266Sopenharmony_ci#ifdef GLOBAL_INIT_IS_THREADSAFE 51113498266Sopenharmony_ci FEATURE("threadsafe", NULL, CURL_VERSION_THREADSAFE), 51213498266Sopenharmony_ci#endif 51313498266Sopenharmony_ci#ifdef USE_TLS_SRP 51413498266Sopenharmony_ci FEATURE("TLS-SRP", NULL, CURL_VERSION_TLSAUTH_SRP), 51513498266Sopenharmony_ci#endif 51613498266Sopenharmony_ci#ifdef CURLDEBUG 51713498266Sopenharmony_ci FEATURE("TrackMemory", NULL, CURL_VERSION_CURLDEBUG), 51813498266Sopenharmony_ci#endif 51913498266Sopenharmony_ci#if defined(_WIN32) && defined(UNICODE) && defined(_UNICODE) 52013498266Sopenharmony_ci FEATURE("Unicode", NULL, CURL_VERSION_UNICODE), 52113498266Sopenharmony_ci#endif 52213498266Sopenharmony_ci#ifdef USE_UNIX_SOCKETS 52313498266Sopenharmony_ci FEATURE("UnixSockets", NULL, CURL_VERSION_UNIX_SOCKETS), 52413498266Sopenharmony_ci#endif 52513498266Sopenharmony_ci#ifdef HAVE_ZSTD 52613498266Sopenharmony_ci FEATURE("zstd", NULL, CURL_VERSION_ZSTD), 52713498266Sopenharmony_ci#endif 52813498266Sopenharmony_ci {NULL, NULL, 0} 52913498266Sopenharmony_ci}; 53013498266Sopenharmony_ci 53113498266Sopenharmony_cistatic const char *feature_names[sizeof(features_table) / 53213498266Sopenharmony_ci sizeof(features_table[0])] = {NULL}; 53313498266Sopenharmony_ci 53413498266Sopenharmony_ci 53513498266Sopenharmony_cistatic curl_version_info_data version_info = { 53613498266Sopenharmony_ci CURLVERSION_NOW, 53713498266Sopenharmony_ci LIBCURL_VERSION, 53813498266Sopenharmony_ci LIBCURL_VERSION_NUM, 53913498266Sopenharmony_ci OS, /* as found by configure or set by hand at build-time */ 54013498266Sopenharmony_ci 0, /* features bitmask is built at run-time */ 54113498266Sopenharmony_ci NULL, /* ssl_version */ 54213498266Sopenharmony_ci 0, /* ssl_version_num, this is kept at zero */ 54313498266Sopenharmony_ci NULL, /* zlib_version */ 54413498266Sopenharmony_ci supported_protocols, 54513498266Sopenharmony_ci NULL, /* c-ares version */ 54613498266Sopenharmony_ci 0, /* c-ares version numerical */ 54713498266Sopenharmony_ci NULL, /* libidn version */ 54813498266Sopenharmony_ci 0, /* iconv version */ 54913498266Sopenharmony_ci NULL, /* ssh lib version */ 55013498266Sopenharmony_ci 0, /* brotli_ver_num */ 55113498266Sopenharmony_ci NULL, /* brotli version */ 55213498266Sopenharmony_ci 0, /* nghttp2 version number */ 55313498266Sopenharmony_ci NULL, /* nghttp2 version string */ 55413498266Sopenharmony_ci NULL, /* quic library string */ 55513498266Sopenharmony_ci#ifdef CURL_CA_BUNDLE 55613498266Sopenharmony_ci CURL_CA_BUNDLE, /* cainfo */ 55713498266Sopenharmony_ci#else 55813498266Sopenharmony_ci NULL, 55913498266Sopenharmony_ci#endif 56013498266Sopenharmony_ci#ifdef CURL_CA_PATH 56113498266Sopenharmony_ci CURL_CA_PATH, /* capath */ 56213498266Sopenharmony_ci#else 56313498266Sopenharmony_ci NULL, 56413498266Sopenharmony_ci#endif 56513498266Sopenharmony_ci 0, /* zstd_ver_num */ 56613498266Sopenharmony_ci NULL, /* zstd version */ 56713498266Sopenharmony_ci NULL, /* Hyper version */ 56813498266Sopenharmony_ci NULL, /* gsasl version */ 56913498266Sopenharmony_ci feature_names 57013498266Sopenharmony_ci}; 57113498266Sopenharmony_ci 57213498266Sopenharmony_cicurl_version_info_data *curl_version_info(CURLversion stamp) 57313498266Sopenharmony_ci{ 57413498266Sopenharmony_ci size_t n; 57513498266Sopenharmony_ci const struct feat *p; 57613498266Sopenharmony_ci int features = 0; 57713498266Sopenharmony_ci 57813498266Sopenharmony_ci#if defined(USE_SSH) 57913498266Sopenharmony_ci static char ssh_buffer[80]; 58013498266Sopenharmony_ci#endif 58113498266Sopenharmony_ci#ifdef USE_SSL 58213498266Sopenharmony_ci#ifdef CURL_WITH_MULTI_SSL 58313498266Sopenharmony_ci static char ssl_buffer[200]; 58413498266Sopenharmony_ci#else 58513498266Sopenharmony_ci static char ssl_buffer[80]; 58613498266Sopenharmony_ci#endif 58713498266Sopenharmony_ci#endif 58813498266Sopenharmony_ci#ifdef HAVE_BROTLI 58913498266Sopenharmony_ci static char brotli_buffer[80]; 59013498266Sopenharmony_ci#endif 59113498266Sopenharmony_ci#ifdef HAVE_ZSTD 59213498266Sopenharmony_ci static char zstd_buffer[80]; 59313498266Sopenharmony_ci#endif 59413498266Sopenharmony_ci 59513498266Sopenharmony_ci (void)stamp; /* avoid compiler warnings, we don't use this */ 59613498266Sopenharmony_ci 59713498266Sopenharmony_ci#ifdef USE_SSL 59813498266Sopenharmony_ci Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer)); 59913498266Sopenharmony_ci version_info.ssl_version = ssl_buffer; 60013498266Sopenharmony_ci#endif 60113498266Sopenharmony_ci 60213498266Sopenharmony_ci#ifdef HAVE_LIBZ 60313498266Sopenharmony_ci version_info.libz_version = zlibVersion(); 60413498266Sopenharmony_ci /* libz left NULL if non-existing */ 60513498266Sopenharmony_ci#endif 60613498266Sopenharmony_ci#ifdef USE_ARES 60713498266Sopenharmony_ci { 60813498266Sopenharmony_ci int aresnum; 60913498266Sopenharmony_ci version_info.ares = ares_version(&aresnum); 61013498266Sopenharmony_ci version_info.ares_num = aresnum; 61113498266Sopenharmony_ci } 61213498266Sopenharmony_ci#endif 61313498266Sopenharmony_ci#ifdef USE_LIBIDN2 61413498266Sopenharmony_ci /* This returns a version string if we use the given version or later, 61513498266Sopenharmony_ci otherwise it returns NULL */ 61613498266Sopenharmony_ci version_info.libidn = idn2_check_version(IDN2_VERSION); 61713498266Sopenharmony_ci#endif 61813498266Sopenharmony_ci 61913498266Sopenharmony_ci#if defined(USE_SSH) 62013498266Sopenharmony_ci Curl_ssh_version(ssh_buffer, sizeof(ssh_buffer)); 62113498266Sopenharmony_ci version_info.libssh_version = ssh_buffer; 62213498266Sopenharmony_ci#endif 62313498266Sopenharmony_ci 62413498266Sopenharmony_ci#ifdef HAVE_BROTLI 62513498266Sopenharmony_ci version_info.brotli_ver_num = BrotliDecoderVersion(); 62613498266Sopenharmony_ci brotli_version(brotli_buffer, sizeof(brotli_buffer)); 62713498266Sopenharmony_ci version_info.brotli_version = brotli_buffer; 62813498266Sopenharmony_ci#endif 62913498266Sopenharmony_ci 63013498266Sopenharmony_ci#ifdef HAVE_ZSTD 63113498266Sopenharmony_ci version_info.zstd_ver_num = (unsigned int)ZSTD_versionNumber(); 63213498266Sopenharmony_ci zstd_version(zstd_buffer, sizeof(zstd_buffer)); 63313498266Sopenharmony_ci version_info.zstd_version = zstd_buffer; 63413498266Sopenharmony_ci#endif 63513498266Sopenharmony_ci 63613498266Sopenharmony_ci#ifdef USE_NGHTTP2 63713498266Sopenharmony_ci { 63813498266Sopenharmony_ci nghttp2_info *h2 = nghttp2_version(0); 63913498266Sopenharmony_ci version_info.nghttp2_ver_num = h2->version_num; 64013498266Sopenharmony_ci version_info.nghttp2_version = h2->version_str; 64113498266Sopenharmony_ci } 64213498266Sopenharmony_ci#endif 64313498266Sopenharmony_ci 64413498266Sopenharmony_ci#ifdef ENABLE_QUIC 64513498266Sopenharmony_ci { 64613498266Sopenharmony_ci static char quicbuffer[80]; 64713498266Sopenharmony_ci Curl_quic_ver(quicbuffer, sizeof(quicbuffer)); 64813498266Sopenharmony_ci version_info.quic_version = quicbuffer; 64913498266Sopenharmony_ci } 65013498266Sopenharmony_ci#endif 65113498266Sopenharmony_ci 65213498266Sopenharmony_ci#ifdef USE_HYPER 65313498266Sopenharmony_ci { 65413498266Sopenharmony_ci static char hyper_buffer[30]; 65513498266Sopenharmony_ci msnprintf(hyper_buffer, sizeof(hyper_buffer), "Hyper/%s", hyper_version()); 65613498266Sopenharmony_ci version_info.hyper_version = hyper_buffer; 65713498266Sopenharmony_ci } 65813498266Sopenharmony_ci#endif 65913498266Sopenharmony_ci 66013498266Sopenharmony_ci#ifdef USE_GSASL 66113498266Sopenharmony_ci { 66213498266Sopenharmony_ci version_info.gsasl_version = gsasl_check_version(NULL); 66313498266Sopenharmony_ci } 66413498266Sopenharmony_ci#endif 66513498266Sopenharmony_ci 66613498266Sopenharmony_ci /* Get available features, build bitmask and names array. */ 66713498266Sopenharmony_ci n = 0; 66813498266Sopenharmony_ci for(p = features_table; p->name; p++) 66913498266Sopenharmony_ci if(!p->present || p->present(&version_info)) { 67013498266Sopenharmony_ci features |= p->bitmask; 67113498266Sopenharmony_ci feature_names[n++] = p->name; 67213498266Sopenharmony_ci } 67313498266Sopenharmony_ci 67413498266Sopenharmony_ci feature_names[n] = NULL; /* Terminate array. */ 67513498266Sopenharmony_ci version_info.features = features; 67613498266Sopenharmony_ci 67713498266Sopenharmony_ci return &version_info; 67813498266Sopenharmony_ci} 679