mirror of
https://github.com/cmclark00/retro-imager.git
synced 2025-05-18 07:55:21 +01:00
deps: Remove unlabelled curl, xz
With very little version data, these area hard to reason about.
This commit is contained in:
parent
6b77ed7edc
commit
64381d2dd3
510 changed files with 6 additions and 191547 deletions
|
@ -191,12 +191,12 @@ if (WIN32)
|
||||||
set(CURL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/cmcurl/include)
|
set(CURL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/cmcurl/include)
|
||||||
|
|
||||||
# Bundled liblzma
|
# Bundled liblzma
|
||||||
add_subdirectory(dependencies/cmliblzma)
|
add_subdirectory(dependencies/xz-5.6.2)
|
||||||
set(LIBLZMA_HAS_AUTO_DECODER 1)
|
set(LIBLZMA_HAS_AUTO_DECODER 1)
|
||||||
set(LIBLZMA_HAS_EASY_ENCODER 1)
|
set(LIBLZMA_HAS_EASY_ENCODER 1)
|
||||||
set(LIBLZMA_HAS_LZMA_PRESET 1)
|
set(LIBLZMA_HAS_LZMA_PRESET 1)
|
||||||
set(LIBLZMA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/cmliblzma/liblzma/api)
|
set(LIBLZMA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/xz-5.6.2/liblzma/api)
|
||||||
set(LIBLZMA_LIBRARY cmliblzma)
|
set(LIBLZMA_LIBRARY liblzma)
|
||||||
|
|
||||||
# Bundled zstd
|
# Bundled zstd
|
||||||
set(ZSTD_BUILD_PROGRAMS OFF)
|
set(ZSTD_BUILD_PROGRAMS OFF)
|
||||||
|
@ -285,12 +285,12 @@ elseif(APPLE)
|
||||||
find_package(CURL REQUIRED)
|
find_package(CURL REQUIRED)
|
||||||
|
|
||||||
# Bundled liblzma
|
# Bundled liblzma
|
||||||
add_subdirectory(dependencies/cmliblzma)
|
add_subdirectory(dependencies/xz-5.6.2)
|
||||||
set(LIBLZMA_HAS_AUTO_DECODER 1)
|
set(LIBLZMA_HAS_AUTO_DECODER 1)
|
||||||
set(LIBLZMA_HAS_EASY_ENCODER 1)
|
set(LIBLZMA_HAS_EASY_ENCODER 1)
|
||||||
set(LIBLZMA_HAS_LZMA_PRESET 1)
|
set(LIBLZMA_HAS_LZMA_PRESET 1)
|
||||||
set(LIBLZMA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/cmliblzma/liblzma/api)
|
set(LIBLZMA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/xz-5.6.2/liblzma/api)
|
||||||
set(LIBLZMA_LIBRARY cmliblzma)
|
set(LIBLZMA_LIBRARY liblzma)
|
||||||
|
|
||||||
# Bundled zstd
|
# Bundled zstd
|
||||||
set(ZSTD_BUILD_PROGRAMS OFF)
|
set(ZSTD_BUILD_PROGRAMS OFF)
|
||||||
|
|
1
src/dependencies/cmcurl/.gitattributes
vendored
1
src/dependencies/cmcurl/.gitattributes
vendored
|
@ -1 +0,0 @@
|
||||||
* -whitespace
|
|
|
@ -1,24 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
@CMAKE_CONFIGURABLE_FILE_CONTENT@
|
|
|
@ -1,78 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
|
|
||||||
option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
|
|
||||||
mark_as_advanced(CURL_HIDDEN_SYMBOLS)
|
|
||||||
|
|
||||||
if(CURL_HIDDEN_SYMBOLS)
|
|
||||||
set(SUPPORTS_SYMBOL_HIDING FALSE)
|
|
||||||
|
|
||||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT MSVC)
|
|
||||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
|
||||||
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
|
|
||||||
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
|
|
||||||
elseif(CMAKE_COMPILER_IS_GNUCC)
|
|
||||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
|
|
||||||
# note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
|
|
||||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
|
||||||
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
|
|
||||||
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
|
|
||||||
endif()
|
|
||||||
elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
|
|
||||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
|
||||||
set(_SYMBOL_EXTERN "__global")
|
|
||||||
set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
|
|
||||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
|
|
||||||
# note: this should probably just check for version 9.1.045 but I'm not 100% sure
|
|
||||||
# so let's do it the same way autotools do.
|
|
||||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
|
||||||
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
|
|
||||||
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
|
|
||||||
check_c_source_compiles("#include <stdio.h>
|
|
||||||
int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
|
|
||||||
if(NOT _no_bug)
|
|
||||||
set(SUPPORTS_SYMBOL_HIDING FALSE)
|
|
||||||
set(_SYMBOL_EXTERN "")
|
|
||||||
set(_CFLAG_SYMBOLS_HIDE "")
|
|
||||||
endif()
|
|
||||||
elseif(MSVC)
|
|
||||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING})
|
|
||||||
elseif(MSVC)
|
|
||||||
if(NOT CMAKE_VERSION VERSION_LESS 3.7)
|
|
||||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken
|
|
||||||
set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
|
|
||||||
else()
|
|
||||||
message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.")
|
|
||||||
set(HIDES_CURL_PRIVATE_SYMBOLS TRUE)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE})
|
|
||||||
set(CURL_EXTERN_SYMBOL ${_SYMBOL_EXTERN})
|
|
|
@ -1,532 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef TIME_WITH_SYS_TIME
|
|
||||||
/* Time with sys/time test */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
if ((struct tm *) 0)
|
|
||||||
return 0;
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_O_NONBLOCK
|
|
||||||
|
|
||||||
/* headers for FCNTL_O_NONBLOCK test */
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
/* */
|
|
||||||
#if defined(sun) || defined(__sun__) || \
|
|
||||||
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
|
||||||
# if defined(__SVR4) || defined(__srv4__)
|
|
||||||
# define PLATFORM_SOLARIS
|
|
||||||
# else
|
|
||||||
# define PLATFORM_SUNOS4
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
|
|
||||||
# define PLATFORM_AIX_V3
|
|
||||||
#endif
|
|
||||||
/* */
|
|
||||||
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3)
|
|
||||||
#error "O_NONBLOCK does not work on this platform"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
/* O_NONBLOCK source test */
|
|
||||||
int flags = 0;
|
|
||||||
if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* tests for gethostbyname_r */
|
|
||||||
#if defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
|
||||||
# define _REENTRANT
|
|
||||||
/* no idea whether _REENTRANT is always set, just invent a new flag */
|
|
||||||
# define TEST_GETHOSTBYFOO_REENTRANT
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_GETHOSTBYNAME_R_3) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_5) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_6) || \
|
|
||||||
defined(TEST_GETHOSTBYFOO_REENTRANT)
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
char *address = "example.com";
|
|
||||||
int length = 0;
|
|
||||||
int type = 0;
|
|
||||||
struct hostent h;
|
|
||||||
int rc = 0;
|
|
||||||
#if defined(HAVE_GETHOSTBYNAME_R_3) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
|
|
||||||
struct hostent_data hdata;
|
|
||||||
#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_6) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
|
||||||
char buffer[8192];
|
|
||||||
int h_errnop;
|
|
||||||
struct hostent *hp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_GETHOSTBYNAME_R_3) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
|
|
||||||
rc = gethostbyname_r(address, &h, &hdata);
|
|
||||||
#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT)
|
|
||||||
rc = gethostbyname_r(address, &h, buffer, 8192, &h_errnop);
|
|
||||||
(void)hp; /* not used for test */
|
|
||||||
#elif defined(HAVE_GETHOSTBYNAME_R_6) || \
|
|
||||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
|
||||||
rc = gethostbyname_r(address, &h, buffer, 8192, &hp, &h_errnop);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
(void)length;
|
|
||||||
(void)type;
|
|
||||||
(void)rc;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SOCKLEN_T
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#else
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
if ((socklen_t *) 0)
|
|
||||||
return 0;
|
|
||||||
if (sizeof (socklen_t))
|
|
||||||
return 0;
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_IN_ADDR_T
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
if ((in_addr_t *) 0)
|
|
||||||
return 0;
|
|
||||||
if (sizeof (in_addr_t))
|
|
||||||
return 0;
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_BOOL_T
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STDBOOL_H
|
|
||||||
#include <stdbool.h>
|
|
||||||
#endif
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
if (sizeof (bool *) )
|
|
||||||
return 0;
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STDC_HEADERS
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <float.h>
|
|
||||||
int main() { return 0; }
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FILE_OFFSET_BITS
|
|
||||||
#ifdef _FILE_OFFSET_BITS
|
|
||||||
#undef _FILE_OFFSET_BITS
|
|
||||||
#endif
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
|
||||||
#include <sys/types.h>
|
|
||||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
|
||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
|
||||||
since some C++ compilers masquerading as C compilers
|
|
||||||
incorrectly reject 9223372036854775807. */
|
|
||||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
|
||||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
|
||||||
? 1 : -1];
|
|
||||||
int main () { ; return 0; }
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_IOCTLSOCKET
|
|
||||||
/* includes start */
|
|
||||||
#ifdef HAVE_WINDOWS_H
|
|
||||||
# ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
# define WIN32_LEAN_AND_MEAN
|
|
||||||
# endif
|
|
||||||
# include <windows.h>
|
|
||||||
# ifdef HAVE_WINSOCK2_H
|
|
||||||
# include <winsock2.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
|
|
||||||
/* ioctlsocket source code */
|
|
||||||
int socket;
|
|
||||||
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
|
|
||||||
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_IOCTLSOCKET_CAMEL
|
|
||||||
/* includes start */
|
|
||||||
#ifdef HAVE_WINDOWS_H
|
|
||||||
# ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
# define WIN32_LEAN_AND_MEAN
|
|
||||||
# endif
|
|
||||||
# include <windows.h>
|
|
||||||
# ifdef HAVE_WINSOCK2_H
|
|
||||||
# include <winsock2.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
|
|
||||||
/* IoctlSocket source code */
|
|
||||||
if(0 != IoctlSocket(0, 0, 0))
|
|
||||||
return 1;
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
|
|
||||||
/* includes start */
|
|
||||||
#ifdef HAVE_WINDOWS_H
|
|
||||||
# ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
# define WIN32_LEAN_AND_MEAN
|
|
||||||
# endif
|
|
||||||
# include <windows.h>
|
|
||||||
# ifdef HAVE_WINSOCK2_H
|
|
||||||
# include <winsock2.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
|
|
||||||
/* IoctlSocket source code */
|
|
||||||
long flags = 0;
|
|
||||||
if(0 != IoctlSocket(0, FIONBIO, &flags))
|
|
||||||
return 1;
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_IOCTLSOCKET_FIONBIO
|
|
||||||
/* includes start */
|
|
||||||
#ifdef HAVE_WINDOWS_H
|
|
||||||
# ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
# define WIN32_LEAN_AND_MEAN
|
|
||||||
# endif
|
|
||||||
# include <windows.h>
|
|
||||||
# ifdef HAVE_WINSOCK2_H
|
|
||||||
# include <winsock2.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
|
|
||||||
int flags = 0;
|
|
||||||
if(0 != ioctlsocket(0, FIONBIO, &flags))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_IOCTL_FIONBIO
|
|
||||||
/* headers for FIONBIO test */
|
|
||||||
/* includes start */
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
# include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_IOCTL_H
|
|
||||||
# include <sys/ioctl.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STROPTS_H
|
|
||||||
# include <stropts.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
|
|
||||||
int flags = 0;
|
|
||||||
if(0 != ioctl(0, FIONBIO, &flags))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_IOCTL_SIOCGIFADDR
|
|
||||||
/* headers for FIONBIO test */
|
|
||||||
/* includes start */
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
# include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_IOCTL_H
|
|
||||||
# include <sys/ioctl.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STROPTS_H
|
|
||||||
# include <stropts.h>
|
|
||||||
#endif
|
|
||||||
#include <net/if.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
struct ifreq ifr;
|
|
||||||
if(0 != ioctl(0, SIOCGIFADDR, &ifr))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
|
|
||||||
/* includes start */
|
|
||||||
#ifdef HAVE_WINDOWS_H
|
|
||||||
# ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
# define WIN32_LEAN_AND_MEAN
|
|
||||||
# endif
|
|
||||||
# include <windows.h>
|
|
||||||
# ifdef HAVE_WINSOCK2_H
|
|
||||||
# include <winsock2.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
/* includes start */
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
# include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
/* includes end */
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0))
|
|
||||||
return 1;
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GLIBC_STRERROR_R
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
void check(char c) {}
|
|
||||||
|
|
||||||
int
|
|
||||||
main () {
|
|
||||||
char buffer[1024];
|
|
||||||
/* This will not compile if strerror_r does not return a char* */
|
|
||||||
check(strerror_r(EACCES, buffer, sizeof(buffer))[0]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_POSIX_STRERROR_R
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/* float, because a pointer can't be implicitly cast to float */
|
|
||||||
void check(float f) {}
|
|
||||||
|
|
||||||
int
|
|
||||||
main () {
|
|
||||||
char buffer[1024];
|
|
||||||
/* This will not compile if strerror_r does not return an int */
|
|
||||||
check(strerror_r(EACCES, buffer, sizeof(buffer)));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FSETXATTR_6
|
|
||||||
#include <sys/xattr.h> /* header from libc, not from libattr */
|
|
||||||
int
|
|
||||||
main() {
|
|
||||||
fsetxattr(0, 0, 0, 0, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FSETXATTR_5
|
|
||||||
#include <sys/xattr.h> /* header from libc, not from libattr */
|
|
||||||
int
|
|
||||||
main() {
|
|
||||||
fsetxattr(0, 0, 0, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_CLOCK_GETTIME_MONOTONIC
|
|
||||||
#include <time.h>
|
|
||||||
int
|
|
||||||
main() {
|
|
||||||
struct timespec ts = {0, 0};
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_BUILTIN_AVAILABLE
|
|
||||||
int
|
|
||||||
main() {
|
|
||||||
if(__builtin_available(macOS 10.12, *)) {}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_VARIADIC_MACROS_C99
|
|
||||||
#define c99_vmacro3(first, ...) fun3(first, __VA_ARGS__)
|
|
||||||
#define c99_vmacro2(first, ...) fun2(first, __VA_ARGS__)
|
|
||||||
|
|
||||||
int fun3(int arg1, int arg2, int arg3);
|
|
||||||
int fun2(int arg1, int arg2);
|
|
||||||
|
|
||||||
int fun3(int arg1, int arg2, int arg3) {
|
|
||||||
return arg1 + arg2 + arg3;
|
|
||||||
}
|
|
||||||
int fun2(int arg1, int arg2) {
|
|
||||||
return arg1 + arg2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main() {
|
|
||||||
int res3 = c99_vmacro3(1, 2, 3);
|
|
||||||
int res2 = c99_vmacro2(1, 2);
|
|
||||||
(void)res3;
|
|
||||||
(void)res2;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_VARIADIC_MACROS_GCC
|
|
||||||
#define gcc_vmacro3(first, args...) fun3(first, args)
|
|
||||||
#define gcc_vmacro2(first, args...) fun2(first, args)
|
|
||||||
|
|
||||||
int fun3(int arg1, int arg2, int arg3);
|
|
||||||
int fun2(int arg1, int arg2);
|
|
||||||
|
|
||||||
int fun3(int arg1, int arg2, int arg3) {
|
|
||||||
return arg1 + arg2 + arg3;
|
|
||||||
}
|
|
||||||
int fun2(int arg1, int arg2) {
|
|
||||||
return arg1 + arg2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main() {
|
|
||||||
int res3 = gcc_vmacro3(1, 2, 3);
|
|
||||||
int res2 = gcc_vmacro2(1, 2);
|
|
||||||
(void)res3;
|
|
||||||
(void)res2;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ATOMIC
|
|
||||||
/* includes start */
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STDATOMIC_H
|
|
||||||
# include <stdatomic.h>
|
|
||||||
#endif
|
|
||||||
/* includes end */
|
|
||||||
|
|
||||||
int
|
|
||||||
main() {
|
|
||||||
_Atomic int i = 1;
|
|
||||||
i = 0; // Force an atomic-write operation.
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WIN32_WINNT
|
|
||||||
/* includes start */
|
|
||||||
#ifdef WIN32
|
|
||||||
# include "../lib/setup-win32.h"
|
|
||||||
#endif
|
|
||||||
/* includes end */
|
|
||||||
|
|
||||||
#define enquote(x) #x
|
|
||||||
#define expand(x) enquote(x)
|
|
||||||
#pragma message("_WIN32_WINNT=" expand(_WIN32_WINNT))
|
|
||||||
|
|
||||||
int
|
|
||||||
main() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,32 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
find_path(BEARSSL_INCLUDE_DIRS bearssl.h)
|
|
||||||
|
|
||||||
find_library(BEARSSL_LIBRARY bearssl)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(BEARSSL DEFAULT_MSG
|
|
||||||
BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY)
|
|
||||||
|
|
||||||
mark_as_advanced(BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY)
|
|
|
@ -1,43 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
|
|
||||||
find_path(BROTLI_INCLUDE_DIR "brotli/decode.h")
|
|
||||||
|
|
||||||
find_library(BROTLICOMMON_LIBRARY NAMES brotlicommon)
|
|
||||||
find_library(BROTLIDEC_LIBRARY NAMES brotlidec)
|
|
||||||
|
|
||||||
find_package_handle_standard_args(Brotli
|
|
||||||
FOUND_VAR
|
|
||||||
BROTLI_FOUND
|
|
||||||
REQUIRED_VARS
|
|
||||||
BROTLIDEC_LIBRARY
|
|
||||||
BROTLICOMMON_LIBRARY
|
|
||||||
BROTLI_INCLUDE_DIR
|
|
||||||
FAIL_MESSAGE
|
|
||||||
"Could NOT find Brotli"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR})
|
|
||||||
set(BROTLI_LIBRARIES ${BROTLICOMMON_LIBRARY} ${BROTLIDEC_LIBRARY})
|
|
|
@ -1,47 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
# - Find c-ares
|
|
||||||
# Find the c-ares includes and library
|
|
||||||
# This module defines
|
|
||||||
# CARES_INCLUDE_DIR, where to find ares.h, etc.
|
|
||||||
# CARES_LIBRARIES, the libraries needed to use c-ares.
|
|
||||||
# CARES_FOUND, If false, do not try to use c-ares.
|
|
||||||
# also defined, but not for general use are
|
|
||||||
# CARES_LIBRARY, where to find the c-ares library.
|
|
||||||
|
|
||||||
find_path(CARES_INCLUDE_DIR ares.h)
|
|
||||||
|
|
||||||
set(CARES_NAMES ${CARES_NAMES} cares)
|
|
||||||
find_library(CARES_LIBRARY
|
|
||||||
NAMES ${CARES_NAMES}
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(CARES
|
|
||||||
REQUIRED_VARS CARES_LIBRARY CARES_INCLUDE_DIR)
|
|
||||||
|
|
||||||
mark_as_advanced(
|
|
||||||
CARES_LIBRARY
|
|
||||||
CARES_INCLUDE_DIR
|
|
||||||
)
|
|
|
@ -1,312 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
# - Try to find the GSS Kerberos library
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# GSS_ROOT_DIR - Set this variable to the root installation of GSS
|
|
||||||
#
|
|
||||||
# Read-Only variables:
|
|
||||||
# GSS_FOUND - system has the Heimdal library
|
|
||||||
# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found.
|
|
||||||
# GSS_INCLUDE_DIR - the Heimdal include directory
|
|
||||||
# GSS_LIBRARIES - The libraries needed to use GSS
|
|
||||||
# GSS_LINK_DIRECTORIES - Directories to add to linker search path
|
|
||||||
# GSS_LINKER_FLAGS - Additional linker flags
|
|
||||||
# GSS_COMPILER_FLAGS - Additional compiler flags
|
|
||||||
# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
|
|
||||||
# In case the library is found but no version info available it'll be set to "unknown"
|
|
||||||
|
|
||||||
set(_MIT_MODNAME mit-krb5-gssapi)
|
|
||||||
set(_HEIMDAL_MODNAME heimdal-gssapi)
|
|
||||||
|
|
||||||
include(CheckIncludeFile)
|
|
||||||
include(CheckIncludeFiles)
|
|
||||||
include(CheckTypeSize)
|
|
||||||
|
|
||||||
set(_GSS_ROOT_HINTS
|
|
||||||
"${GSS_ROOT_DIR}"
|
|
||||||
"$ENV{GSS_ROOT_DIR}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# try to find library using system pkg-config if user didn't specify root dir
|
|
||||||
if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
|
|
||||||
if(UNIX)
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
|
|
||||||
list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
|
|
||||||
elseif(WIN32)
|
|
||||||
list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
|
|
||||||
find_file(_GSS_CONFIGURE_SCRIPT
|
|
||||||
NAMES
|
|
||||||
"krb5-config"
|
|
||||||
HINTS
|
|
||||||
${_GSS_ROOT_HINTS}
|
|
||||||
PATH_SUFFIXES
|
|
||||||
bin
|
|
||||||
NO_CMAKE_PATH
|
|
||||||
NO_CMAKE_ENVIRONMENT_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
# if not found in user-supplied directories, maybe system knows better
|
|
||||||
find_file(_GSS_CONFIGURE_SCRIPT
|
|
||||||
NAMES
|
|
||||||
"krb5-config"
|
|
||||||
PATH_SUFFIXES
|
|
||||||
bin
|
|
||||||
)
|
|
||||||
|
|
||||||
if(_GSS_CONFIGURE_SCRIPT)
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
|
|
||||||
OUTPUT_VARIABLE _GSS_CFLAGS
|
|
||||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
|
|
||||||
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
|
|
||||||
# should also work in an odd case when multiple directories are given
|
|
||||||
string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
|
|
||||||
string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
|
|
||||||
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _GSS_CFLAGS "${_GSS_CFLAGS}")
|
|
||||||
|
|
||||||
foreach(_flag ${_GSS_CFLAGS})
|
|
||||||
if(_flag MATCHES "^-I.*")
|
|
||||||
string(REGEX REPLACE "^-I" "" _val "${_flag}")
|
|
||||||
list(APPEND _GSS_INCLUDE_DIR "${_val}")
|
|
||||||
else()
|
|
||||||
list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
|
|
||||||
OUTPUT_VARIABLE _GSS_LIB_FLAGS
|
|
||||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
|
|
||||||
|
|
||||||
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
|
|
||||||
# this script gives us libraries and link directories. Blah. We have to deal with it.
|
|
||||||
string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
|
|
||||||
string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
|
|
||||||
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
|
|
||||||
|
|
||||||
foreach(_flag ${_GSS_LIB_FLAGS})
|
|
||||||
if(_flag MATCHES "^-l.*")
|
|
||||||
string(REGEX REPLACE "^-l" "" _val "${_flag}")
|
|
||||||
list(APPEND _GSS_LIBRARIES "${_val}")
|
|
||||||
elseif(_flag MATCHES "^-L.*")
|
|
||||||
string(REGEX REPLACE "^-L" "" _val "${_flag}")
|
|
||||||
list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
|
|
||||||
else()
|
|
||||||
list(APPEND _GSS_LINKER_FLAGS "${_flag}")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
|
|
||||||
OUTPUT_VARIABLE _GSS_VERSION
|
|
||||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
|
|
||||||
# older versions may not have the "--version" parameter. In this case we just don't care.
|
|
||||||
if(_GSS_CONFIGURE_FAILED)
|
|
||||||
set(_GSS_VERSION 0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
|
|
||||||
OUTPUT_VARIABLE _GSS_VENDOR
|
|
||||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
|
|
||||||
# older versions may not have the "--vendor" parameter. In this case we just don't care.
|
|
||||||
if(_GSS_CONFIGURE_FAILED)
|
|
||||||
set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
|
|
||||||
else()
|
|
||||||
if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
|
|
||||||
set(GSS_FLAVOUR "Heimdal")
|
|
||||||
else()
|
|
||||||
set(GSS_FLAVOUR "MIT")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
else() # either there is no config script or we are on a platform that doesn't provide one (Windows?)
|
|
||||||
|
|
||||||
find_path(_GSS_INCLUDE_DIR
|
|
||||||
NAMES
|
|
||||||
"gssapi/gssapi.h"
|
|
||||||
HINTS
|
|
||||||
${_GSS_ROOT_HINTS}
|
|
||||||
PATH_SUFFIXES
|
|
||||||
include
|
|
||||||
inc
|
|
||||||
)
|
|
||||||
|
|
||||||
if(_GSS_INCLUDE_DIR) #jay, we've found something
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
|
|
||||||
check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
|
|
||||||
|
|
||||||
if(_GSS_HAVE_MIT_HEADERS)
|
|
||||||
set(GSS_FLAVOUR "MIT")
|
|
||||||
else()
|
|
||||||
# prevent compiling the header - just check if we can include it
|
|
||||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__)
|
|
||||||
check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
|
|
||||||
|
|
||||||
check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
|
|
||||||
if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
|
|
||||||
set(GSS_FLAVOUR "Heimdal")
|
|
||||||
endif()
|
|
||||||
list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
# I'm not convinced if this is the right way but this is what autotools do at the moment
|
|
||||||
find_path(_GSS_INCLUDE_DIR
|
|
||||||
NAMES
|
|
||||||
"gssapi.h"
|
|
||||||
HINTS
|
|
||||||
${_GSS_ROOT_HINTS}
|
|
||||||
PATH_SUFFIXES
|
|
||||||
include
|
|
||||||
inc
|
|
||||||
)
|
|
||||||
|
|
||||||
if(_GSS_INCLUDE_DIR)
|
|
||||||
set(GSS_FLAVOUR "Heimdal")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# if we have headers, check if we can link libraries
|
|
||||||
if(GSS_FLAVOUR)
|
|
||||||
set(_GSS_LIBDIR_SUFFIXES "")
|
|
||||||
set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
|
|
||||||
get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
|
|
||||||
list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
|
|
||||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
|
||||||
set(_GSS_LIBNAME "gssapi64")
|
|
||||||
else()
|
|
||||||
set(_GSS_LIBNAME "libgssapi")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
|
|
||||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
|
||||||
set(_GSS_LIBNAME "gssapi32")
|
|
||||||
else()
|
|
||||||
set(_GSS_LIBNAME "libgssapi")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
|
|
||||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
|
||||||
set(_GSS_LIBNAME "gssapi_krb5")
|
|
||||||
else()
|
|
||||||
set(_GSS_LIBNAME "gssapi")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_library(_GSS_LIBRARIES
|
|
||||||
NAMES
|
|
||||||
${_GSS_LIBNAME}
|
|
||||||
HINTS
|
|
||||||
${_GSS_LIBDIR_HINTS}
|
|
||||||
PATH_SUFFIXES
|
|
||||||
${_GSS_LIBDIR_SUFFIXES}
|
|
||||||
)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
|
|
||||||
set(GSS_FLAVOUR "MIT")
|
|
||||||
set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
|
|
||||||
else()
|
|
||||||
set(GSS_FLAVOUR "Heimdal")
|
|
||||||
set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
|
|
||||||
set(GSS_LIBRARIES ${_GSS_LIBRARIES})
|
|
||||||
set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES})
|
|
||||||
set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS})
|
|
||||||
set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
|
|
||||||
set(GSS_VERSION ${_GSS_VERSION})
|
|
||||||
|
|
||||||
if(GSS_FLAVOUR)
|
|
||||||
if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
|
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
|
|
||||||
else()
|
|
||||||
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
|
|
||||||
file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
|
|
||||||
REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
|
|
||||||
|
|
||||||
string(REGEX MATCH "[0-9]\\.[^\"]+"
|
|
||||||
GSS_VERSION "${heimdal_version_str}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT GSS_VERSION)
|
|
||||||
set(GSS_VERSION "Heimdal Unknown")
|
|
||||||
endif()
|
|
||||||
elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
|
|
||||||
get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
|
|
||||||
if(WIN32 AND _MIT_VERSION)
|
|
||||||
set(GSS_VERSION "${_MIT_VERSION}")
|
|
||||||
else()
|
|
||||||
set(GSS_VERSION "MIT Unknown")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
|
|
||||||
set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
|
|
||||||
|
|
||||||
find_package_handle_standard_args(GSS
|
|
||||||
REQUIRED_VARS
|
|
||||||
${_GSS_REQUIRED_VARS}
|
|
||||||
VERSION_VAR
|
|
||||||
GSS_VERSION
|
|
||||||
FAIL_MESSAGE
|
|
||||||
"Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
|
|
||||||
)
|
|
||||||
|
|
||||||
mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES)
|
|
|
@ -1,45 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
# - Try to find the libpsl library
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# LIBPSL_FOUND - system has the libpsl library
|
|
||||||
# LIBPSL_INCLUDE_DIR - the libpsl include directory
|
|
||||||
# LIBPSL_LIBRARY - the libpsl library name
|
|
||||||
|
|
||||||
find_path(LIBPSL_INCLUDE_DIR libpsl.h)
|
|
||||||
|
|
||||||
find_library(LIBPSL_LIBRARY NAMES psl libpsl)
|
|
||||||
|
|
||||||
if(LIBPSL_INCLUDE_DIR)
|
|
||||||
file(STRINGS "${LIBPSL_INCLUDE_DIR}/libpsl.h" libpsl_version_str REGEX "^#define[\t ]+PSL_VERSION[\t ]+\"(.*)\"")
|
|
||||||
string(REGEX REPLACE "^.*\"([^\"]+)\"" "\\1" LIBPSL_VERSION "${libpsl_version_str}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(LibPSL
|
|
||||||
REQUIRED_VARS LIBPSL_LIBRARY LIBPSL_INCLUDE_DIR
|
|
||||||
VERSION_VAR LIBPSL_VERSION)
|
|
||||||
|
|
||||||
mark_as_advanced(LIBPSL_INCLUDE_DIR LIBPSL_LIBRARY)
|
|
|
@ -1,45 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
# - Try to find the libssh2 library
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# LIBSSH2_FOUND - system has the libssh2 library
|
|
||||||
# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
|
|
||||||
# LIBSSH2_LIBRARY - the libssh2 library name
|
|
||||||
|
|
||||||
find_path(LIBSSH2_INCLUDE_DIR libssh2.h)
|
|
||||||
|
|
||||||
find_library(LIBSSH2_LIBRARY NAMES ssh2 libssh2)
|
|
||||||
|
|
||||||
if(LIBSSH2_INCLUDE_DIR)
|
|
||||||
file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION[\t ]+\"(.*)\"")
|
|
||||||
string(REGEX REPLACE "^.*\"([^\"]+)\"" "\\1" LIBSSH2_VERSION "${libssh2_version_str}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(LibSSH2
|
|
||||||
REQUIRED_VARS LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR
|
|
||||||
VERSION_VAR LIBSSH2_VERSION)
|
|
||||||
|
|
||||||
mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY)
|
|
|
@ -1,70 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
|
|
||||||
#[=======================================================================[.rst:
|
|
||||||
FindMSH3
|
|
||||||
----------
|
|
||||||
|
|
||||||
Find the msh3 library
|
|
||||||
|
|
||||||
Result Variables
|
|
||||||
^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
``MSH3_FOUND``
|
|
||||||
System has msh3
|
|
||||||
``MSH3_INCLUDE_DIRS``
|
|
||||||
The msh3 include directories.
|
|
||||||
``MSH3_LIBRARIES``
|
|
||||||
The libraries needed to use msh3
|
|
||||||
#]=======================================================================]
|
|
||||||
if(UNIX)
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_search_module(PC_MSH3 libmsh3)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_path(MSH3_INCLUDE_DIR msh3.h
|
|
||||||
HINTS
|
|
||||||
${PC_MSH3_INCLUDEDIR}
|
|
||||||
${PC_MSH3_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(MSH3_LIBRARY NAMES msh3
|
|
||||||
HINTS
|
|
||||||
${PC_MSH3_LIBDIR}
|
|
||||||
${PC_MSH3_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(MSH3
|
|
||||||
REQUIRED_VARS
|
|
||||||
MSH3_LIBRARY
|
|
||||||
MSH3_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
if(MSH3_FOUND)
|
|
||||||
set(MSH3_LIBRARIES ${MSH3_LIBRARY})
|
|
||||||
set(MSH3_INCLUDE_DIRS ${MSH3_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced(MSH3_INCLUDE_DIRS MSH3_LIBRARIES)
|
|
|
@ -1,36 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
|
|
||||||
|
|
||||||
find_library(MBEDTLS_LIBRARY mbedtls)
|
|
||||||
find_library(MBEDX509_LIBRARY mbedx509)
|
|
||||||
find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
|
|
||||||
|
|
||||||
set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(MbedTLS DEFAULT_MSG
|
|
||||||
MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
|
||||||
|
|
||||||
mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
|
|
@ -1,41 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
|
|
||||||
find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h")
|
|
||||||
|
|
||||||
find_library(NGHTTP2_LIBRARY NAMES nghttp2)
|
|
||||||
|
|
||||||
find_package_handle_standard_args(NGHTTP2
|
|
||||||
FOUND_VAR
|
|
||||||
NGHTTP2_FOUND
|
|
||||||
REQUIRED_VARS
|
|
||||||
NGHTTP2_LIBRARY
|
|
||||||
NGHTTP2_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
|
|
||||||
set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
|
|
||||||
|
|
||||||
mark_as_advanced(NGHTTP2_INCLUDE_DIRS NGHTTP2_LIBRARIES)
|
|
|
@ -1,78 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
|
|
||||||
#[=======================================================================[.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)
|
|
|
@ -1,115 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
|
|
||||||
#[=======================================================================[.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 "^(BoringSSL|OpenSSL|wolfSSL|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)
|
|
|
@ -1,40 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
if(UNIX)
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_search_module(PC_NSS nss)
|
|
||||||
endif()
|
|
||||||
if(NOT PC_NSS_FOUND)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(NSS_LIBRARIES ${PC_NSS_LINK_LIBRARIES})
|
|
||||||
set(NSS_INCLUDE_DIRS ${PC_NSS_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(NSS
|
|
||||||
REQUIRED_VARS NSS_LIBRARIES NSS_INCLUDE_DIRS
|
|
||||||
VERSION_VAR PC_NSS_VERSION)
|
|
||||||
|
|
||||||
mark_as_advanced(NSS_INCLUDE_DIRS NSS_LIBRARIES)
|
|
|
@ -1,70 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
|
|
||||||
#[=======================================================================[.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)
|
|
|
@ -1,36 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
find_path(WolfSSL_INCLUDE_DIR NAMES wolfssl/ssl.h)
|
|
||||||
find_library(WolfSSL_LIBRARY NAMES wolfssl)
|
|
||||||
mark_as_advanced(WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(WolfSSL
|
|
||||||
REQUIRED_VARS WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WolfSSL_FOUND)
|
|
||||||
set(WolfSSL_INCLUDE_DIRS ${WolfSSL_INCLUDE_DIR})
|
|
||||||
set(WolfSSL_LIBRARIES ${WolfSSL_LIBRARY})
|
|
||||||
endif()
|
|
|
@ -1,71 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
|
|
||||||
#[=======================================================================[.rst:
|
|
||||||
FindZstd
|
|
||||||
----------
|
|
||||||
|
|
||||||
Find the zstd library
|
|
||||||
|
|
||||||
Result Variables
|
|
||||||
^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
``Zstd_FOUND``
|
|
||||||
System has zstd
|
|
||||||
``Zstd_INCLUDE_DIRS``
|
|
||||||
The zstd include directories.
|
|
||||||
``Zstd_LIBRARIES``
|
|
||||||
The libraries needed to use zstd
|
|
||||||
#]=======================================================================]
|
|
||||||
|
|
||||||
if(UNIX)
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_search_module(PC_Zstd libzstd)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_path(Zstd_INCLUDE_DIR zstd.h
|
|
||||||
HINTS
|
|
||||||
${PC_Zstd_INCLUDEDIR}
|
|
||||||
${PC_Zstd_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(Zstd_LIBRARY NAMES zstd
|
|
||||||
HINTS
|
|
||||||
${PC_Zstd_LIBDIR}
|
|
||||||
${PC_Zstd_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(Zstd
|
|
||||||
REQUIRED_VARS
|
|
||||||
Zstd_LIBRARY
|
|
||||||
Zstd_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
if(Zstd_FOUND)
|
|
||||||
set(Zstd_LIBRARIES ${Zstd_LIBRARY})
|
|
||||||
set(Zstd_INCLUDE_DIRS ${Zstd_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced(Zstd_INCLUDE_DIRS Zstd_LIBRARIES)
|
|
|
@ -1,122 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
#File defines convenience macros for available feature testing
|
|
||||||
|
|
||||||
# This macro checks if the symbol exists in the library and if it
|
|
||||||
# does, it prepends library to the list. It is intended to be called
|
|
||||||
# multiple times with a sequence of possibly dependent libraries in
|
|
||||||
# order of least-to-most-dependent. Some libraries depend on others
|
|
||||||
# to link correctly.
|
|
||||||
macro(check_library_exists_concat LIBRARY SYMBOL VARIABLE)
|
|
||||||
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
|
|
||||||
${VARIABLE})
|
|
||||||
if(${VARIABLE})
|
|
||||||
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Check if header file exists and add it to the list.
|
|
||||||
# This macro is intended to be called multiple times with a sequence of
|
|
||||||
# possibly dependent header files. Some headers depend on others to be
|
|
||||||
# compiled correctly.
|
|
||||||
macro(check_include_file_concat FILE VARIABLE)
|
|
||||||
check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
|
|
||||||
if(${VARIABLE})
|
|
||||||
set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
|
|
||||||
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# For other curl specific tests, use this macro.
|
|
||||||
macro(curl_internal_test CURL_TEST)
|
|
||||||
if(NOT DEFINED "${CURL_TEST}")
|
|
||||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
|
||||||
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
|
|
||||||
if(CMAKE_REQUIRED_LIBRARIES)
|
|
||||||
set(CURL_TEST_ADD_LIBRARIES
|
|
||||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "Performing Curl Test ${CURL_TEST}")
|
|
||||||
try_compile(${CURL_TEST}
|
|
||||||
${CMAKE_BINARY_DIR}
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
|
|
||||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
|
||||||
"${CURL_TEST_ADD_LIBRARIES}"
|
|
||||||
OUTPUT_VARIABLE OUTPUT)
|
|
||||||
if(${CURL_TEST})
|
|
||||||
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
|
|
||||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
|
|
||||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
|
||||||
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
|
|
||||||
"${OUTPUT}\n")
|
|
||||||
else()
|
|
||||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
|
|
||||||
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
|
|
||||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
|
||||||
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
|
|
||||||
"${OUTPUT}\n")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
macro(curl_nroff_check)
|
|
||||||
find_program(NROFF NAMES gnroff nroff)
|
|
||||||
if(NROFF)
|
|
||||||
# Need a way to write to stdin, this will do
|
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt" "test")
|
|
||||||
# Tests for a valid nroff option to generate a manpage
|
|
||||||
foreach(_MANOPT "-man" "-mandoc")
|
|
||||||
execute_process(COMMAND "${NROFF}" ${_MANOPT}
|
|
||||||
OUTPUT_VARIABLE NROFF_MANOPT_OUTPUT
|
|
||||||
INPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt"
|
|
||||||
ERROR_QUIET)
|
|
||||||
# Save the option if it was valid
|
|
||||||
if(NROFF_MANOPT_OUTPUT)
|
|
||||||
message("Found *nroff option: -- ${_MANOPT}")
|
|
||||||
set(NROFF_MANOPT ${_MANOPT})
|
|
||||||
set(NROFF_USEFUL ON)
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
# No need for the temporary file
|
|
||||||
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt")
|
|
||||||
if(NOT NROFF_USEFUL)
|
|
||||||
message(WARNING "Found no *nroff option to get plaintext from man pages")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
message(WARNING "Found no *nroff program")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
macro(optional_dependency DEPENDENCY)
|
|
||||||
set(CURL_${DEPENDENCY} AUTO CACHE STRING "Build curl with ${DEPENDENCY} support (AUTO, ON or OFF)")
|
|
||||||
set_property(CACHE CURL_${DEPENDENCY} PROPERTY STRINGS AUTO ON OFF)
|
|
||||||
|
|
||||||
if(CURL_${DEPENDENCY} STREQUAL AUTO)
|
|
||||||
find_package(${DEPENDENCY})
|
|
||||||
elseif(CURL_${DEPENDENCY})
|
|
||||||
find_package(${DEPENDENCY} REQUIRED)
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
|
@ -1,136 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
# The begin of the sources (macros and includes)
|
|
||||||
set(_source_epilogue "#undef inline")
|
|
||||||
|
|
||||||
macro(add_header_include check header)
|
|
||||||
if(${check})
|
|
||||||
set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
set(signature_call_conv)
|
|
||||||
if(HAVE_WINDOWS_H)
|
|
||||||
add_header_include(HAVE_WINSOCK2_H "winsock2.h")
|
|
||||||
add_header_include(HAVE_WINDOWS_H "windows.h")
|
|
||||||
set(_source_epilogue
|
|
||||||
"${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif")
|
|
||||||
set(signature_call_conv "PASCAL")
|
|
||||||
if(HAVE_LIBWS2_32)
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
|
|
||||||
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
|
||||||
|
|
||||||
check_c_source_compiles("${_source_epilogue}
|
|
||||||
int main(void) {
|
|
||||||
int flag = MSG_NOSIGNAL;
|
|
||||||
(void)flag;
|
|
||||||
return 0;
|
|
||||||
}" HAVE_MSG_NOSIGNAL)
|
|
||||||
|
|
||||||
if(NOT HAVE_WINDOWS_H)
|
|
||||||
add_header_include(HAVE_SYS_TIME_H "sys/time.h")
|
|
||||||
add_header_include(TIME_WITH_SYS_TIME "time.h")
|
|
||||||
add_header_include(HAVE_TIME_H "time.h")
|
|
||||||
endif()
|
|
||||||
check_c_source_compiles("${_source_epilogue}
|
|
||||||
int main(void) {
|
|
||||||
struct timeval ts;
|
|
||||||
ts.tv_sec = 0;
|
|
||||||
ts.tv_usec = 0;
|
|
||||||
(void)ts;
|
|
||||||
return 0;
|
|
||||||
}" HAVE_STRUCT_TIMEVAL)
|
|
||||||
|
|
||||||
if(HAVE_WINDOWS_H)
|
|
||||||
set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
|
|
||||||
else()
|
|
||||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
|
||||||
if(HAVE_SYS_SOCKET_H)
|
|
||||||
set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
|
|
||||||
if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
|
|
||||||
set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
|
|
||||||
|
|
||||||
if(NOT CMAKE_CROSSCOMPILING)
|
|
||||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "iOS")
|
|
||||||
# only try this on non-apple platforms
|
|
||||||
|
|
||||||
# if not cross-compilation...
|
|
||||||
include(CheckCSourceRuns)
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "")
|
|
||||||
if(HAVE_SYS_POLL_H)
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
|
|
||||||
elseif(HAVE_POLL_H)
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_POLL_H")
|
|
||||||
endif()
|
|
||||||
check_c_source_runs("
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_POLL_H
|
|
||||||
# include <sys/poll.h>
|
|
||||||
#elif HAVE_POLL_H
|
|
||||||
# include <poll.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
if(0 != poll(0, 0, 10)) {
|
|
||||||
return 1; /* fail */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* detect the 10.12 poll() breakage */
|
|
||||||
struct timeval before, after;
|
|
||||||
int rc;
|
|
||||||
size_t us;
|
|
||||||
|
|
||||||
gettimeofday(&before, NULL);
|
|
||||||
rc = poll(NULL, 0, 500);
|
|
||||||
gettimeofday(&after, NULL);
|
|
||||||
|
|
||||||
us = (after.tv_sec - before.tv_sec) * 1000000 +
|
|
||||||
(after.tv_usec - before.tv_usec);
|
|
||||||
|
|
||||||
if(us < 400000) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}" HAVE_POLL_FINE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
if(NOT UNIX)
|
|
||||||
if(WIN32)
|
|
||||||
set(HAVE_LIBSOCKET 0)
|
|
||||||
set(HAVE_GETHOSTNAME 1)
|
|
||||||
set(HAVE_LIBZ 0)
|
|
||||||
|
|
||||||
set(HAVE_ARPA_INET_H 0)
|
|
||||||
set(HAVE_FCNTL_H 1)
|
|
||||||
set(HAVE_IO_H 1)
|
|
||||||
set(HAVE_NETDB_H 0)
|
|
||||||
set(HAVE_NETINET_IN_H 0)
|
|
||||||
set(HAVE_NET_IF_H 0)
|
|
||||||
set(HAVE_PWD_H 0)
|
|
||||||
set(HAVE_SETJMP_H 1)
|
|
||||||
set(HAVE_SIGNAL_H 1)
|
|
||||||
set(HAVE_STDLIB_H 1)
|
|
||||||
set(HAVE_STRINGS_H 0)
|
|
||||||
set(HAVE_STRING_H 1)
|
|
||||||
set(HAVE_SYS_PARAM_H 0)
|
|
||||||
set(HAVE_SYS_POLL_H 0)
|
|
||||||
set(HAVE_SYS_SELECT_H 0)
|
|
||||||
set(HAVE_SYS_SOCKET_H 0)
|
|
||||||
set(HAVE_SYS_SOCKIO_H 0)
|
|
||||||
set(HAVE_SYS_STAT_H 1)
|
|
||||||
set(HAVE_SYS_TIME_H 0)
|
|
||||||
set(HAVE_SYS_TYPES_H 1)
|
|
||||||
set(HAVE_SYS_UTIME_H 1)
|
|
||||||
set(HAVE_TERMIOS_H 0)
|
|
||||||
set(HAVE_TERMIO_H 0)
|
|
||||||
set(HAVE_TIME_H 1)
|
|
||||||
set(HAVE_UTIME_H 0)
|
|
||||||
|
|
||||||
set(HAVE_SOCKET 1)
|
|
||||||
set(HAVE_SELECT 1)
|
|
||||||
set(HAVE_STRDUP 1)
|
|
||||||
set(HAVE_STRICMP 1)
|
|
||||||
set(HAVE_STRCMPI 1)
|
|
||||||
set(HAVE_GETTIMEOFDAY 0)
|
|
||||||
set(HAVE_CLOSESOCKET 1)
|
|
||||||
set(HAVE_SIGSETJMP 0)
|
|
||||||
set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1)
|
|
||||||
set(HAVE_GETPASS_R 0)
|
|
||||||
set(HAVE_GETPWUID 0)
|
|
||||||
set(HAVE_GETEUID 0)
|
|
||||||
set(HAVE_UTIME 1)
|
|
||||||
set(HAVE_RAND_EGD 0)
|
|
||||||
set(HAVE_GMTIME_R 0)
|
|
||||||
set(HAVE_GETHOSTBYNAME_R 0)
|
|
||||||
set(HAVE_SIGNAL 1)
|
|
||||||
|
|
||||||
set(HAVE_GETHOSTBYNAME_R_3 0)
|
|
||||||
set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
|
|
||||||
set(HAVE_GETHOSTBYNAME_R_5 0)
|
|
||||||
set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0)
|
|
||||||
set(HAVE_GETHOSTBYNAME_R_6 0)
|
|
||||||
set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0)
|
|
||||||
|
|
||||||
set(TIME_WITH_SYS_TIME 0)
|
|
||||||
set(HAVE_O_NONBLOCK 0)
|
|
||||||
set(HAVE_IN_ADDR_T 0)
|
|
||||||
set(STDC_HEADERS 1)
|
|
||||||
|
|
||||||
set(HAVE_SIGACTION 0)
|
|
||||||
set(HAVE_MACRO_SIGSETJMP 0)
|
|
||||||
else()
|
|
||||||
message("This file should be included on Windows platform only")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
|
@ -1,35 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
# File containing various utilities
|
|
||||||
|
|
||||||
# Returns a list of arguments that evaluate to true
|
|
||||||
function(count_true output_count_var)
|
|
||||||
set(lst_len 0)
|
|
||||||
foreach(option_var IN LISTS ARGN)
|
|
||||||
if(${option_var})
|
|
||||||
math(EXPR lst_len "${lst_len} + 1")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
set(${output_count_var} ${lst_len} PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
|
@ -1,49 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
|
||||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
|
||||||
set(CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
|
|
||||||
endif()
|
|
||||||
message(${CMAKE_INSTALL_PREFIX})
|
|
||||||
|
|
||||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
|
||||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
|
||||||
foreach(file ${files})
|
|
||||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
|
||||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
|
||||||
exec_program(
|
|
||||||
"@CMAKE_COMMAND@" ARGS "-E rm -f \"$ENV{DESTDIR}${file}\""
|
|
||||||
OUTPUT_VARIABLE rm_out
|
|
||||||
RETURN_VALUE rm_retval
|
|
||||||
)
|
|
||||||
if(NOT "${rm_retval}" STREQUAL 0)
|
|
||||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
|
@ -1,35 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
@PACKAGE_INIT@
|
|
||||||
|
|
||||||
include(CMakeFindDependencyMacro)
|
|
||||||
if(@USE_OPENSSL@)
|
|
||||||
find_dependency(OpenSSL @OPENSSL_VERSION_MAJOR@)
|
|
||||||
endif()
|
|
||||||
if(@USE_ZLIB@)
|
|
||||||
find_dependency(ZLIB @ZLIB_VERSION_MAJOR@)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
|
|
||||||
check_required_components("@PROJECT_NAME@")
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,22 +0,0 @@
|
||||||
COPYRIGHT AND PERMISSION NOTICE
|
|
||||||
|
|
||||||
Copyright (c) 1996 - 2023, Daniel Stenberg, <daniel@haxx.se>, and many
|
|
||||||
contributors, see the THANKS file.
|
|
||||||
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software for any purpose
|
|
||||||
with or without fee is hereby granted, provided that the above copyright
|
|
||||||
notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
|
|
||||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
||||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
Except as contained in this notice, the name of a copyright holder shall not
|
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
|
||||||
in this Software without prior written authorization of the copyright holder.
|
|
|
@ -1,81 +0,0 @@
|
||||||
#include "curl/curl.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
int test_curl(const char* url)
|
|
||||||
{
|
|
||||||
CURL* curl;
|
|
||||||
CURLcode r;
|
|
||||||
char proxy[1024];
|
|
||||||
int proxy_type = 0;
|
|
||||||
|
|
||||||
if (getenv("HTTP_PROXY")) {
|
|
||||||
proxy_type = 1;
|
|
||||||
if (getenv("HTTP_PROXY_PORT")) {
|
|
||||||
sprintf(proxy, "%s:%s", getenv("HTTP_PROXY"), getenv("HTTP_PROXY_PORT"));
|
|
||||||
} else {
|
|
||||||
sprintf(proxy, "%s", getenv("HTTP_PROXY"));
|
|
||||||
}
|
|
||||||
if (getenv("HTTP_PROXY_TYPE")) {
|
|
||||||
/* HTTP/SOCKS4/SOCKS5 */
|
|
||||||
if (strcmp(getenv("HTTP_PROXY_TYPE"), "HTTP") == 0) {
|
|
||||||
proxy_type = 1;
|
|
||||||
} else if (strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS4") == 0) {
|
|
||||||
proxy_type = 2;
|
|
||||||
} else if (strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS5") == 0) {
|
|
||||||
proxy_type = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
curl = curl_easy_init();
|
|
||||||
if (!curl) {
|
|
||||||
fprintf(stderr, "curl_easy_init failed\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
|
|
||||||
|
|
||||||
if (proxy_type > 0) {
|
|
||||||
curl_easy_setopt(curl, CURLOPT_PROXY, proxy);
|
|
||||||
switch (proxy_type) {
|
|
||||||
case 2:
|
|
||||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
||||||
r = curl_easy_perform(curl);
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
|
|
||||||
if (r != CURLE_OK) {
|
|
||||||
fprintf(stderr, "error: fetching '%s' failed: %s\n", url,
|
|
||||||
curl_easy_strerror(r));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, const char* argv[])
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
||||||
if (argc == 2) {
|
|
||||||
r = test_curl(argv[1]);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "error: no URL given as first argument\n");
|
|
||||||
r = 1;
|
|
||||||
}
|
|
||||||
curl_global_cleanup();
|
|
||||||
return r;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,79 +0,0 @@
|
||||||
#ifndef CURLINC_CURLVER_H
|
|
||||||
#define CURLINC_CURLVER_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/* This header file contains nothing but libcurl version info, generated by
|
|
||||||
a script at release-time. This was made its own header file in 7.11.2 */
|
|
||||||
|
|
||||||
/* This is the global package copyright */
|
|
||||||
#define LIBCURL_COPYRIGHT "Daniel Stenberg, <daniel@haxx.se>."
|
|
||||||
|
|
||||||
/* This is the version number of the libcurl package from which this header
|
|
||||||
file origins: */
|
|
||||||
#define LIBCURL_VERSION "8.0.1"
|
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
|
||||||
defines: */
|
|
||||||
#define LIBCURL_VERSION_MAJOR 8
|
|
||||||
#define LIBCURL_VERSION_MINOR 0
|
|
||||||
#define LIBCURL_VERSION_PATCH 1
|
|
||||||
|
|
||||||
/* This is the numeric version of the libcurl version number, meant for easier
|
|
||||||
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
|
|
||||||
always follow this syntax:
|
|
||||||
|
|
||||||
0xXXYYZZ
|
|
||||||
|
|
||||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
|
||||||
hexadecimal (using 8 bits each). All three numbers are always represented
|
|
||||||
using two digits. 1.2 would appear as "0x010200" while version 9.11.7
|
|
||||||
appears as "0x090b07".
|
|
||||||
|
|
||||||
This 6-digit (24 bits) hexadecimal number does not show pre-release number,
|
|
||||||
and it is always a greater number in a more recent release. It makes
|
|
||||||
comparisons with greater than and less than work.
|
|
||||||
|
|
||||||
Note: This define is the full hex number and _does not_ use the
|
|
||||||
CURL_VERSION_BITS() macro since curl's own configure script greps for it
|
|
||||||
and needs it to contain the full number.
|
|
||||||
*/
|
|
||||||
#define LIBCURL_VERSION_NUM 0x080001
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the date and time when the full source package was created. The
|
|
||||||
* timestamp is not stored in git, as the timestamp is properly set in the
|
|
||||||
* tarballs by the maketgz script.
|
|
||||||
*
|
|
||||||
* The format of the date follows this template:
|
|
||||||
*
|
|
||||||
* "2007-11-23"
|
|
||||||
*/
|
|
||||||
#define LIBCURL_TIMESTAMP "[unreleased]"
|
|
||||||
|
|
||||||
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
|
|
||||||
#define CURL_AT_LEAST_VERSION(x,y,z) \
|
|
||||||
(LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
|
|
||||||
|
|
||||||
#endif /* CURLINC_CURLVER_H */
|
|
|
@ -1,125 +0,0 @@
|
||||||
#ifndef CURLINC_EASY_H
|
|
||||||
#define CURLINC_EASY_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Flag bits in the curl_blob struct: */
|
|
||||||
#define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */
|
|
||||||
#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */
|
|
||||||
|
|
||||||
struct curl_blob {
|
|
||||||
void *data;
|
|
||||||
size_t len;
|
|
||||||
unsigned int flags; /* bit 0 is defined, the rest are reserved and should be
|
|
||||||
left zeroes */
|
|
||||||
};
|
|
||||||
|
|
||||||
CURL_EXTERN CURL *curl_easy_init(void);
|
|
||||||
CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
|
|
||||||
CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
|
|
||||||
CURL_EXTERN void curl_easy_cleanup(CURL *curl);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NAME curl_easy_getinfo()
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* Request internal information from the curl session with this function. The
|
|
||||||
* third argument MUST be a pointer to a long, a pointer to a char * or a
|
|
||||||
* pointer to a double (as the documentation describes elsewhere). The data
|
|
||||||
* pointed to will be filled in accordingly and can be relied upon only if the
|
|
||||||
* function returns CURLE_OK. This function is intended to get used *AFTER* a
|
|
||||||
* performed transfer, all results from this function are undefined until the
|
|
||||||
* transfer is completed.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NAME curl_easy_duphandle()
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* Creates a new curl session handle with the same options set for the handle
|
|
||||||
* passed in. Duplicating a handle could only be a matter of cloning data and
|
|
||||||
* options, internal state info and things like persistent connections cannot
|
|
||||||
* be transferred. It is useful in multithreaded applications when you can run
|
|
||||||
* curl_easy_duphandle() for each new thread to avoid a series of identical
|
|
||||||
* curl_easy_setopt() invokes in every thread.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NAME curl_easy_reset()
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* Re-initializes a CURL handle to the default values. This puts back the
|
|
||||||
* handle to the same state as it was in when it was just created.
|
|
||||||
*
|
|
||||||
* It does keep: live connections, the Session ID cache, the DNS cache and the
|
|
||||||
* cookies.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN void curl_easy_reset(CURL *curl);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NAME curl_easy_recv()
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* Receives data from the connected socket. Use after successful
|
|
||||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
|
|
||||||
size_t *n);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NAME curl_easy_send()
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* Sends data over the connected socket. Use after successful
|
|
||||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
|
|
||||||
size_t buflen, size_t *n);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NAME curl_easy_upkeep()
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* Performs connection upkeep for the given session handle.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* end of extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,74 +0,0 @@
|
||||||
#ifndef CURLINC_HEADER_H
|
|
||||||
#define CURLINC_HEADER_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct curl_header {
|
|
||||||
char *name; /* this might not use the same case */
|
|
||||||
char *value;
|
|
||||||
size_t amount; /* number of headers using this name */
|
|
||||||
size_t index; /* ... of this instance, 0 or higher */
|
|
||||||
unsigned int origin; /* see bits below */
|
|
||||||
void *anchor; /* handle privately used by libcurl */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 'origin' bits */
|
|
||||||
#define CURLH_HEADER (1<<0) /* plain server header */
|
|
||||||
#define CURLH_TRAILER (1<<1) /* trailers */
|
|
||||||
#define CURLH_CONNECT (1<<2) /* CONNECT headers */
|
|
||||||
#define CURLH_1XX (1<<3) /* 1xx headers */
|
|
||||||
#define CURLH_PSEUDO (1<<4) /* pseudo headers */
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CURLHE_OK,
|
|
||||||
CURLHE_BADINDEX, /* header exists but not with this index */
|
|
||||||
CURLHE_MISSING, /* no such header exists */
|
|
||||||
CURLHE_NOHEADERS, /* no headers at all exist (yet) */
|
|
||||||
CURLHE_NOREQUEST, /* no request with this number was used */
|
|
||||||
CURLHE_OUT_OF_MEMORY, /* out of memory while processing */
|
|
||||||
CURLHE_BAD_ARGUMENT, /* a function argument was not okay */
|
|
||||||
CURLHE_NOT_BUILT_IN /* if API was disabled in the build */
|
|
||||||
} CURLHcode;
|
|
||||||
|
|
||||||
CURL_EXTERN CURLHcode curl_easy_header(CURL *easy,
|
|
||||||
const char *name,
|
|
||||||
size_t index,
|
|
||||||
unsigned int origin,
|
|
||||||
int request,
|
|
||||||
struct curl_header **hout);
|
|
||||||
|
|
||||||
CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *easy,
|
|
||||||
unsigned int origin,
|
|
||||||
int request,
|
|
||||||
struct curl_header *prev);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* end of extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CURLINC_HEADER_H */
|
|
|
@ -1,52 +0,0 @@
|
||||||
#ifndef CURLINC_MPRINTF_H
|
|
||||||
#define CURLINC_MPRINTF_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h> /* needed for FILE */
|
|
||||||
#include "curl.h" /* for CURL_EXTERN */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CURL_EXTERN int curl_mprintf(const char *format, ...);
|
|
||||||
CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
|
|
||||||
CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
|
|
||||||
CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
|
|
||||||
const char *format, ...);
|
|
||||||
CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
|
|
||||||
CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
|
|
||||||
CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
|
|
||||||
CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
|
|
||||||
const char *format, va_list args);
|
|
||||||
CURL_EXTERN char *curl_maprintf(const char *format, ...);
|
|
||||||
CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* end of extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CURLINC_MPRINTF_H */
|
|
|
@ -1,460 +0,0 @@
|
||||||
#ifndef CURLINC_MULTI_H
|
|
||||||
#define CURLINC_MULTI_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
/*
|
|
||||||
This is an "external" header file. Don't give away any internals here!
|
|
||||||
|
|
||||||
GOALS
|
|
||||||
|
|
||||||
o Enable a "pull" interface. The application that uses libcurl decides where
|
|
||||||
and when to ask libcurl to get/send data.
|
|
||||||
|
|
||||||
o Enable multiple simultaneous transfers in the same thread without making it
|
|
||||||
complicated for the application.
|
|
||||||
|
|
||||||
o Enable the application to select() on its own file descriptors and curl's
|
|
||||||
file descriptors simultaneous easily.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This header file should not really need to include "curl.h" since curl.h
|
|
||||||
* itself includes this file and we expect user applications to do #include
|
|
||||||
* <curl/curl.h> without the need for especially including multi.h.
|
|
||||||
*
|
|
||||||
* For some reason we added this include here at one point, and rather than to
|
|
||||||
* break existing (wrongly written) libcurl applications, we leave it as-is
|
|
||||||
* but with this warning attached.
|
|
||||||
*/
|
|
||||||
#include "curl.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
|
|
||||||
typedef struct Curl_multi CURLM;
|
|
||||||
#else
|
|
||||||
typedef void CURLM;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
|
|
||||||
curl_multi_socket*() soon */
|
|
||||||
CURLM_OK,
|
|
||||||
CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
|
|
||||||
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
|
||||||
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
|
||||||
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
|
||||||
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
|
|
||||||
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
|
|
||||||
CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
|
|
||||||
attempted to get added - again */
|
|
||||||
CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
|
|
||||||
callback */
|
|
||||||
CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */
|
|
||||||
CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */
|
|
||||||
CURLM_ABORTED_BY_CALLBACK,
|
|
||||||
CURLM_UNRECOVERABLE_POLL,
|
|
||||||
CURLM_LAST
|
|
||||||
} CURLMcode;
|
|
||||||
|
|
||||||
/* just to make code nicer when using curl_multi_socket() you can now check
|
|
||||||
for CURLM_CALL_MULTI_SOCKET too in the same style it works for
|
|
||||||
curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
|
|
||||||
#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
|
|
||||||
|
|
||||||
/* bitmask bits for CURLMOPT_PIPELINING */
|
|
||||||
#define CURLPIPE_NOTHING 0L
|
|
||||||
#define CURLPIPE_HTTP1 1L
|
|
||||||
#define CURLPIPE_MULTIPLEX 2L
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CURLMSG_NONE, /* first, not used */
|
|
||||||
CURLMSG_DONE, /* This easy handle has completed. 'result' contains
|
|
||||||
the CURLcode of the transfer */
|
|
||||||
CURLMSG_LAST /* last, not used */
|
|
||||||
} CURLMSG;
|
|
||||||
|
|
||||||
struct CURLMsg {
|
|
||||||
CURLMSG msg; /* what this message means */
|
|
||||||
CURL *easy_handle; /* the handle it concerns */
|
|
||||||
union {
|
|
||||||
void *whatever; /* message-specific data */
|
|
||||||
CURLcode result; /* return code for transfer */
|
|
||||||
} data;
|
|
||||||
};
|
|
||||||
typedef struct CURLMsg CURLMsg;
|
|
||||||
|
|
||||||
/* Based on poll(2) structure and values.
|
|
||||||
* We don't use pollfd and POLL* constants explicitly
|
|
||||||
* to cover platforms without poll(). */
|
|
||||||
#define CURL_WAIT_POLLIN 0x0001
|
|
||||||
#define CURL_WAIT_POLLPRI 0x0002
|
|
||||||
#define CURL_WAIT_POLLOUT 0x0004
|
|
||||||
|
|
||||||
struct curl_waitfd {
|
|
||||||
curl_socket_t fd;
|
|
||||||
short events;
|
|
||||||
short revents; /* not supported yet */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_init()
|
|
||||||
*
|
|
||||||
* Desc: initialize multi-style curl usage
|
|
||||||
*
|
|
||||||
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLM *curl_multi_init(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_add_handle()
|
|
||||||
*
|
|
||||||
* Desc: add a standard curl handle to the multi stack
|
|
||||||
*
|
|
||||||
* Returns: CURLMcode type, general multi error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
|
||||||
CURL *curl_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_remove_handle()
|
|
||||||
*
|
|
||||||
* Desc: removes a curl handle from the multi stack again
|
|
||||||
*
|
|
||||||
* Returns: CURLMcode type, general multi error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
|
||||||
CURL *curl_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_fdset()
|
|
||||||
*
|
|
||||||
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
|
||||||
* poll() on. We want curl_multi_perform() called as soon as one of
|
|
||||||
* them are ready.
|
|
||||||
*
|
|
||||||
* Returns: CURLMcode type, general multi error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
|
||||||
fd_set *read_fd_set,
|
|
||||||
fd_set *write_fd_set,
|
|
||||||
fd_set *exc_fd_set,
|
|
||||||
int *max_fd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_wait()
|
|
||||||
*
|
|
||||||
* Desc: Poll on all fds within a CURLM set as well as any
|
|
||||||
* additional fds passed to the function.
|
|
||||||
*
|
|
||||||
* Returns: CURLMcode type, general multi error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
|
|
||||||
struct curl_waitfd extra_fds[],
|
|
||||||
unsigned int extra_nfds,
|
|
||||||
int timeout_ms,
|
|
||||||
int *ret);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_poll()
|
|
||||||
*
|
|
||||||
* Desc: Poll on all fds within a CURLM set as well as any
|
|
||||||
* additional fds passed to the function.
|
|
||||||
*
|
|
||||||
* Returns: CURLMcode type, general multi error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
|
|
||||||
struct curl_waitfd extra_fds[],
|
|
||||||
unsigned int extra_nfds,
|
|
||||||
int timeout_ms,
|
|
||||||
int *ret);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_wakeup()
|
|
||||||
*
|
|
||||||
* Desc: wakes up a sleeping curl_multi_poll call.
|
|
||||||
*
|
|
||||||
* Returns: CURLMcode type, general multi error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_perform()
|
|
||||||
*
|
|
||||||
* Desc: When the app thinks there's data available for curl it calls this
|
|
||||||
* function to read/write whatever there is right now. This returns
|
|
||||||
* as soon as the reads and writes are done. This function does not
|
|
||||||
* require that there actually is data available for reading or that
|
|
||||||
* data can be written, it can be called just in case. It returns
|
|
||||||
* the number of handles that still transfer data in the second
|
|
||||||
* argument's integer-pointer.
|
|
||||||
*
|
|
||||||
* Returns: CURLMcode type, general multi error code. *NOTE* that this only
|
|
||||||
* returns errors etc regarding the whole multi stack. There might
|
|
||||||
* still have occurred problems on individual transfers even when
|
|
||||||
* this returns OK.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
|
|
||||||
int *running_handles);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_cleanup()
|
|
||||||
*
|
|
||||||
* Desc: Cleans up and removes a whole multi stack. It does not free or
|
|
||||||
* touch any individual easy handles in any way. We need to define
|
|
||||||
* in what state those handles will be if this function is called
|
|
||||||
* in the middle of a transfer.
|
|
||||||
*
|
|
||||||
* Returns: CURLMcode type, general multi error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_info_read()
|
|
||||||
*
|
|
||||||
* Desc: Ask the multi handle if there's any messages/informationals from
|
|
||||||
* the individual transfers. Messages include informationals such as
|
|
||||||
* error code from the transfer or just the fact that a transfer is
|
|
||||||
* completed. More details on these should be written down as well.
|
|
||||||
*
|
|
||||||
* Repeated calls to this function will return a new struct each
|
|
||||||
* time, until a special "end of msgs" struct is returned as a signal
|
|
||||||
* that there is no more to get at this point.
|
|
||||||
*
|
|
||||||
* The data the returned pointer points to will not survive calling
|
|
||||||
* curl_multi_cleanup().
|
|
||||||
*
|
|
||||||
* The 'CURLMsg' struct is meant to be very simple and only contain
|
|
||||||
* very basic information. If more involved information is wanted,
|
|
||||||
* we will provide the particular "transfer handle" in that struct
|
|
||||||
* and that should/could/would be used in subsequent
|
|
||||||
* curl_easy_getinfo() calls (or similar). The point being that we
|
|
||||||
* must never expose complex structs to applications, as then we'll
|
|
||||||
* undoubtably get backwards compatibility problems in the future.
|
|
||||||
*
|
|
||||||
* Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
|
|
||||||
* of structs. It also writes the number of messages left in the
|
|
||||||
* queue (after this read) in the integer the second argument points
|
|
||||||
* to.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
|
||||||
int *msgs_in_queue);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_strerror()
|
|
||||||
*
|
|
||||||
* Desc: The curl_multi_strerror function may be used to turn a CURLMcode
|
|
||||||
* value into the equivalent human readable error string. This is
|
|
||||||
* useful for printing meaningful error messages.
|
|
||||||
*
|
|
||||||
* Returns: A pointer to a null-terminated error message.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_socket() and
|
|
||||||
* curl_multi_socket_all()
|
|
||||||
*
|
|
||||||
* Desc: An alternative version of curl_multi_perform() that allows the
|
|
||||||
* application to pass in one of the file descriptors that have been
|
|
||||||
* detected to have "action" on them and let libcurl perform.
|
|
||||||
* See man page for details.
|
|
||||||
*/
|
|
||||||
#define CURL_POLL_NONE 0
|
|
||||||
#define CURL_POLL_IN 1
|
|
||||||
#define CURL_POLL_OUT 2
|
|
||||||
#define CURL_POLL_INOUT 3
|
|
||||||
#define CURL_POLL_REMOVE 4
|
|
||||||
|
|
||||||
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
|
||||||
|
|
||||||
#define CURL_CSELECT_IN 0x01
|
|
||||||
#define CURL_CSELECT_OUT 0x02
|
|
||||||
#define CURL_CSELECT_ERR 0x04
|
|
||||||
|
|
||||||
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
|
||||||
curl_socket_t s, /* socket */
|
|
||||||
int what, /* see above */
|
|
||||||
void *userp, /* private callback
|
|
||||||
pointer */
|
|
||||||
void *socketp); /* private socket
|
|
||||||
pointer */
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_timer_callback
|
|
||||||
*
|
|
||||||
* Desc: Called by libcurl whenever the library detects a change in the
|
|
||||||
* maximum number of milliseconds the app is allowed to wait before
|
|
||||||
* curl_multi_socket() or curl_multi_perform() must be called
|
|
||||||
* (to allow libcurl's timed events to take place).
|
|
||||||
*
|
|
||||||
* Returns: The callback should return zero.
|
|
||||||
*/
|
|
||||||
typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
|
|
||||||
long timeout_ms, /* see above */
|
|
||||||
void *userp); /* private callback
|
|
||||||
pointer */
|
|
||||||
|
|
||||||
CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()")
|
|
||||||
curl_multi_socket(CURLM *multi_handle, curl_socket_t s, int *running_handles);
|
|
||||||
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
|
|
||||||
curl_socket_t s,
|
|
||||||
int ev_bitmask,
|
|
||||||
int *running_handles);
|
|
||||||
|
|
||||||
CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()")
|
|
||||||
curl_multi_socket_all(CURLM *multi_handle, int *running_handles);
|
|
||||||
|
|
||||||
#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
|
|
||||||
/* This macro below was added in 7.16.3 to push users who recompile to use
|
|
||||||
the new curl_multi_socket_action() instead of the old curl_multi_socket()
|
|
||||||
*/
|
|
||||||
#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_timeout()
|
|
||||||
*
|
|
||||||
* Desc: Returns the maximum number of milliseconds the app is allowed to
|
|
||||||
* wait before curl_multi_socket() or curl_multi_perform() must be
|
|
||||||
* called (to allow libcurl's timed events to take place).
|
|
||||||
*
|
|
||||||
* Returns: CURLM error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
|
|
||||||
long *milliseconds);
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
/* This is the socket callback function pointer */
|
|
||||||
CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1),
|
|
||||||
|
|
||||||
/* This is the argument passed to the socket callback */
|
|
||||||
CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2),
|
|
||||||
|
|
||||||
/* set to 1 to enable pipelining for this multi handle */
|
|
||||||
CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3),
|
|
||||||
|
|
||||||
/* This is the timer callback function pointer */
|
|
||||||
CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4),
|
|
||||||
|
|
||||||
/* This is the argument passed to the timer callback */
|
|
||||||
CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5),
|
|
||||||
|
|
||||||
/* maximum number of entries in the connection cache */
|
|
||||||
CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6),
|
|
||||||
|
|
||||||
/* maximum number of (pipelining) connections to one host */
|
|
||||||
CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7),
|
|
||||||
|
|
||||||
/* maximum number of requests in a pipeline */
|
|
||||||
CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8),
|
|
||||||
|
|
||||||
/* a connection with a content-length longer than this
|
|
||||||
will not be considered for pipelining */
|
|
||||||
CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9),
|
|
||||||
|
|
||||||
/* a connection with a chunk length longer than this
|
|
||||||
will not be considered for pipelining */
|
|
||||||
CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10),
|
|
||||||
|
|
||||||
/* a list of site names(+port) that are blocked from pipelining */
|
|
||||||
CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11),
|
|
||||||
|
|
||||||
/* a list of server types that are blocked from pipelining */
|
|
||||||
CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12),
|
|
||||||
|
|
||||||
/* maximum number of open connections in total */
|
|
||||||
CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13),
|
|
||||||
|
|
||||||
/* This is the server push callback function pointer */
|
|
||||||
CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14),
|
|
||||||
|
|
||||||
/* This is the argument passed to the server push callback */
|
|
||||||
CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15),
|
|
||||||
|
|
||||||
/* maximum number of concurrent streams to support on a connection */
|
|
||||||
CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16),
|
|
||||||
|
|
||||||
CURLMOPT_LASTENTRY /* the last unused */
|
|
||||||
} CURLMoption;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_setopt()
|
|
||||||
*
|
|
||||||
* Desc: Sets options for the multi handle.
|
|
||||||
*
|
|
||||||
* Returns: CURLM error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
|
||||||
CURLMoption option, ...);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_multi_assign()
|
|
||||||
*
|
|
||||||
* Desc: This function sets an association in the multi handle between the
|
|
||||||
* given socket and a private pointer of the application. This is
|
|
||||||
* (only) useful for curl_multi_socket uses.
|
|
||||||
*
|
|
||||||
* Returns: CURLM error code.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
|
|
||||||
curl_socket_t sockfd, void *sockp);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name: curl_push_callback
|
|
||||||
*
|
|
||||||
* Desc: This callback gets called when a new stream is being pushed by the
|
|
||||||
* server. It approves or denies the new stream. It can also decide
|
|
||||||
* to completely fail the connection.
|
|
||||||
*
|
|
||||||
* Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT
|
|
||||||
*/
|
|
||||||
#define CURL_PUSH_OK 0
|
|
||||||
#define CURL_PUSH_DENY 1
|
|
||||||
#define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */
|
|
||||||
|
|
||||||
struct curl_pushheaders; /* forward declaration only */
|
|
||||||
|
|
||||||
CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
|
|
||||||
size_t num);
|
|
||||||
CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
|
|
||||||
const char *name);
|
|
||||||
|
|
||||||
typedef int (*curl_push_callback)(CURL *parent,
|
|
||||||
CURL *easy,
|
|
||||||
size_t num_headers,
|
|
||||||
struct curl_pushheaders *headers,
|
|
||||||
void *userp);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* end of extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,70 +0,0 @@
|
||||||
#ifndef CURLINC_OPTIONS_H
|
|
||||||
#define CURLINC_OPTIONS_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CURLOT_LONG, /* long (a range of values) */
|
|
||||||
CURLOT_VALUES, /* (a defined set or bitmask) */
|
|
||||||
CURLOT_OFF_T, /* curl_off_t (a range of values) */
|
|
||||||
CURLOT_OBJECT, /* pointer (void *) */
|
|
||||||
CURLOT_STRING, /* (char * to null-terminated buffer) */
|
|
||||||
CURLOT_SLIST, /* (struct curl_slist *) */
|
|
||||||
CURLOT_CBPTR, /* (void * passed as-is to a callback) */
|
|
||||||
CURLOT_BLOB, /* blob (struct curl_blob *) */
|
|
||||||
CURLOT_FUNCTION /* function pointer */
|
|
||||||
} curl_easytype;
|
|
||||||
|
|
||||||
/* Flag bits */
|
|
||||||
|
|
||||||
/* "alias" means it is provided for old programs to remain functional,
|
|
||||||
we prefer another name */
|
|
||||||
#define CURLOT_FLAG_ALIAS (1<<0)
|
|
||||||
|
|
||||||
/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size
|
|
||||||
to use for curl_easy_setopt() for the given id */
|
|
||||||
struct curl_easyoption {
|
|
||||||
const char *name;
|
|
||||||
CURLoption id;
|
|
||||||
curl_easytype type;
|
|
||||||
unsigned int flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
CURL_EXTERN const struct curl_easyoption *
|
|
||||||
curl_easy_option_by_name(const char *name);
|
|
||||||
|
|
||||||
CURL_EXTERN const struct curl_easyoption *
|
|
||||||
curl_easy_option_by_id(CURLoption id);
|
|
||||||
|
|
||||||
CURL_EXTERN const struct curl_easyoption *
|
|
||||||
curl_easy_option_next(const struct curl_easyoption *prev);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* end of extern "C" */
|
|
||||||
#endif
|
|
||||||
#endif /* CURLINC_OPTIONS_H */
|
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef CURLINC_STDCHEADERS_H
|
|
||||||
#define CURLINC_STDCHEADERS_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
size_t fread(void *, size_t, size_t, FILE *);
|
|
||||||
size_t fwrite(const void *, size_t, size_t, FILE *);
|
|
||||||
|
|
||||||
int strcasecmp(const char *, const char *);
|
|
||||||
int strncasecmp(const char *, const char *, size_t);
|
|
||||||
|
|
||||||
#endif /* CURLINC_STDCHEADERS_H */
|
|
|
@ -1,508 +0,0 @@
|
||||||
#ifndef CURLINC_SYSTEM_H
|
|
||||||
#define CURLINC_SYSTEM_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to keep one section per platform, compiler and architecture, otherwise,
|
|
||||||
* if an existing section is reused for a different one and later on the
|
|
||||||
* original is adjusted, probably the piggybacking one can be adversely
|
|
||||||
* changed.
|
|
||||||
*
|
|
||||||
* In order to differentiate between platforms/compilers/architectures use
|
|
||||||
* only compiler built in predefined preprocessor symbols.
|
|
||||||
*
|
|
||||||
* curl_off_t
|
|
||||||
* ----------
|
|
||||||
*
|
|
||||||
* For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
|
|
||||||
* wide signed integral data type. The width of this data type must remain
|
|
||||||
* constant and independent of any possible large file support settings.
|
|
||||||
*
|
|
||||||
* As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
|
|
||||||
* wide signed integral data type if there is no 64-bit type.
|
|
||||||
*
|
|
||||||
* As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
|
|
||||||
* only be violated if off_t is the only 64-bit data type available and the
|
|
||||||
* size of off_t is independent of large file support settings. Keep your
|
|
||||||
* build on the safe side avoiding an off_t gating. If you have a 64-bit
|
|
||||||
* off_t then take for sure that another 64-bit data type exists, dig deeper
|
|
||||||
* and you will find it.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__DJGPP__) || defined(__GO32__)
|
|
||||||
# if defined(__DJGPP__) && (__DJGPP__ > 1)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# else
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
|
|
||||||
#elif defined(__SALFORDC__)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
|
|
||||||
#elif defined(__BORLANDC__)
|
|
||||||
# if (__BORLANDC__ < 0x520)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# else
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
|
|
||||||
#elif defined(__TURBOC__)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
|
|
||||||
#elif defined(__POCC__)
|
|
||||||
# if (__POCC__ < 280)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# elif defined(_MSC_VER)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
|
||||||
# else
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
|
|
||||||
#elif defined(__LCC__)
|
|
||||||
# if defined(__MCST__) /* MCST eLbrus Compiler Collection */
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
|
||||||
# define CURL_PULL_SYS_TYPES_H 1
|
|
||||||
# define CURL_PULL_SYS_SOCKET_H 1
|
|
||||||
# else /* Local (or Little) C Compiler */
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__SYMBIAN32__)
|
|
||||||
# if defined(__EABI__) /* Treat all ARM compilers equally */
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# elif defined(__CW32__)
|
|
||||||
# pragma longlong on
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# elif defined(__VC32__)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
|
|
||||||
|
|
||||||
#elif defined(macintosh)
|
|
||||||
# include <ConditionalMacros.h>
|
|
||||||
# if TYPE_LONGLONG
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# else
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
|
|
||||||
|
|
||||||
#elif defined(__TANDEM)
|
|
||||||
# if ! defined(__LP64)
|
|
||||||
/* Required for 32-bit NonStop builds only. */
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(_WIN32_WCE)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
|
|
||||||
#elif defined(__MINGW32__)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
|
||||||
# define CURL_PULL_SYS_TYPES_H 1
|
|
||||||
# define CURL_PULL_WS2TCPIP_H 1
|
|
||||||
|
|
||||||
#elif defined(__VMS)
|
|
||||||
# if defined(__VAX)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# else
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
|
|
||||||
|
|
||||||
#elif defined(__OS400__)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
|
||||||
# define CURL_PULL_SYS_TYPES_H 1
|
|
||||||
# define CURL_PULL_SYS_SOCKET_H 1
|
|
||||||
|
|
||||||
#elif defined(__MVS__)
|
|
||||||
# if defined(__IBMC__) || defined(__IBMCPP__)
|
|
||||||
# if defined(_ILP32)
|
|
||||||
# elif defined(_LP64)
|
|
||||||
# endif
|
|
||||||
# if defined(_LONG_LONG)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# elif defined(_LP64)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# else
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
|
||||||
# define CURL_PULL_SYS_TYPES_H 1
|
|
||||||
# define CURL_PULL_SYS_SOCKET_H 1
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__370__)
|
|
||||||
# if defined(__IBMC__) || defined(__IBMCPP__)
|
|
||||||
# if defined(_ILP32)
|
|
||||||
# elif defined(_LP64)
|
|
||||||
# endif
|
|
||||||
# if defined(_LONG_LONG)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# elif defined(_LP64)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# else
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
|
||||||
# define CURL_PULL_SYS_TYPES_H 1
|
|
||||||
# define CURL_PULL_SYS_SOCKET_H 1
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(TPF)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
|
|
||||||
#elif defined(__TINYC__) /* also known as tcc */
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
|
||||||
# define CURL_PULL_SYS_TYPES_H 1
|
|
||||||
# define CURL_PULL_SYS_SOCKET_H 1
|
|
||||||
|
|
||||||
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */
|
|
||||||
# if !defined(__LP64) && (defined(__ILP32) || \
|
|
||||||
defined(__i386) || \
|
|
||||||
defined(__sparcv8) || \
|
|
||||||
defined(__sparcv8plus))
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# elif defined(__LP64) || \
|
|
||||||
defined(__amd64) || defined(__sparcv9)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
|
||||||
# define CURL_PULL_SYS_TYPES_H 1
|
|
||||||
# define CURL_PULL_SYS_SOCKET_H 1
|
|
||||||
|
|
||||||
#elif defined(__xlc__) /* IBM xlc compiler */
|
|
||||||
# if !defined(_LP64)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# else
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
|
||||||
# define CURL_PULL_SYS_TYPES_H 1
|
|
||||||
# define CURL_PULL_SYS_SOCKET_H 1
|
|
||||||
|
|
||||||
/* ===================================== */
|
|
||||||
/* KEEP MSVC THE PENULTIMATE ENTRY */
|
|
||||||
/* ===================================== */
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
|
||||||
# else
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
|
|
||||||
/* ===================================== */
|
|
||||||
/* KEEP GENERIC GCC THE LAST ENTRY */
|
|
||||||
/* ===================================== */
|
|
||||||
|
|
||||||
#elif defined(__GNUC__) && !defined(_SCO_DS)
|
|
||||||
# if !defined(__LP64__) && \
|
|
||||||
(defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \
|
|
||||||
defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \
|
|
||||||
defined(__sparc__) || defined(__mips__) || defined(__sh__) || \
|
|
||||||
defined(__XTENSA__) || \
|
|
||||||
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \
|
|
||||||
(defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L))
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
|
||||||
# elif defined(__LP64__) || \
|
|
||||||
defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
|
|
||||||
defined(__e2k__) || \
|
|
||||||
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
|
|
||||||
(defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# endif
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
|
||||||
# define CURL_PULL_SYS_TYPES_H 1
|
|
||||||
# define CURL_PULL_SYS_SOCKET_H 1
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* generic "safe guess" on old 32 bit style */
|
|
||||||
# define CURL_TYPEOF_CURL_OFF_T long
|
|
||||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
|
||||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_T L
|
|
||||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
|
||||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _AIX
|
|
||||||
/* AIX needs <sys/poll.h> */
|
|
||||||
#define CURL_PULL_SYS_POLL_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */
|
|
||||||
/* ws2tcpip.h is required here to properly make type definitions below. */
|
|
||||||
#ifdef CURL_PULL_WS2TCPIP_H
|
|
||||||
# include <winsock2.h>
|
|
||||||
# include <windows.h>
|
|
||||||
# include <ws2tcpip.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */
|
|
||||||
/* sys/types.h is required here to properly make type definitions below. */
|
|
||||||
#ifdef CURL_PULL_SYS_TYPES_H
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
|
|
||||||
/* sys/socket.h is required here to properly make type definitions below. */
|
|
||||||
#ifdef CURL_PULL_SYS_SOCKET_H
|
|
||||||
# include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */
|
|
||||||
/* sys/poll.h is required here to properly make type definitions below. */
|
|
||||||
#ifdef CURL_PULL_SYS_POLL_H
|
|
||||||
# include <sys/poll.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Data type definition of curl_socklen_t. */
|
|
||||||
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
|
||||||
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Data type definition of curl_off_t. */
|
|
||||||
|
|
||||||
#ifdef CURL_TYPEOF_CURL_OFF_T
|
|
||||||
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
|
|
||||||
* these to be visible and exported by the external libcurl interface API,
|
|
||||||
* while also making them visible to the library internals, simply including
|
|
||||||
* curl_setup.h, without actually needing to include curl.h internally.
|
|
||||||
* If some day this section would grow big enough, all this should be moved
|
|
||||||
* to its own header file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Figure out if we can use the ## preprocessor operator, which is supported
|
|
||||||
* by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
|
|
||||||
* or __cplusplus so we need to carefully check for them too.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
|
||||||
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
|
|
||||||
defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
|
|
||||||
defined(__ILEC400__)
|
|
||||||
/* This compiler is believed to have an ISO compatible preprocessor */
|
|
||||||
#define CURL_ISOCPP
|
|
||||||
#else
|
|
||||||
/* This compiler is believed NOT to have an ISO compatible preprocessor */
|
|
||||||
#undef CURL_ISOCPP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Macros for minimum-width signed and unsigned curl_off_t integer constants.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
|
|
||||||
# define CURLINC_OFF_T_C_HLPR2(x) x
|
|
||||||
# define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x)
|
|
||||||
# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
|
|
||||||
CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
|
|
||||||
# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
|
|
||||||
CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
|
|
||||||
#else
|
|
||||||
# ifdef CURL_ISOCPP
|
|
||||||
# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
|
|
||||||
# else
|
|
||||||
# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
|
|
||||||
# endif
|
|
||||||
# define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix)
|
|
||||||
# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
|
|
||||||
# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CURLINC_SYSTEM_H */
|
|
|
@ -1,716 +0,0 @@
|
||||||
#ifndef CURLINC_TYPECHECK_GCC_H
|
|
||||||
#define CURLINC_TYPECHECK_GCC_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/* wraps curl_easy_setopt() with typechecking */
|
|
||||||
|
|
||||||
/* To add a new kind of warning, add an
|
|
||||||
* if(curlcheck_sometype_option(_curl_opt))
|
|
||||||
* if(!curlcheck_sometype(value))
|
|
||||||
* _curl_easy_setopt_err_sometype();
|
|
||||||
* block and define curlcheck_sometype_option, curlcheck_sometype and
|
|
||||||
* _curl_easy_setopt_err_sometype below
|
|
||||||
*
|
|
||||||
* NOTE: We use two nested 'if' statements here instead of the && operator, in
|
|
||||||
* order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
|
|
||||||
* when compiling with -Wlogical-op.
|
|
||||||
*
|
|
||||||
* To add an option that uses the same type as an existing option, you'll just
|
|
||||||
* need to extend the appropriate _curl_*_option macro
|
|
||||||
*/
|
|
||||||
#define curl_easy_setopt(handle, option, value) \
|
|
||||||
__extension__({ \
|
|
||||||
CURLoption _curl_opt = (option); \
|
|
||||||
if(__builtin_constant_p(_curl_opt)) { \
|
|
||||||
CURL_IGNORE_DEPRECATION( \
|
|
||||||
if(curlcheck_long_option(_curl_opt)) \
|
|
||||||
if(!curlcheck_long(value)) \
|
|
||||||
_curl_easy_setopt_err_long(); \
|
|
||||||
if(curlcheck_off_t_option(_curl_opt)) \
|
|
||||||
if(!curlcheck_off_t(value)) \
|
|
||||||
_curl_easy_setopt_err_curl_off_t(); \
|
|
||||||
if(curlcheck_string_option(_curl_opt)) \
|
|
||||||
if(!curlcheck_string(value)) \
|
|
||||||
_curl_easy_setopt_err_string(); \
|
|
||||||
if(curlcheck_write_cb_option(_curl_opt)) \
|
|
||||||
if(!curlcheck_write_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_write_callback(); \
|
|
||||||
if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION) \
|
|
||||||
if(!curlcheck_resolver_start_callback(value)) \
|
|
||||||
_curl_easy_setopt_err_resolver_start_callback(); \
|
|
||||||
if((_curl_opt) == CURLOPT_READFUNCTION) \
|
|
||||||
if(!curlcheck_read_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_read_cb(); \
|
|
||||||
if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
|
|
||||||
if(!curlcheck_ioctl_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_ioctl_cb(); \
|
|
||||||
if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
|
|
||||||
if(!curlcheck_sockopt_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_sockopt_cb(); \
|
|
||||||
if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
|
|
||||||
if(!curlcheck_opensocket_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_opensocket_cb(); \
|
|
||||||
if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
|
|
||||||
if(!curlcheck_progress_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_progress_cb(); \
|
|
||||||
if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
|
|
||||||
if(!curlcheck_debug_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_debug_cb(); \
|
|
||||||
if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
|
|
||||||
if(!curlcheck_ssl_ctx_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_ssl_ctx_cb(); \
|
|
||||||
if(curlcheck_conv_cb_option(_curl_opt)) \
|
|
||||||
if(!curlcheck_conv_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_conv_cb(); \
|
|
||||||
if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
|
|
||||||
if(!curlcheck_seek_cb(value)) \
|
|
||||||
_curl_easy_setopt_err_seek_cb(); \
|
|
||||||
if(curlcheck_cb_data_option(_curl_opt)) \
|
|
||||||
if(!curlcheck_cb_data(value)) \
|
|
||||||
_curl_easy_setopt_err_cb_data(); \
|
|
||||||
if((_curl_opt) == CURLOPT_ERRORBUFFER) \
|
|
||||||
if(!curlcheck_error_buffer(value)) \
|
|
||||||
_curl_easy_setopt_err_error_buffer(); \
|
|
||||||
if((_curl_opt) == CURLOPT_STDERR) \
|
|
||||||
if(!curlcheck_FILE(value)) \
|
|
||||||
_curl_easy_setopt_err_FILE(); \
|
|
||||||
if(curlcheck_postfields_option(_curl_opt)) \
|
|
||||||
if(!curlcheck_postfields(value)) \
|
|
||||||
_curl_easy_setopt_err_postfields(); \
|
|
||||||
if((_curl_opt) == CURLOPT_HTTPPOST) \
|
|
||||||
if(!curlcheck_arr((value), struct curl_httppost)) \
|
|
||||||
_curl_easy_setopt_err_curl_httpost(); \
|
|
||||||
if((_curl_opt) == CURLOPT_MIMEPOST) \
|
|
||||||
if(!curlcheck_ptr((value), curl_mime)) \
|
|
||||||
_curl_easy_setopt_err_curl_mimepost(); \
|
|
||||||
if(curlcheck_slist_option(_curl_opt)) \
|
|
||||||
if(!curlcheck_arr((value), struct curl_slist)) \
|
|
||||||
_curl_easy_setopt_err_curl_slist(); \
|
|
||||||
if((_curl_opt) == CURLOPT_SHARE) \
|
|
||||||
if(!curlcheck_ptr((value), CURLSH)) \
|
|
||||||
_curl_easy_setopt_err_CURLSH(); \
|
|
||||||
) \
|
|
||||||
} \
|
|
||||||
curl_easy_setopt(handle, _curl_opt, value); \
|
|
||||||
})
|
|
||||||
|
|
||||||
/* wraps curl_easy_getinfo() with typechecking */
|
|
||||||
#define curl_easy_getinfo(handle, info, arg) \
|
|
||||||
__extension__({ \
|
|
||||||
CURLINFO _curl_info = (info); \
|
|
||||||
if(__builtin_constant_p(_curl_info)) { \
|
|
||||||
CURL_IGNORE_DEPRECATION( \
|
|
||||||
if(curlcheck_string_info(_curl_info)) \
|
|
||||||
if(!curlcheck_arr((arg), char *)) \
|
|
||||||
_curl_easy_getinfo_err_string(); \
|
|
||||||
if(curlcheck_long_info(_curl_info)) \
|
|
||||||
if(!curlcheck_arr((arg), long)) \
|
|
||||||
_curl_easy_getinfo_err_long(); \
|
|
||||||
if(curlcheck_double_info(_curl_info)) \
|
|
||||||
if(!curlcheck_arr((arg), double)) \
|
|
||||||
_curl_easy_getinfo_err_double(); \
|
|
||||||
if(curlcheck_slist_info(_curl_info)) \
|
|
||||||
if(!curlcheck_arr((arg), struct curl_slist *)) \
|
|
||||||
_curl_easy_getinfo_err_curl_slist(); \
|
|
||||||
if(curlcheck_tlssessioninfo_info(_curl_info)) \
|
|
||||||
if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \
|
|
||||||
_curl_easy_getinfo_err_curl_tlssesssioninfo(); \
|
|
||||||
if(curlcheck_certinfo_info(_curl_info)) \
|
|
||||||
if(!curlcheck_arr((arg), struct curl_certinfo *)) \
|
|
||||||
_curl_easy_getinfo_err_curl_certinfo(); \
|
|
||||||
if(curlcheck_socket_info(_curl_info)) \
|
|
||||||
if(!curlcheck_arr((arg), curl_socket_t)) \
|
|
||||||
_curl_easy_getinfo_err_curl_socket(); \
|
|
||||||
if(curlcheck_off_t_info(_curl_info)) \
|
|
||||||
if(!curlcheck_arr((arg), curl_off_t)) \
|
|
||||||
_curl_easy_getinfo_err_curl_off_t(); \
|
|
||||||
) \
|
|
||||||
} \
|
|
||||||
curl_easy_getinfo(handle, _curl_info, arg); \
|
|
||||||
})
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For now, just make sure that the functions are called with three arguments
|
|
||||||
*/
|
|
||||||
#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
|
|
||||||
#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
|
|
||||||
|
|
||||||
|
|
||||||
/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
|
|
||||||
* functions */
|
|
||||||
|
|
||||||
/* To define a new warning, use _CURL_WARNING(identifier, "message") */
|
|
||||||
#define CURLWARNING(id, message) \
|
|
||||||
static void __attribute__((__warning__(message))) \
|
|
||||||
__attribute__((__unused__)) __attribute__((__noinline__)) \
|
|
||||||
id(void) { __asm__(""); }
|
|
||||||
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_long,
|
|
||||||
"curl_easy_setopt expects a long argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_curl_off_t,
|
|
||||||
"curl_easy_setopt expects a curl_off_t argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_string,
|
|
||||||
"curl_easy_setopt expects a "
|
|
||||||
"string ('char *' or char[]) argument for this option"
|
|
||||||
)
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_write_callback,
|
|
||||||
"curl_easy_setopt expects a curl_write_callback argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
|
|
||||||
"curl_easy_setopt expects a "
|
|
||||||
"curl_resolver_start_callback argument for this option"
|
|
||||||
)
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_read_cb,
|
|
||||||
"curl_easy_setopt expects a curl_read_callback argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
|
|
||||||
"curl_easy_setopt expects a curl_ioctl_callback argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
|
|
||||||
"curl_easy_setopt expects a curl_sockopt_callback argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
|
|
||||||
"curl_easy_setopt expects a "
|
|
||||||
"curl_opensocket_callback argument for this option"
|
|
||||||
)
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_progress_cb,
|
|
||||||
"curl_easy_setopt expects a curl_progress_callback argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_debug_cb,
|
|
||||||
"curl_easy_setopt expects a curl_debug_callback argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
|
|
||||||
"curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_conv_cb,
|
|
||||||
"curl_easy_setopt expects a curl_conv_callback argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_seek_cb,
|
|
||||||
"curl_easy_setopt expects a curl_seek_callback argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_cb_data,
|
|
||||||
"curl_easy_setopt expects a "
|
|
||||||
"private data pointer as argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_error_buffer,
|
|
||||||
"curl_easy_setopt expects a "
|
|
||||||
"char buffer of CURL_ERROR_SIZE as argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_FILE,
|
|
||||||
"curl_easy_setopt expects a 'FILE *' argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_postfields,
|
|
||||||
"curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_curl_httpost,
|
|
||||||
"curl_easy_setopt expects a 'struct curl_httppost *' "
|
|
||||||
"argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
|
|
||||||
"curl_easy_setopt expects a 'curl_mime *' "
|
|
||||||
"argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_curl_slist,
|
|
||||||
"curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
|
|
||||||
CURLWARNING(_curl_easy_setopt_err_CURLSH,
|
|
||||||
"curl_easy_setopt expects a CURLSH* argument for this option")
|
|
||||||
|
|
||||||
CURLWARNING(_curl_easy_getinfo_err_string,
|
|
||||||
"curl_easy_getinfo expects a pointer to 'char *' for this info")
|
|
||||||
CURLWARNING(_curl_easy_getinfo_err_long,
|
|
||||||
"curl_easy_getinfo expects a pointer to long for this info")
|
|
||||||
CURLWARNING(_curl_easy_getinfo_err_double,
|
|
||||||
"curl_easy_getinfo expects a pointer to double for this info")
|
|
||||||
CURLWARNING(_curl_easy_getinfo_err_curl_slist,
|
|
||||||
"curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
|
|
||||||
CURLWARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
|
|
||||||
"curl_easy_getinfo expects a pointer to "
|
|
||||||
"'struct curl_tlssessioninfo *' for this info")
|
|
||||||
CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
|
|
||||||
"curl_easy_getinfo expects a pointer to "
|
|
||||||
"'struct curl_certinfo *' for this info")
|
|
||||||
CURLWARNING(_curl_easy_getinfo_err_curl_socket,
|
|
||||||
"curl_easy_getinfo expects a pointer to curl_socket_t for this info")
|
|
||||||
CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
|
|
||||||
"curl_easy_getinfo expects a pointer to curl_off_t for this info")
|
|
||||||
|
|
||||||
/* groups of curl_easy_setops options that take the same type of argument */
|
|
||||||
|
|
||||||
/* To add a new option to one of the groups, just add
|
|
||||||
* (option) == CURLOPT_SOMETHING
|
|
||||||
* to the or-expression. If the option takes a long or curl_off_t, you don't
|
|
||||||
* have to do anything
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* evaluates to true if option takes a long argument */
|
|
||||||
#define curlcheck_long_option(option) \
|
|
||||||
(0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
|
|
||||||
|
|
||||||
#define curlcheck_off_t_option(option) \
|
|
||||||
(((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
|
|
||||||
|
|
||||||
/* evaluates to true if option takes a char* argument */
|
|
||||||
#define curlcheck_string_option(option) \
|
|
||||||
((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
|
|
||||||
(option) == CURLOPT_ACCEPT_ENCODING || \
|
|
||||||
(option) == CURLOPT_ALTSVC || \
|
|
||||||
(option) == CURLOPT_CAINFO || \
|
|
||||||
(option) == CURLOPT_CAPATH || \
|
|
||||||
(option) == CURLOPT_COOKIE || \
|
|
||||||
(option) == CURLOPT_COOKIEFILE || \
|
|
||||||
(option) == CURLOPT_COOKIEJAR || \
|
|
||||||
(option) == CURLOPT_COOKIELIST || \
|
|
||||||
(option) == CURLOPT_CRLFILE || \
|
|
||||||
(option) == CURLOPT_CUSTOMREQUEST || \
|
|
||||||
(option) == CURLOPT_DEFAULT_PROTOCOL || \
|
|
||||||
(option) == CURLOPT_DNS_INTERFACE || \
|
|
||||||
(option) == CURLOPT_DNS_LOCAL_IP4 || \
|
|
||||||
(option) == CURLOPT_DNS_LOCAL_IP6 || \
|
|
||||||
(option) == CURLOPT_DNS_SERVERS || \
|
|
||||||
(option) == CURLOPT_DOH_URL || \
|
|
||||||
(option) == CURLOPT_EGDSOCKET || \
|
|
||||||
(option) == CURLOPT_FTP_ACCOUNT || \
|
|
||||||
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
|
|
||||||
(option) == CURLOPT_FTPPORT || \
|
|
||||||
(option) == CURLOPT_HSTS || \
|
|
||||||
(option) == CURLOPT_INTERFACE || \
|
|
||||||
(option) == CURLOPT_ISSUERCERT || \
|
|
||||||
(option) == CURLOPT_KEYPASSWD || \
|
|
||||||
(option) == CURLOPT_KRBLEVEL || \
|
|
||||||
(option) == CURLOPT_LOGIN_OPTIONS || \
|
|
||||||
(option) == CURLOPT_MAIL_AUTH || \
|
|
||||||
(option) == CURLOPT_MAIL_FROM || \
|
|
||||||
(option) == CURLOPT_NETRC_FILE || \
|
|
||||||
(option) == CURLOPT_NOPROXY || \
|
|
||||||
(option) == CURLOPT_PASSWORD || \
|
|
||||||
(option) == CURLOPT_PINNEDPUBLICKEY || \
|
|
||||||
(option) == CURLOPT_PRE_PROXY || \
|
|
||||||
(option) == CURLOPT_PROTOCOLS_STR || \
|
|
||||||
(option) == CURLOPT_PROXY || \
|
|
||||||
(option) == CURLOPT_PROXY_CAINFO || \
|
|
||||||
(option) == CURLOPT_PROXY_CAPATH || \
|
|
||||||
(option) == CURLOPT_PROXY_CRLFILE || \
|
|
||||||
(option) == CURLOPT_PROXY_ISSUERCERT || \
|
|
||||||
(option) == CURLOPT_PROXY_KEYPASSWD || \
|
|
||||||
(option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \
|
|
||||||
(option) == CURLOPT_PROXY_SERVICE_NAME || \
|
|
||||||
(option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \
|
|
||||||
(option) == CURLOPT_PROXY_SSLCERT || \
|
|
||||||
(option) == CURLOPT_PROXY_SSLCERTTYPE || \
|
|
||||||
(option) == CURLOPT_PROXY_SSLKEY || \
|
|
||||||
(option) == CURLOPT_PROXY_SSLKEYTYPE || \
|
|
||||||
(option) == CURLOPT_PROXY_TLS13_CIPHERS || \
|
|
||||||
(option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \
|
|
||||||
(option) == CURLOPT_PROXY_TLSAUTH_TYPE || \
|
|
||||||
(option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \
|
|
||||||
(option) == CURLOPT_PROXYPASSWORD || \
|
|
||||||
(option) == CURLOPT_PROXYUSERNAME || \
|
|
||||||
(option) == CURLOPT_PROXYUSERPWD || \
|
|
||||||
(option) == CURLOPT_RANDOM_FILE || \
|
|
||||||
(option) == CURLOPT_RANGE || \
|
|
||||||
(option) == CURLOPT_REDIR_PROTOCOLS_STR || \
|
|
||||||
(option) == CURLOPT_REFERER || \
|
|
||||||
(option) == CURLOPT_REQUEST_TARGET || \
|
|
||||||
(option) == CURLOPT_RTSP_SESSION_ID || \
|
|
||||||
(option) == CURLOPT_RTSP_STREAM_URI || \
|
|
||||||
(option) == CURLOPT_RTSP_TRANSPORT || \
|
|
||||||
(option) == CURLOPT_SASL_AUTHZID || \
|
|
||||||
(option) == CURLOPT_SERVICE_NAME || \
|
|
||||||
(option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
|
|
||||||
(option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
|
|
||||||
(option) == CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 || \
|
|
||||||
(option) == CURLOPT_SSH_KNOWNHOSTS || \
|
|
||||||
(option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
|
|
||||||
(option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
|
|
||||||
(option) == CURLOPT_SSLCERT || \
|
|
||||||
(option) == CURLOPT_SSLCERTTYPE || \
|
|
||||||
(option) == CURLOPT_SSLENGINE || \
|
|
||||||
(option) == CURLOPT_SSLKEY || \
|
|
||||||
(option) == CURLOPT_SSLKEYTYPE || \
|
|
||||||
(option) == CURLOPT_SSL_CIPHER_LIST || \
|
|
||||||
(option) == CURLOPT_TLS13_CIPHERS || \
|
|
||||||
(option) == CURLOPT_TLSAUTH_PASSWORD || \
|
|
||||||
(option) == CURLOPT_TLSAUTH_TYPE || \
|
|
||||||
(option) == CURLOPT_TLSAUTH_USERNAME || \
|
|
||||||
(option) == CURLOPT_UNIX_SOCKET_PATH || \
|
|
||||||
(option) == CURLOPT_URL || \
|
|
||||||
(option) == CURLOPT_USERAGENT || \
|
|
||||||
(option) == CURLOPT_USERNAME || \
|
|
||||||
(option) == CURLOPT_AWS_SIGV4 || \
|
|
||||||
(option) == CURLOPT_USERPWD || \
|
|
||||||
(option) == CURLOPT_XOAUTH2_BEARER || \
|
|
||||||
(option) == CURLOPT_SSL_EC_CURVES || \
|
|
||||||
0)
|
|
||||||
|
|
||||||
/* evaluates to true if option takes a curl_write_callback argument */
|
|
||||||
#define curlcheck_write_cb_option(option) \
|
|
||||||
((option) == CURLOPT_HEADERFUNCTION || \
|
|
||||||
(option) == CURLOPT_WRITEFUNCTION)
|
|
||||||
|
|
||||||
/* evaluates to true if option takes a curl_conv_callback argument */
|
|
||||||
#define curlcheck_conv_cb_option(option) \
|
|
||||||
((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
|
|
||||||
(option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
|
|
||||||
(option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
|
|
||||||
|
|
||||||
/* evaluates to true if option takes a data argument to pass to a callback */
|
|
||||||
#define curlcheck_cb_data_option(option) \
|
|
||||||
((option) == CURLOPT_CHUNK_DATA || \
|
|
||||||
(option) == CURLOPT_CLOSESOCKETDATA || \
|
|
||||||
(option) == CURLOPT_DEBUGDATA || \
|
|
||||||
(option) == CURLOPT_FNMATCH_DATA || \
|
|
||||||
(option) == CURLOPT_HEADERDATA || \
|
|
||||||
(option) == CURLOPT_HSTSREADDATA || \
|
|
||||||
(option) == CURLOPT_HSTSWRITEDATA || \
|
|
||||||
(option) == CURLOPT_INTERLEAVEDATA || \
|
|
||||||
(option) == CURLOPT_IOCTLDATA || \
|
|
||||||
(option) == CURLOPT_OPENSOCKETDATA || \
|
|
||||||
(option) == CURLOPT_PREREQDATA || \
|
|
||||||
(option) == CURLOPT_PROGRESSDATA || \
|
|
||||||
(option) == CURLOPT_READDATA || \
|
|
||||||
(option) == CURLOPT_SEEKDATA || \
|
|
||||||
(option) == CURLOPT_SOCKOPTDATA || \
|
|
||||||
(option) == CURLOPT_SSH_KEYDATA || \
|
|
||||||
(option) == CURLOPT_SSL_CTX_DATA || \
|
|
||||||
(option) == CURLOPT_WRITEDATA || \
|
|
||||||
(option) == CURLOPT_RESOLVER_START_DATA || \
|
|
||||||
(option) == CURLOPT_TRAILERDATA || \
|
|
||||||
(option) == CURLOPT_SSH_HOSTKEYDATA || \
|
|
||||||
0)
|
|
||||||
|
|
||||||
/* evaluates to true if option takes a POST data argument (void* or char*) */
|
|
||||||
#define curlcheck_postfields_option(option) \
|
|
||||||
((option) == CURLOPT_POSTFIELDS || \
|
|
||||||
(option) == CURLOPT_COPYPOSTFIELDS || \
|
|
||||||
0)
|
|
||||||
|
|
||||||
/* evaluates to true if option takes a struct curl_slist * argument */
|
|
||||||
#define curlcheck_slist_option(option) \
|
|
||||||
((option) == CURLOPT_HTTP200ALIASES || \
|
|
||||||
(option) == CURLOPT_HTTPHEADER || \
|
|
||||||
(option) == CURLOPT_MAIL_RCPT || \
|
|
||||||
(option) == CURLOPT_POSTQUOTE || \
|
|
||||||
(option) == CURLOPT_PREQUOTE || \
|
|
||||||
(option) == CURLOPT_PROXYHEADER || \
|
|
||||||
(option) == CURLOPT_QUOTE || \
|
|
||||||
(option) == CURLOPT_RESOLVE || \
|
|
||||||
(option) == CURLOPT_TELNETOPTIONS || \
|
|
||||||
(option) == CURLOPT_CONNECT_TO || \
|
|
||||||
0)
|
|
||||||
|
|
||||||
/* groups of curl_easy_getinfo infos that take the same type of argument */
|
|
||||||
|
|
||||||
/* evaluates to true if info expects a pointer to char * argument */
|
|
||||||
#define curlcheck_string_info(info) \
|
|
||||||
(CURLINFO_STRING < (info) && (info) < CURLINFO_LONG && \
|
|
||||||
(info) != CURLINFO_PRIVATE)
|
|
||||||
|
|
||||||
/* evaluates to true if info expects a pointer to long argument */
|
|
||||||
#define curlcheck_long_info(info) \
|
|
||||||
(CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
|
|
||||||
|
|
||||||
/* evaluates to true if info expects a pointer to double argument */
|
|
||||||
#define curlcheck_double_info(info) \
|
|
||||||
(CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
|
|
||||||
|
|
||||||
/* true if info expects a pointer to struct curl_slist * argument */
|
|
||||||
#define curlcheck_slist_info(info) \
|
|
||||||
(((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
|
|
||||||
|
|
||||||
/* true if info expects a pointer to struct curl_tlssessioninfo * argument */
|
|
||||||
#define curlcheck_tlssessioninfo_info(info) \
|
|
||||||
(((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
|
|
||||||
|
|
||||||
/* true if info expects a pointer to struct curl_certinfo * argument */
|
|
||||||
#define curlcheck_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
|
|
||||||
|
|
||||||
/* true if info expects a pointer to struct curl_socket_t argument */
|
|
||||||
#define curlcheck_socket_info(info) \
|
|
||||||
(CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
|
|
||||||
|
|
||||||
/* true if info expects a pointer to curl_off_t argument */
|
|
||||||
#define curlcheck_off_t_info(info) \
|
|
||||||
(CURLINFO_OFF_T < (info))
|
|
||||||
|
|
||||||
|
|
||||||
/* typecheck helpers -- check whether given expression has requested type */
|
|
||||||
|
|
||||||
/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros,
|
|
||||||
* otherwise define a new macro. Search for __builtin_types_compatible_p
|
|
||||||
* in the GCC manual.
|
|
||||||
* NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
|
|
||||||
* the actual expression passed to the curl_easy_setopt macro. This
|
|
||||||
* means that you can only apply the sizeof and __typeof__ operators, no
|
|
||||||
* == or whatsoever.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX: should evaluate to true if expr is a pointer */
|
|
||||||
#define curlcheck_any_ptr(expr) \
|
|
||||||
(sizeof(expr) == sizeof(void *))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is NULL */
|
|
||||||
/* XXX: must not evaluate expr, so this check is not accurate */
|
|
||||||
#define curlcheck_NULL(expr) \
|
|
||||||
(__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is type*, const type* or NULL */
|
|
||||||
#define curlcheck_ptr(expr, type) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), type *) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), const type *))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is one of type[], type*, NULL or const type* */
|
|
||||||
#define curlcheck_arr(expr, type) \
|
|
||||||
(curlcheck_ptr((expr), type) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), type []))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is a string */
|
|
||||||
#define curlcheck_string(expr) \
|
|
||||||
(curlcheck_arr((expr), char) || \
|
|
||||||
curlcheck_arr((expr), signed char) || \
|
|
||||||
curlcheck_arr((expr), unsigned char))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is a long (no matter the signedness)
|
|
||||||
* XXX: for now, int is also accepted (and therefore short and char, which
|
|
||||||
* are promoted to int when passed to a variadic function) */
|
|
||||||
#define curlcheck_long(expr) \
|
|
||||||
(__builtin_types_compatible_p(__typeof__(expr), long) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), signed long) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), int) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), signed int) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), short) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), signed short) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), char) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), signed char) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), unsigned char))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_off_t */
|
|
||||||
#define curlcheck_off_t(expr) \
|
|
||||||
(__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
|
|
||||||
/* XXX: also check size of an char[] array? */
|
|
||||||
#define curlcheck_error_buffer(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), char *) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(expr), char[]))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type (const) void* or (const) FILE* */
|
|
||||||
#if 0
|
|
||||||
#define curlcheck_cb_data(expr) \
|
|
||||||
(curlcheck_ptr((expr), void) || \
|
|
||||||
curlcheck_ptr((expr), FILE))
|
|
||||||
#else /* be less strict */
|
|
||||||
#define curlcheck_cb_data(expr) \
|
|
||||||
curlcheck_any_ptr(expr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type FILE* */
|
|
||||||
#define curlcheck_FILE(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
(__builtin_types_compatible_p(__typeof__(expr), FILE *)))
|
|
||||||
|
|
||||||
/* evaluates to true if expr can be passed as POST data (void* or char*) */
|
|
||||||
#define curlcheck_postfields(expr) \
|
|
||||||
(curlcheck_ptr((expr), void) || \
|
|
||||||
curlcheck_arr((expr), char) || \
|
|
||||||
curlcheck_arr((expr), unsigned char))
|
|
||||||
|
|
||||||
/* helper: __builtin_types_compatible_p distinguishes between functions and
|
|
||||||
* function pointers, hide it */
|
|
||||||
#define curlcheck_cb_compatible(func, type) \
|
|
||||||
(__builtin_types_compatible_p(__typeof__(func), type) || \
|
|
||||||
__builtin_types_compatible_p(__typeof__(func) *, type))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_resolver_start_callback */
|
|
||||||
#define curlcheck_resolver_start_callback(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_resolver_start_callback))
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_read_callback or "similar" */
|
|
||||||
#define curlcheck_read_cb(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), __typeof__(fread) *) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_read_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_read_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_read_callback2) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_read_callback3) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_read_callback4) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_read_callback5) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_read_callback6))
|
|
||||||
typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
|
|
||||||
typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
|
|
||||||
typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
|
|
||||||
typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *);
|
|
||||||
typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
|
|
||||||
typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_write_callback or "similar" */
|
|
||||||
#define curlcheck_write_cb(expr) \
|
|
||||||
(curlcheck_read_cb(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), __typeof__(fwrite) *) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_write_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_write_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_write_callback2) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_write_callback3) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_write_callback4) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_write_callback5) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_write_callback6))
|
|
||||||
typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
|
|
||||||
typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
|
|
||||||
const void *);
|
|
||||||
typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *);
|
|
||||||
typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *);
|
|
||||||
typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
|
|
||||||
const void *);
|
|
||||||
typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
|
|
||||||
#define curlcheck_ioctl_cb(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_ioctl_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback2) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback3) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback4))
|
|
||||||
typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
|
|
||||||
typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
|
|
||||||
typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
|
|
||||||
typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
|
|
||||||
#define curlcheck_sockopt_cb(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_sockopt_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_sockopt_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_sockopt_callback2))
|
|
||||||
typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
|
|
||||||
typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
|
|
||||||
curlsocktype);
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_opensocket_callback or
|
|
||||||
"similar" */
|
|
||||||
#define curlcheck_opensocket_cb(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_opensocket_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback2) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback3) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback4))
|
|
||||||
typedef curl_socket_t (*_curl_opensocket_callback1)
|
|
||||||
(void *, curlsocktype, struct curl_sockaddr *);
|
|
||||||
typedef curl_socket_t (*_curl_opensocket_callback2)
|
|
||||||
(void *, curlsocktype, const struct curl_sockaddr *);
|
|
||||||
typedef curl_socket_t (*_curl_opensocket_callback3)
|
|
||||||
(const void *, curlsocktype, struct curl_sockaddr *);
|
|
||||||
typedef curl_socket_t (*_curl_opensocket_callback4)
|
|
||||||
(const void *, curlsocktype, const struct curl_sockaddr *);
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_progress_callback or "similar" */
|
|
||||||
#define curlcheck_progress_cb(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_progress_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_progress_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_progress_callback2))
|
|
||||||
typedef int (*_curl_progress_callback1)(void *,
|
|
||||||
double, double, double, double);
|
|
||||||
typedef int (*_curl_progress_callback2)(const void *,
|
|
||||||
double, double, double, double);
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_debug_callback or "similar" */
|
|
||||||
#define curlcheck_debug_cb(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_debug_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_debug_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_debug_callback2) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_debug_callback3) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_debug_callback4) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_debug_callback5) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_debug_callback6) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_debug_callback7) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_debug_callback8))
|
|
||||||
typedef int (*_curl_debug_callback1) (CURL *,
|
|
||||||
curl_infotype, char *, size_t, void *);
|
|
||||||
typedef int (*_curl_debug_callback2) (CURL *,
|
|
||||||
curl_infotype, char *, size_t, const void *);
|
|
||||||
typedef int (*_curl_debug_callback3) (CURL *,
|
|
||||||
curl_infotype, const char *, size_t, void *);
|
|
||||||
typedef int (*_curl_debug_callback4) (CURL *,
|
|
||||||
curl_infotype, const char *, size_t, const void *);
|
|
||||||
typedef int (*_curl_debug_callback5) (CURL *,
|
|
||||||
curl_infotype, unsigned char *, size_t, void *);
|
|
||||||
typedef int (*_curl_debug_callback6) (CURL *,
|
|
||||||
curl_infotype, unsigned char *, size_t, const void *);
|
|
||||||
typedef int (*_curl_debug_callback7) (CURL *,
|
|
||||||
curl_infotype, const unsigned char *, size_t, void *);
|
|
||||||
typedef int (*_curl_debug_callback8) (CURL *,
|
|
||||||
curl_infotype, const unsigned char *, size_t, const void *);
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
|
|
||||||
/* this is getting even messier... */
|
|
||||||
#define curlcheck_ssl_ctx_cb(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback8))
|
|
||||||
typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
|
|
||||||
typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
|
|
||||||
typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
|
|
||||||
typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *,
|
|
||||||
const void *);
|
|
||||||
#ifdef HEADER_SSL_H
|
|
||||||
/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
|
|
||||||
* this will of course break if we're included before OpenSSL headers...
|
|
||||||
*/
|
|
||||||
typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX *, void *);
|
|
||||||
typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX *, const void *);
|
|
||||||
typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX *, void *);
|
|
||||||
typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX *,
|
|
||||||
const void *);
|
|
||||||
#else
|
|
||||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
|
|
||||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
|
|
||||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
|
|
||||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_conv_callback or "similar" */
|
|
||||||
#define curlcheck_conv_cb(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_conv_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_conv_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_conv_callback2) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_conv_callback3) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_conv_callback4))
|
|
||||||
typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
|
|
||||||
typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
|
|
||||||
typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
|
|
||||||
typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
|
|
||||||
|
|
||||||
/* evaluates to true if expr is of type curl_seek_callback or "similar" */
|
|
||||||
#define curlcheck_seek_cb(expr) \
|
|
||||||
(curlcheck_NULL(expr) || \
|
|
||||||
curlcheck_cb_compatible((expr), curl_seek_callback) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_seek_callback1) || \
|
|
||||||
curlcheck_cb_compatible((expr), _curl_seek_callback2))
|
|
||||||
typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
|
|
||||||
typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* CURLINC_TYPECHECK_GCC_H */
|
|
|
@ -1,149 +0,0 @@
|
||||||
#ifndef CURLINC_URLAPI_H
|
|
||||||
#define CURLINC_URLAPI_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* the error codes for the URL API */
|
|
||||||
typedef enum {
|
|
||||||
CURLUE_OK,
|
|
||||||
CURLUE_BAD_HANDLE, /* 1 */
|
|
||||||
CURLUE_BAD_PARTPOINTER, /* 2 */
|
|
||||||
CURLUE_MALFORMED_INPUT, /* 3 */
|
|
||||||
CURLUE_BAD_PORT_NUMBER, /* 4 */
|
|
||||||
CURLUE_UNSUPPORTED_SCHEME, /* 5 */
|
|
||||||
CURLUE_URLDECODE, /* 6 */
|
|
||||||
CURLUE_OUT_OF_MEMORY, /* 7 */
|
|
||||||
CURLUE_USER_NOT_ALLOWED, /* 8 */
|
|
||||||
CURLUE_UNKNOWN_PART, /* 9 */
|
|
||||||
CURLUE_NO_SCHEME, /* 10 */
|
|
||||||
CURLUE_NO_USER, /* 11 */
|
|
||||||
CURLUE_NO_PASSWORD, /* 12 */
|
|
||||||
CURLUE_NO_OPTIONS, /* 13 */
|
|
||||||
CURLUE_NO_HOST, /* 14 */
|
|
||||||
CURLUE_NO_PORT, /* 15 */
|
|
||||||
CURLUE_NO_QUERY, /* 16 */
|
|
||||||
CURLUE_NO_FRAGMENT, /* 17 */
|
|
||||||
CURLUE_NO_ZONEID, /* 18 */
|
|
||||||
CURLUE_BAD_FILE_URL, /* 19 */
|
|
||||||
CURLUE_BAD_FRAGMENT, /* 20 */
|
|
||||||
CURLUE_BAD_HOSTNAME, /* 21 */
|
|
||||||
CURLUE_BAD_IPV6, /* 22 */
|
|
||||||
CURLUE_BAD_LOGIN, /* 23 */
|
|
||||||
CURLUE_BAD_PASSWORD, /* 24 */
|
|
||||||
CURLUE_BAD_PATH, /* 25 */
|
|
||||||
CURLUE_BAD_QUERY, /* 26 */
|
|
||||||
CURLUE_BAD_SCHEME, /* 27 */
|
|
||||||
CURLUE_BAD_SLASHES, /* 28 */
|
|
||||||
CURLUE_BAD_USER, /* 29 */
|
|
||||||
CURLUE_LACKS_IDN, /* 30 */
|
|
||||||
CURLUE_LAST
|
|
||||||
} CURLUcode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CURLUPART_URL,
|
|
||||||
CURLUPART_SCHEME,
|
|
||||||
CURLUPART_USER,
|
|
||||||
CURLUPART_PASSWORD,
|
|
||||||
CURLUPART_OPTIONS,
|
|
||||||
CURLUPART_HOST,
|
|
||||||
CURLUPART_PORT,
|
|
||||||
CURLUPART_PATH,
|
|
||||||
CURLUPART_QUERY,
|
|
||||||
CURLUPART_FRAGMENT,
|
|
||||||
CURLUPART_ZONEID /* added in 7.65.0 */
|
|
||||||
} CURLUPart;
|
|
||||||
|
|
||||||
#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
|
|
||||||
#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set,
|
|
||||||
if the port number matches the
|
|
||||||
default for the scheme */
|
|
||||||
#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if
|
|
||||||
missing */
|
|
||||||
#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */
|
|
||||||
#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */
|
|
||||||
#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */
|
|
||||||
#define CURLU_URLDECODE (1<<6) /* URL decode on get */
|
|
||||||
#define CURLU_URLENCODE (1<<7) /* URL encode on set */
|
|
||||||
#define CURLU_APPENDQUERY (1<<8) /* append a form style part */
|
|
||||||
#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
|
|
||||||
#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
|
|
||||||
scheme is unknown. */
|
|
||||||
#define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */
|
|
||||||
#define CURLU_PUNYCODE (1<<12) /* get the host name in pynycode */
|
|
||||||
|
|
||||||
typedef struct Curl_URL CURLU;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* curl_url() creates a new CURLU handle and returns a pointer to it.
|
|
||||||
* Must be freed with curl_url_cleanup().
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLU *curl_url(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* curl_url_cleanup() frees the CURLU handle and related resources used for
|
|
||||||
* the URL parsing. It will not free strings previously returned with the URL
|
|
||||||
* API.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN void curl_url_cleanup(CURLU *handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
|
|
||||||
* handle must also be freed with curl_url_cleanup().
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLU *curl_url_dup(const CURLU *in);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* curl_url_get() extracts a specific part of the URL from a CURLU
|
|
||||||
* handle. Returns error code. The returned pointer MUST be freed with
|
|
||||||
* curl_free() afterwards.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLUcode curl_url_get(const CURLU *handle, CURLUPart what,
|
|
||||||
char **part, unsigned int flags);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
|
|
||||||
* error code. The passed in string will be copied. Passing a NULL instead of
|
|
||||||
* a part string, clears that part.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
|
|
||||||
const char *part, unsigned int flags);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* curl_url_strerror() turns a CURLUcode value into the equivalent human
|
|
||||||
* readable error string. This is useful for printing meaningful error
|
|
||||||
* messages.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN const char *curl_url_strerror(CURLUcode);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* end of extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CURLINC_URLAPI_H */
|
|
|
@ -1,84 +0,0 @@
|
||||||
#ifndef CURLINC_WEBSOCKETS_H
|
|
||||||
#define CURLINC_WEBSOCKETS_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct curl_ws_frame {
|
|
||||||
int age; /* zero */
|
|
||||||
int flags; /* See the CURLWS_* defines */
|
|
||||||
curl_off_t offset; /* the offset of this data into the frame */
|
|
||||||
curl_off_t bytesleft; /* number of pending bytes left of the payload */
|
|
||||||
size_t len; /* size of the current data chunk */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* flag bits */
|
|
||||||
#define CURLWS_TEXT (1<<0)
|
|
||||||
#define CURLWS_BINARY (1<<1)
|
|
||||||
#define CURLWS_CONT (1<<2)
|
|
||||||
#define CURLWS_CLOSE (1<<3)
|
|
||||||
#define CURLWS_PING (1<<4)
|
|
||||||
#define CURLWS_OFFSET (1<<5)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NAME curl_ws_recv()
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* Receives data from the websocket connection. Use after successful
|
|
||||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
|
|
||||||
size_t *recv,
|
|
||||||
struct curl_ws_frame **metap);
|
|
||||||
|
|
||||||
/* sendflags for curl_ws_send() */
|
|
||||||
#define CURLWS_PONG (1<<6)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NAME curl_easy_send()
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* Sends data over the websocket connection. Use after successful
|
|
||||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
|
||||||
*/
|
|
||||||
CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer,
|
|
||||||
size_t buflen, size_t *sent,
|
|
||||||
curl_off_t framesize,
|
|
||||||
unsigned int sendflags);
|
|
||||||
|
|
||||||
/* bits for the CURLOPT_WS_OPTIONS bitmask: */
|
|
||||||
#define CURLWS_RAW_MODE (1<<0)
|
|
||||||
|
|
||||||
CURL_EXTERN struct curl_ws_frame *curl_ws_meta(CURL *curl);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CURLINC_WEBSOCKETS_H */
|
|
|
@ -1,181 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
set(LIB_NAME cmcurl)
|
|
||||||
set(LIBCURL_OUTPUT_NAME cmcurl)
|
|
||||||
add_definitions(-DBUILDING_LIBCURL)
|
|
||||||
|
|
||||||
if(BUILD_SHARED_LIBS)
|
|
||||||
set(CURL_STATICLIB NO)
|
|
||||||
else()
|
|
||||||
set(CURL_STATICLIB YES)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Use:
|
|
||||||
# * CURL_STATICLIB
|
|
||||||
configure_file(curl_config.h.cmake
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
|
|
||||||
|
|
||||||
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
|
|
||||||
include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
|
|
||||||
|
|
||||||
list(APPEND HHEADERS
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WIN32 AND NOT CURL_STATICLIB)
|
|
||||||
list(APPEND CSOURCES libcurl.rc)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# The rest of the build
|
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include)
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
if(USE_ARES)
|
|
||||||
include_directories(${CARES_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# For windows we want to install OPENSSL_LIBRARIES dlls
|
|
||||||
# and also copy them into the build tree so that testing
|
|
||||||
# can find them.
|
|
||||||
if(CURL_USE_OPENSSL AND OPENSSL_FOUND AND WIN32)
|
|
||||||
find_file(CMAKE_EAY_DLL NAME libeay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
|
|
||||||
find_file(CMAKE_SSL_DLL NAME ssleay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
|
|
||||||
mark_as_advanced(CMAKE_EAY_DLL CMAKE_SSL_DLL)
|
|
||||||
if(CMAKE_SSL_DLL AND CMAKE_EAY_DLL)
|
|
||||||
set(CMAKE_CURL_SSL_DLLS ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
|
|
||||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
|
|
||||||
add_custom_command(OUTPUT
|
|
||||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
|
|
||||||
DEPENDS ${CMAKE_EAY_DLL}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_EAY_DLL}
|
|
||||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll)
|
|
||||||
add_custom_command(OUTPUT
|
|
||||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll
|
|
||||||
DEPENDS ${CMAKE_SSL_DLL}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SSL_DLL}
|
|
||||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
|
|
||||||
install(PROGRAMS ${CMAKE_EAY_DLL} ${CMAKE_SSL_DLL} DESTINATION bin)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(
|
|
||||||
${LIB_NAME}
|
|
||||||
${HHEADERS} ${CSOURCES}
|
|
||||||
${CMAKE_CURL_SSL_DLLS}
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(
|
|
||||||
${PROJECT_NAME}::${LIB_NAME}
|
|
||||||
ALIAS ${LIB_NAME}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(NOT BUILD_SHARED_LIBS)
|
|
||||||
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_link_libraries(${LIB_NAME} PRIVATE ${CURL_LIBS})
|
|
||||||
|
|
||||||
if(0) # This code not needed for building within CMake.
|
|
||||||
transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
|
|
||||||
include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(${LIB_NAME} PROPERTIES
|
|
||||||
COMPILE_DEFINITIONS BUILDING_LIBCURL
|
|
||||||
OUTPUT_NAME ${LIBCURL_OUTPUT_NAME}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(0) # This code not needed for building within CMake.
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
|
|
||||||
CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
|
|
||||||
CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
|
|
||||||
CMAKE_SYSTEM_NAME STREQUAL "GNU/kFreeBSD" OR
|
|
||||||
|
|
||||||
# FreeBSD comes with the a.out and elf flavours
|
|
||||||
# but a.out was supported up to version 3.x and
|
|
||||||
# elf from 3.x. I cannot imagine someone running
|
|
||||||
# CMake on those ancient systems
|
|
||||||
CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
|
|
||||||
|
|
||||||
CMAKE_SYSTEM_NAME STREQUAL "Haiku")
|
|
||||||
|
|
||||||
math(EXPR CMAKESONAME "${VERSIONCHANGE} - ${VERSIONDEL}")
|
|
||||||
set(CMAKEVERSION "${CMAKESONAME}.${VERSIONDEL}.${VERSIONADD}")
|
|
||||||
|
|
||||||
set_target_properties(${LIB_NAME} PROPERTIES
|
|
||||||
VERSION ${CMAKEVERSION}
|
|
||||||
SOVERSION ${CMAKESONAME}
|
|
||||||
)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
|
||||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
|
||||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
|
||||||
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
|
|
||||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
|
|
||||||
|
|
||||||
if(CURL_HAS_LTO)
|
|
||||||
set_target_properties(${LIB_NAME} PROPERTIES
|
|
||||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
|
||||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
if(BUILD_SHARED_LIBS)
|
|
||||||
if(MSVC)
|
|
||||||
# Add "_imp" as a suffix before the extension to avoid conflicting with
|
|
||||||
# the statically linked "libcurl.lib"
|
|
||||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(${LIB_NAME} INTERFACE
|
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
|
||||||
$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
|
|
||||||
|
|
||||||
if(CURL_ENABLE_EXPORT_TARGET)
|
|
||||||
install(TARGETS ${LIB_NAME}
|
|
||||||
EXPORT ${TARGETS_EXPORT_NAME}
|
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
export(TARGETS ${LIB_NAME}
|
|
||||||
FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
|
|
||||||
NAMESPACE ${PROJECT_NAME}::
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
endif()
|
|
|
@ -1,361 +0,0 @@
|
||||||
#***************************************************************************
|
|
||||||
# _ _ ____ _
|
|
||||||
# Project ___| | | | _ \| |
|
|
||||||
# / __| | | | |_) | |
|
|
||||||
# | (__| |_| | _ <| |___
|
|
||||||
# \___|\___/|_| \_\_____|
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.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.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: curl
|
|
||||||
#
|
|
||||||
###########################################################################
|
|
||||||
|
|
||||||
LIB_VAUTH_CFILES = \
|
|
||||||
vauth/cleartext.c \
|
|
||||||
vauth/cram.c \
|
|
||||||
vauth/digest.c \
|
|
||||||
vauth/digest_sspi.c \
|
|
||||||
vauth/gsasl.c \
|
|
||||||
vauth/krb5_gssapi.c \
|
|
||||||
vauth/krb5_sspi.c \
|
|
||||||
vauth/ntlm.c \
|
|
||||||
vauth/ntlm_sspi.c \
|
|
||||||
vauth/oauth2.c \
|
|
||||||
vauth/spnego_gssapi.c \
|
|
||||||
vauth/spnego_sspi.c \
|
|
||||||
vauth/vauth.c
|
|
||||||
|
|
||||||
LIB_VAUTH_HFILES = \
|
|
||||||
vauth/digest.h \
|
|
||||||
vauth/ntlm.h \
|
|
||||||
vauth/vauth.h
|
|
||||||
|
|
||||||
LIB_VTLS_CFILES = \
|
|
||||||
vtls/bearssl.c \
|
|
||||||
vtls/gskit.c \
|
|
||||||
vtls/gtls.c \
|
|
||||||
vtls/hostcheck.c \
|
|
||||||
vtls/keylog.c \
|
|
||||||
vtls/mbedtls.c \
|
|
||||||
vtls/mbedtls_threadlock.c \
|
|
||||||
vtls/nss.c \
|
|
||||||
vtls/openssl.c \
|
|
||||||
vtls/rustls.c \
|
|
||||||
vtls/schannel.c \
|
|
||||||
vtls/schannel_verify.c \
|
|
||||||
vtls/sectransp.c \
|
|
||||||
vtls/vtls.c \
|
|
||||||
vtls/wolfssl.c \
|
|
||||||
vtls/x509asn1.c
|
|
||||||
|
|
||||||
LIB_VTLS_HFILES = \
|
|
||||||
vtls/bearssl.h \
|
|
||||||
vtls/gskit.h \
|
|
||||||
vtls/gtls.h \
|
|
||||||
vtls/hostcheck.h \
|
|
||||||
vtls/keylog.h \
|
|
||||||
vtls/mbedtls.h \
|
|
||||||
vtls/mbedtls_threadlock.h \
|
|
||||||
vtls/nssg.h \
|
|
||||||
vtls/openssl.h \
|
|
||||||
vtls/rustls.h \
|
|
||||||
vtls/schannel.h \
|
|
||||||
vtls/sectransp.h \
|
|
||||||
vtls/vtls.h \
|
|
||||||
vtls/vtls_int.h \
|
|
||||||
vtls/wolfssl.h \
|
|
||||||
vtls/x509asn1.h
|
|
||||||
|
|
||||||
LIB_VQUIC_CFILES = \
|
|
||||||
vquic/curl_msh3.c \
|
|
||||||
vquic/curl_ngtcp2.c \
|
|
||||||
vquic/curl_quiche.c \
|
|
||||||
vquic/vquic.c
|
|
||||||
|
|
||||||
LIB_VQUIC_HFILES = \
|
|
||||||
vquic/curl_msh3.h \
|
|
||||||
vquic/curl_ngtcp2.h \
|
|
||||||
vquic/curl_quiche.h \
|
|
||||||
vquic/vquic.h \
|
|
||||||
vquic/vquic_int.h
|
|
||||||
|
|
||||||
LIB_VSSH_CFILES = \
|
|
||||||
vssh/libssh.c \
|
|
||||||
vssh/libssh2.c \
|
|
||||||
vssh/wolfssh.c
|
|
||||||
|
|
||||||
LIB_VSSH_HFILES = \
|
|
||||||
vssh/ssh.h
|
|
||||||
|
|
||||||
LIB_CFILES = \
|
|
||||||
altsvc.c \
|
|
||||||
amigaos.c \
|
|
||||||
asyn-ares.c \
|
|
||||||
asyn-thread.c \
|
|
||||||
base64.c \
|
|
||||||
bufref.c \
|
|
||||||
c-hyper.c \
|
|
||||||
cf-https-connect.c \
|
|
||||||
cf-socket.c \
|
|
||||||
cfilters.c \
|
|
||||||
conncache.c \
|
|
||||||
connect.c \
|
|
||||||
content_encoding.c \
|
|
||||||
cookie.c \
|
|
||||||
curl_addrinfo.c \
|
|
||||||
curl_des.c \
|
|
||||||
curl_endian.c \
|
|
||||||
curl_fnmatch.c \
|
|
||||||
curl_get_line.c \
|
|
||||||
curl_gethostname.c \
|
|
||||||
curl_gssapi.c \
|
|
||||||
curl_log.c \
|
|
||||||
curl_memrchr.c \
|
|
||||||
curl_multibyte.c \
|
|
||||||
curl_ntlm_core.c \
|
|
||||||
curl_ntlm_wb.c \
|
|
||||||
curl_path.c \
|
|
||||||
curl_range.c \
|
|
||||||
curl_rtmp.c \
|
|
||||||
curl_sasl.c \
|
|
||||||
curl_sspi.c \
|
|
||||||
curl_threads.c \
|
|
||||||
dict.c \
|
|
||||||
doh.c \
|
|
||||||
dynbuf.c \
|
|
||||||
easy.c \
|
|
||||||
easygetopt.c \
|
|
||||||
easyoptions.c \
|
|
||||||
escape.c \
|
|
||||||
file.c \
|
|
||||||
fileinfo.c \
|
|
||||||
fopen.c \
|
|
||||||
formdata.c \
|
|
||||||
ftp.c \
|
|
||||||
ftplistparser.c \
|
|
||||||
getenv.c \
|
|
||||||
getinfo.c \
|
|
||||||
gopher.c \
|
|
||||||
h2h3.c \
|
|
||||||
hash.c \
|
|
||||||
headers.c \
|
|
||||||
hmac.c \
|
|
||||||
hostasyn.c \
|
|
||||||
hostip.c \
|
|
||||||
hostip4.c \
|
|
||||||
hostip6.c \
|
|
||||||
hostsyn.c \
|
|
||||||
hsts.c \
|
|
||||||
http.c \
|
|
||||||
http2.c \
|
|
||||||
http_chunks.c \
|
|
||||||
http_digest.c \
|
|
||||||
http_negotiate.c \
|
|
||||||
http_ntlm.c \
|
|
||||||
http_proxy.c \
|
|
||||||
http_aws_sigv4.c \
|
|
||||||
idn.c \
|
|
||||||
if2ip.c \
|
|
||||||
imap.c \
|
|
||||||
inet_ntop.c \
|
|
||||||
inet_pton.c \
|
|
||||||
krb5.c \
|
|
||||||
ldap.c \
|
|
||||||
llist.c \
|
|
||||||
md4.c \
|
|
||||||
md5.c \
|
|
||||||
memdebug.c \
|
|
||||||
mime.c \
|
|
||||||
mprintf.c \
|
|
||||||
mqtt.c \
|
|
||||||
multi.c \
|
|
||||||
netrc.c \
|
|
||||||
nonblock.c \
|
|
||||||
noproxy.c \
|
|
||||||
openldap.c \
|
|
||||||
parsedate.c \
|
|
||||||
pingpong.c \
|
|
||||||
pop3.c \
|
|
||||||
progress.c \
|
|
||||||
psl.c \
|
|
||||||
rand.c \
|
|
||||||
rename.c \
|
|
||||||
rtsp.c \
|
|
||||||
select.c \
|
|
||||||
sendf.c \
|
|
||||||
setopt.c \
|
|
||||||
sha256.c \
|
|
||||||
share.c \
|
|
||||||
slist.c \
|
|
||||||
smb.c \
|
|
||||||
smtp.c \
|
|
||||||
socketpair.c \
|
|
||||||
socks.c \
|
|
||||||
socks_gssapi.c \
|
|
||||||
socks_sspi.c \
|
|
||||||
speedcheck.c \
|
|
||||||
splay.c \
|
|
||||||
strcase.c \
|
|
||||||
strdup.c \
|
|
||||||
strerror.c \
|
|
||||||
strtok.c \
|
|
||||||
strtoofft.c \
|
|
||||||
system_win32.c \
|
|
||||||
telnet.c \
|
|
||||||
tftp.c \
|
|
||||||
timediff.c \
|
|
||||||
timeval.c \
|
|
||||||
transfer.c \
|
|
||||||
url.c \
|
|
||||||
urlapi.c \
|
|
||||||
version.c \
|
|
||||||
version_win32.c \
|
|
||||||
warnless.c \
|
|
||||||
ws.c
|
|
||||||
|
|
||||||
LIB_HFILES = \
|
|
||||||
altsvc.h \
|
|
||||||
amigaos.h \
|
|
||||||
arpa_telnet.h \
|
|
||||||
asyn.h \
|
|
||||||
bufref.h \
|
|
||||||
c-hyper.h \
|
|
||||||
cf-https-connect.h \
|
|
||||||
cf-socket.h \
|
|
||||||
cfilters.h \
|
|
||||||
conncache.h \
|
|
||||||
connect.h \
|
|
||||||
content_encoding.h \
|
|
||||||
cookie.h \
|
|
||||||
curl_addrinfo.h \
|
|
||||||
curl_base64.h \
|
|
||||||
curl_ctype.h \
|
|
||||||
curl_des.h \
|
|
||||||
curl_endian.h \
|
|
||||||
curl_fnmatch.h \
|
|
||||||
curl_get_line.h \
|
|
||||||
curl_gethostname.h \
|
|
||||||
curl_gssapi.h \
|
|
||||||
curl_hmac.h \
|
|
||||||
curl_krb5.h \
|
|
||||||
curl_ldap.h \
|
|
||||||
curl_log.h \
|
|
||||||
curl_md4.h \
|
|
||||||
curl_md5.h \
|
|
||||||
curl_memory.h \
|
|
||||||
curl_memrchr.h \
|
|
||||||
curl_multibyte.h \
|
|
||||||
curl_ntlm_core.h \
|
|
||||||
curl_ntlm_wb.h \
|
|
||||||
curl_path.h \
|
|
||||||
curl_printf.h \
|
|
||||||
curl_range.h \
|
|
||||||
curl_rtmp.h \
|
|
||||||
curl_sasl.h \
|
|
||||||
curl_setup.h \
|
|
||||||
curl_setup_once.h \
|
|
||||||
curl_sha256.h \
|
|
||||||
curl_sspi.h \
|
|
||||||
curl_threads.h \
|
|
||||||
curlx.h \
|
|
||||||
dict.h \
|
|
||||||
doh.h \
|
|
||||||
dynbuf.h \
|
|
||||||
easy_lock.h \
|
|
||||||
easyif.h \
|
|
||||||
easyoptions.h \
|
|
||||||
escape.h \
|
|
||||||
file.h \
|
|
||||||
fileinfo.h \
|
|
||||||
fopen.h \
|
|
||||||
formdata.h \
|
|
||||||
functypes.h \
|
|
||||||
ftp.h \
|
|
||||||
ftplistparser.h \
|
|
||||||
getinfo.h \
|
|
||||||
gopher.h \
|
|
||||||
h2h3.h \
|
|
||||||
hash.h \
|
|
||||||
headers.h \
|
|
||||||
hostip.h \
|
|
||||||
hsts.h \
|
|
||||||
http.h \
|
|
||||||
http2.h \
|
|
||||||
http_chunks.h \
|
|
||||||
http_digest.h \
|
|
||||||
http_negotiate.h \
|
|
||||||
http_ntlm.h \
|
|
||||||
http_proxy.h \
|
|
||||||
http_aws_sigv4.h \
|
|
||||||
idn.h \
|
|
||||||
if2ip.h \
|
|
||||||
imap.h \
|
|
||||||
inet_ntop.h \
|
|
||||||
inet_pton.h \
|
|
||||||
llist.h \
|
|
||||||
memdebug.h \
|
|
||||||
mime.h \
|
|
||||||
mqtt.h \
|
|
||||||
multihandle.h \
|
|
||||||
multiif.h \
|
|
||||||
netrc.h \
|
|
||||||
nonblock.h \
|
|
||||||
noproxy.h \
|
|
||||||
parsedate.h \
|
|
||||||
pingpong.h \
|
|
||||||
pop3.h \
|
|
||||||
progress.h \
|
|
||||||
psl.h \
|
|
||||||
rand.h \
|
|
||||||
rename.h \
|
|
||||||
rtsp.h \
|
|
||||||
select.h \
|
|
||||||
sendf.h \
|
|
||||||
setopt.h \
|
|
||||||
setup-vms.h \
|
|
||||||
share.h \
|
|
||||||
sigpipe.h \
|
|
||||||
slist.h \
|
|
||||||
smb.h \
|
|
||||||
smtp.h \
|
|
||||||
sockaddr.h \
|
|
||||||
socketpair.h \
|
|
||||||
socks.h \
|
|
||||||
speedcheck.h \
|
|
||||||
splay.h \
|
|
||||||
strcase.h \
|
|
||||||
strdup.h \
|
|
||||||
strerror.h \
|
|
||||||
strtok.h \
|
|
||||||
strtoofft.h \
|
|
||||||
system_win32.h \
|
|
||||||
telnet.h \
|
|
||||||
tftp.h \
|
|
||||||
timediff.h \
|
|
||||||
timeval.h \
|
|
||||||
transfer.h \
|
|
||||||
url.h \
|
|
||||||
urlapi-int.h \
|
|
||||||
urldata.h \
|
|
||||||
version_win32.h \
|
|
||||||
warnless.h \
|
|
||||||
ws.h
|
|
||||||
|
|
||||||
LIB_RCFILES = libcurl.rc
|
|
||||||
|
|
||||||
CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \
|
|
||||||
$(LIB_VQUIC_CFILES) $(LIB_VSSH_CFILES)
|
|
||||||
HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) \
|
|
||||||
$(LIB_VQUIC_HFILES) $(LIB_VSSH_HFILES)
|
|
|
@ -1,662 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
/*
|
|
||||||
* The Alt-Svc: header is defined in RFC 7838:
|
|
||||||
* https://datatracker.ietf.org/doc/html/rfc7838
|
|
||||||
*/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include "urldata.h"
|
|
||||||
#include "altsvc.h"
|
|
||||||
#include "curl_get_line.h"
|
|
||||||
#include "strcase.h"
|
|
||||||
#include "parsedate.h"
|
|
||||||
#include "sendf.h"
|
|
||||||
#include "warnless.h"
|
|
||||||
#include "fopen.h"
|
|
||||||
#include "rename.h"
|
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
#define MAX_ALTSVC_LINE 4095
|
|
||||||
#define MAX_ALTSVC_DATELENSTR "64"
|
|
||||||
#define MAX_ALTSVC_DATELEN 64
|
|
||||||
#define MAX_ALTSVC_HOSTLENSTR "512"
|
|
||||||
#define MAX_ALTSVC_HOSTLEN 512
|
|
||||||
#define MAX_ALTSVC_ALPNLENSTR "10"
|
|
||||||
#define MAX_ALTSVC_ALPNLEN 10
|
|
||||||
|
|
||||||
#define H3VERSION "h3"
|
|
||||||
|
|
||||||
static enum alpnid alpn2alpnid(char *name)
|
|
||||||
{
|
|
||||||
if(strcasecompare(name, "h1"))
|
|
||||||
return ALPN_h1;
|
|
||||||
if(strcasecompare(name, "h2"))
|
|
||||||
return ALPN_h2;
|
|
||||||
if(strcasecompare(name, H3VERSION))
|
|
||||||
return ALPN_h3;
|
|
||||||
return ALPN_none; /* unknown, probably rubbish input */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given the ALPN ID, return the name */
|
|
||||||
const char *Curl_alpnid2str(enum alpnid id)
|
|
||||||
{
|
|
||||||
switch(id) {
|
|
||||||
case ALPN_h1:
|
|
||||||
return "h1";
|
|
||||||
case ALPN_h2:
|
|
||||||
return "h2";
|
|
||||||
case ALPN_h3:
|
|
||||||
return H3VERSION;
|
|
||||||
default:
|
|
||||||
return ""; /* bad */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void altsvc_free(struct altsvc *as)
|
|
||||||
{
|
|
||||||
free(as->src.host);
|
|
||||||
free(as->dst.host);
|
|
||||||
free(as);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct altsvc *altsvc_createid(const char *srchost,
|
|
||||||
const char *dsthost,
|
|
||||||
enum alpnid srcalpnid,
|
|
||||||
enum alpnid dstalpnid,
|
|
||||||
unsigned int srcport,
|
|
||||||
unsigned int dstport)
|
|
||||||
{
|
|
||||||
struct altsvc *as = calloc(sizeof(struct altsvc), 1);
|
|
||||||
size_t hlen;
|
|
||||||
if(!as)
|
|
||||||
return NULL;
|
|
||||||
hlen = strlen(srchost);
|
|
||||||
DEBUGASSERT(hlen);
|
|
||||||
as->src.host = strdup(srchost);
|
|
||||||
if(!as->src.host)
|
|
||||||
goto error;
|
|
||||||
if(hlen && (srchost[hlen - 1] == '.'))
|
|
||||||
/* strip off trailing any dot */
|
|
||||||
as->src.host[--hlen] = 0;
|
|
||||||
as->dst.host = strdup(dsthost);
|
|
||||||
if(!as->dst.host)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
as->src.alpnid = srcalpnid;
|
|
||||||
as->dst.alpnid = dstalpnid;
|
|
||||||
as->src.port = curlx_ultous(srcport);
|
|
||||||
as->dst.port = curlx_ultous(dstport);
|
|
||||||
|
|
||||||
return as;
|
|
||||||
error:
|
|
||||||
altsvc_free(as);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct altsvc *altsvc_create(char *srchost,
|
|
||||||
char *dsthost,
|
|
||||||
char *srcalpn,
|
|
||||||
char *dstalpn,
|
|
||||||
unsigned int srcport,
|
|
||||||
unsigned int dstport)
|
|
||||||
{
|
|
||||||
enum alpnid dstalpnid = alpn2alpnid(dstalpn);
|
|
||||||
enum alpnid srcalpnid = alpn2alpnid(srcalpn);
|
|
||||||
if(!srcalpnid || !dstalpnid)
|
|
||||||
return NULL;
|
|
||||||
return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid,
|
|
||||||
srcport, dstport);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* only returns SERIOUS errors */
|
|
||||||
static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
|
|
||||||
{
|
|
||||||
/* Example line:
|
|
||||||
h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1
|
|
||||||
*/
|
|
||||||
char srchost[MAX_ALTSVC_HOSTLEN + 1];
|
|
||||||
char dsthost[MAX_ALTSVC_HOSTLEN + 1];
|
|
||||||
char srcalpn[MAX_ALTSVC_ALPNLEN + 1];
|
|
||||||
char dstalpn[MAX_ALTSVC_ALPNLEN + 1];
|
|
||||||
char date[MAX_ALTSVC_DATELEN + 1];
|
|
||||||
unsigned int srcport;
|
|
||||||
unsigned int dstport;
|
|
||||||
unsigned int prio;
|
|
||||||
unsigned int persist;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = sscanf(line,
|
|
||||||
"%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
|
|
||||||
"%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
|
|
||||||
"\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u",
|
|
||||||
srcalpn, srchost, &srcport,
|
|
||||||
dstalpn, dsthost, &dstport,
|
|
||||||
date, &persist, &prio);
|
|
||||||
if(9 == rc) {
|
|
||||||
struct altsvc *as;
|
|
||||||
time_t expires = Curl_getdate_capped(date);
|
|
||||||
as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
|
|
||||||
if(as) {
|
|
||||||
as->expires = expires;
|
|
||||||
as->prio = prio;
|
|
||||||
as->persist = persist ? 1 : 0;
|
|
||||||
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load alt-svc entries from the given file. The text based line-oriented file
|
|
||||||
* format is documented here: https://curl.se/docs/alt-svc.html
|
|
||||||
*
|
|
||||||
* This function only returns error on major problems that prevent alt-svc
|
|
||||||
* handling to work completely. It will ignore individual syntactical errors
|
|
||||||
* etc.
|
|
||||||
*/
|
|
||||||
static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
|
|
||||||
{
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
char *line = NULL;
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
/* we need a private copy of the file name so that the altsvc cache file
|
|
||||||
name survives an easy handle reset */
|
|
||||||
free(asi->filename);
|
|
||||||
asi->filename = strdup(file);
|
|
||||||
if(!asi->filename)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
fp = fopen(file, FOPEN_READTEXT);
|
|
||||||
if(fp) {
|
|
||||||
line = malloc(MAX_ALTSVC_LINE);
|
|
||||||
if(!line)
|
|
||||||
goto fail;
|
|
||||||
while(Curl_get_line(line, MAX_ALTSVC_LINE, fp)) {
|
|
||||||
char *lineptr = line;
|
|
||||||
while(*lineptr && ISBLANK(*lineptr))
|
|
||||||
lineptr++;
|
|
||||||
if(*lineptr == '#')
|
|
||||||
/* skip commented lines */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
altsvc_add(asi, lineptr);
|
|
||||||
}
|
|
||||||
free(line); /* free the line buffer */
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
Curl_safefree(asi->filename);
|
|
||||||
free(line);
|
|
||||||
fclose(fp);
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write this single altsvc entry to a single output line
|
|
||||||
*/
|
|
||||||
|
|
||||||
static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
|
||||||
{
|
|
||||||
struct tm stamp;
|
|
||||||
CURLcode result = Curl_gmtime(as->expires, &stamp);
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
fprintf(fp,
|
|
||||||
"%s %s %u "
|
|
||||||
"%s %s %u "
|
|
||||||
"\"%d%02d%02d "
|
|
||||||
"%02d:%02d:%02d\" "
|
|
||||||
"%u %d\n",
|
|
||||||
Curl_alpnid2str(as->src.alpnid), as->src.host, as->src.port,
|
|
||||||
Curl_alpnid2str(as->dst.alpnid), as->dst.host, as->dst.port,
|
|
||||||
stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
|
|
||||||
stamp.tm_hour, stamp.tm_min, stamp.tm_sec,
|
|
||||||
as->persist, as->prio);
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- library-wide functions below ---- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_altsvc_init() creates a new altsvc cache.
|
|
||||||
* It returns the new instance or NULL if something goes wrong.
|
|
||||||
*/
|
|
||||||
struct altsvcinfo *Curl_altsvc_init(void)
|
|
||||||
{
|
|
||||||
struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1);
|
|
||||||
if(!asi)
|
|
||||||
return NULL;
|
|
||||||
Curl_llist_init(&asi->list, NULL);
|
|
||||||
|
|
||||||
/* set default behavior */
|
|
||||||
asi->flags = CURLALTSVC_H1
|
|
||||||
#ifdef USE_HTTP2
|
|
||||||
| CURLALTSVC_H2
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_QUIC
|
|
||||||
| CURLALTSVC_H3
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
return asi;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_altsvc_load() loads alt-svc from file.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file)
|
|
||||||
{
|
|
||||||
CURLcode result;
|
|
||||||
DEBUGASSERT(asi);
|
|
||||||
result = altsvc_load(asi, file);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_altsvc_ctrl() passes on the external bitmask.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(asi);
|
|
||||||
if(!ctrl)
|
|
||||||
/* unexpected */
|
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
|
||||||
asi->flags = ctrl;
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_altsvc_cleanup() frees an altsvc cache instance and all associated
|
|
||||||
* resources.
|
|
||||||
*/
|
|
||||||
void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp)
|
|
||||||
{
|
|
||||||
struct Curl_llist_element *e;
|
|
||||||
struct Curl_llist_element *n;
|
|
||||||
if(*altsvcp) {
|
|
||||||
struct altsvcinfo *altsvc = *altsvcp;
|
|
||||||
for(e = altsvc->list.head; e; e = n) {
|
|
||||||
struct altsvc *as = e->ptr;
|
|
||||||
n = e->next;
|
|
||||||
altsvc_free(as);
|
|
||||||
}
|
|
||||||
free(altsvc->filename);
|
|
||||||
free(altsvc);
|
|
||||||
*altsvcp = NULL; /* clear the pointer */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_altsvc_save() writes the altsvc cache to a file.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_altsvc_save(struct Curl_easy *data,
|
|
||||||
struct altsvcinfo *altsvc, const char *file)
|
|
||||||
{
|
|
||||||
struct Curl_llist_element *e;
|
|
||||||
struct Curl_llist_element *n;
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
FILE *out;
|
|
||||||
char *tempstore = NULL;
|
|
||||||
|
|
||||||
if(!altsvc)
|
|
||||||
/* no cache activated */
|
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
/* if not new name is given, use the one we stored from the load */
|
|
||||||
if(!file && altsvc->filename)
|
|
||||||
file = altsvc->filename;
|
|
||||||
|
|
||||||
if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0])
|
|
||||||
/* marked as read-only, no file or zero length file name */
|
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
result = Curl_fopen(data, file, &out, &tempstore);
|
|
||||||
if(!result) {
|
|
||||||
fputs("# Your alt-svc cache. https://curl.se/docs/alt-svc.html\n"
|
|
||||||
"# This file was generated by libcurl! Edit at your own risk.\n",
|
|
||||||
out);
|
|
||||||
for(e = altsvc->list.head; e; e = n) {
|
|
||||||
struct altsvc *as = e->ptr;
|
|
||||||
n = e->next;
|
|
||||||
result = altsvc_out(as, out);
|
|
||||||
if(result)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fclose(out);
|
|
||||||
if(!result && tempstore && Curl_rename(tempstore, file))
|
|
||||||
result = CURLE_WRITE_ERROR;
|
|
||||||
|
|
||||||
if(result && tempstore)
|
|
||||||
unlink(tempstore);
|
|
||||||
}
|
|
||||||
free(tempstore);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
const char *protop;
|
|
||||||
const char *p = *ptr;
|
|
||||||
while(*p && ISBLANK(*p))
|
|
||||||
p++;
|
|
||||||
protop = p;
|
|
||||||
while(*p && !ISBLANK(*p) && (*p != ';') && (*p != '='))
|
|
||||||
p++;
|
|
||||||
len = p - protop;
|
|
||||||
*ptr = p;
|
|
||||||
|
|
||||||
if(!len || (len >= buflen))
|
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
|
||||||
memcpy(alpnbuf, protop, len);
|
|
||||||
alpnbuf[len] = 0;
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hostcompare() returns true if 'host' matches 'check'. The first host
|
|
||||||
* argument may have a trailing dot present that will be ignored.
|
|
||||||
*/
|
|
||||||
static bool hostcompare(const char *host, const char *check)
|
|
||||||
{
|
|
||||||
size_t hlen = strlen(host);
|
|
||||||
size_t clen = strlen(check);
|
|
||||||
|
|
||||||
if(hlen && (host[hlen - 1] == '.'))
|
|
||||||
hlen--;
|
|
||||||
if(hlen != clen)
|
|
||||||
/* they can't match if they have different lengths */
|
|
||||||
return FALSE;
|
|
||||||
return strncasecompare(host, check, hlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* altsvc_flush() removes all alternatives for this source origin from the
|
|
||||||
list */
|
|
||||||
static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
|
|
||||||
const char *srchost, unsigned short srcport)
|
|
||||||
{
|
|
||||||
struct Curl_llist_element *e;
|
|
||||||
struct Curl_llist_element *n;
|
|
||||||
for(e = asi->list.head; e; e = n) {
|
|
||||||
struct altsvc *as = e->ptr;
|
|
||||||
n = e->next;
|
|
||||||
if((srcalpnid == as->src.alpnid) &&
|
|
||||||
(srcport == as->src.port) &&
|
|
||||||
hostcompare(srchost, as->src.host)) {
|
|
||||||
Curl_llist_remove(&asi->list, e, NULL);
|
|
||||||
altsvc_free(as);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
/* to play well with debug builds, we can *set* a fixed time this will
|
|
||||||
return */
|
|
||||||
static time_t debugtime(void *unused)
|
|
||||||
{
|
|
||||||
char *timestr = getenv("CURL_TIME");
|
|
||||||
(void)unused;
|
|
||||||
if(timestr) {
|
|
||||||
unsigned long val = strtol(timestr, NULL, 10);
|
|
||||||
return (time_t)val;
|
|
||||||
}
|
|
||||||
return time(NULL);
|
|
||||||
}
|
|
||||||
#define time(x) debugtime(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_altsvc_parse() takes an incoming alt-svc response header and stores
|
|
||||||
* the data correctly in the cache.
|
|
||||||
*
|
|
||||||
* 'value' points to the header *value*. That's contents to the right of the
|
|
||||||
* header name.
|
|
||||||
*
|
|
||||||
* Currently this function rejects invalid data without returning an error.
|
|
||||||
* Invalid host name, port number will result in the specific alternative
|
|
||||||
* being rejected. Unknown protocols are skipped.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
|
||||||
struct altsvcinfo *asi, const char *value,
|
|
||||||
enum alpnid srcalpnid, const char *srchost,
|
|
||||||
unsigned short srcport)
|
|
||||||
{
|
|
||||||
const char *p = value;
|
|
||||||
size_t len;
|
|
||||||
char namebuf[MAX_ALTSVC_HOSTLEN] = "";
|
|
||||||
char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
|
|
||||||
struct altsvc *as;
|
|
||||||
unsigned short dstport = srcport; /* the same by default */
|
|
||||||
CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
|
|
||||||
size_t entries = 0;
|
|
||||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
|
||||||
(void)data;
|
|
||||||
#endif
|
|
||||||
if(result) {
|
|
||||||
infof(data, "Excessive alt-svc header, ignoring.");
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGASSERT(asi);
|
|
||||||
|
|
||||||
/* "clear" is a magic keyword */
|
|
||||||
if(strcasecompare(alpnbuf, "clear")) {
|
|
||||||
/* Flush cached alternatives for this source origin */
|
|
||||||
altsvc_flush(asi, srcalpnid, srchost, srcport);
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if(*p == '=') {
|
|
||||||
/* [protocol]="[host][:port]" */
|
|
||||||
enum alpnid dstalpnid = alpn2alpnid(alpnbuf); /* the same by default */
|
|
||||||
p++;
|
|
||||||
if(*p == '\"') {
|
|
||||||
const char *dsthost = "";
|
|
||||||
const char *value_ptr;
|
|
||||||
char option[32];
|
|
||||||
unsigned long num;
|
|
||||||
char *end_ptr;
|
|
||||||
bool quoted = FALSE;
|
|
||||||
time_t maxage = 24 * 3600; /* default is 24 hours */
|
|
||||||
bool persist = FALSE;
|
|
||||||
bool valid = TRUE;
|
|
||||||
p++;
|
|
||||||
if(*p != ':') {
|
|
||||||
/* host name starts here */
|
|
||||||
const char *hostp = p;
|
|
||||||
while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
|
|
||||||
p++;
|
|
||||||
len = p - hostp;
|
|
||||||
if(!len || (len >= MAX_ALTSVC_HOSTLEN)) {
|
|
||||||
infof(data, "Excessive alt-svc host name, ignoring.");
|
|
||||||
valid = FALSE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
memcpy(namebuf, hostp, len);
|
|
||||||
namebuf[len] = 0;
|
|
||||||
dsthost = namebuf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* no destination name, use source host */
|
|
||||||
dsthost = srchost;
|
|
||||||
}
|
|
||||||
if(*p == ':') {
|
|
||||||
unsigned long port = 0;
|
|
||||||
p++;
|
|
||||||
if(ISDIGIT(*p))
|
|
||||||
/* a port number */
|
|
||||||
port = strtoul(p, &end_ptr, 10);
|
|
||||||
else
|
|
||||||
end_ptr = (char *)p; /* not left uninitialized */
|
|
||||||
if(!port || port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
|
|
||||||
infof(data, "Unknown alt-svc port number, ignoring.");
|
|
||||||
valid = FALSE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dstport = curlx_ultous(port);
|
|
||||||
p = end_ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(*p++ != '\"')
|
|
||||||
break;
|
|
||||||
/* Handle the optional 'ma' and 'persist' flags. Unknown flags
|
|
||||||
are skipped. */
|
|
||||||
for(;;) {
|
|
||||||
while(ISBLANK(*p))
|
|
||||||
p++;
|
|
||||||
if(*p != ';')
|
|
||||||
break;
|
|
||||||
p++; /* pass the semicolon */
|
|
||||||
if(!*p || ISNEWLINE(*p))
|
|
||||||
break;
|
|
||||||
result = getalnum(&p, option, sizeof(option));
|
|
||||||
if(result) {
|
|
||||||
/* skip option if name is too long */
|
|
||||||
option[0] = '\0';
|
|
||||||
}
|
|
||||||
while(*p && ISBLANK(*p))
|
|
||||||
p++;
|
|
||||||
if(*p != '=')
|
|
||||||
return CURLE_OK;
|
|
||||||
p++;
|
|
||||||
while(*p && ISBLANK(*p))
|
|
||||||
p++;
|
|
||||||
if(!*p)
|
|
||||||
return CURLE_OK;
|
|
||||||
if(*p == '\"') {
|
|
||||||
/* quoted value */
|
|
||||||
p++;
|
|
||||||
quoted = TRUE;
|
|
||||||
}
|
|
||||||
value_ptr = p;
|
|
||||||
if(quoted) {
|
|
||||||
while(*p && *p != '\"')
|
|
||||||
p++;
|
|
||||||
if(!*p++)
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
while(*p && !ISBLANK(*p) && *p!= ';' && *p != ',')
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
num = strtoul(value_ptr, &end_ptr, 10);
|
|
||||||
if((end_ptr != value_ptr) && (num < ULONG_MAX)) {
|
|
||||||
if(strcasecompare("ma", option))
|
|
||||||
maxage = num;
|
|
||||||
else if(strcasecompare("persist", option) && (num == 1))
|
|
||||||
persist = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(dstalpnid && valid) {
|
|
||||||
if(!entries++)
|
|
||||||
/* Flush cached alternatives for this source origin, if any - when
|
|
||||||
this is the first entry of the line. */
|
|
||||||
altsvc_flush(asi, srcalpnid, srchost, srcport);
|
|
||||||
|
|
||||||
as = altsvc_createid(srchost, dsthost,
|
|
||||||
srcalpnid, dstalpnid,
|
|
||||||
srcport, dstport);
|
|
||||||
if(as) {
|
|
||||||
/* The expires time also needs to take the Age: value (if any) into
|
|
||||||
account. [See RFC 7838 section 3.1] */
|
|
||||||
as->expires = maxage + time(NULL);
|
|
||||||
as->persist = persist;
|
|
||||||
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
|
|
||||||
infof(data, "Added alt-svc: %s:%d over %s", dsthost, dstport,
|
|
||||||
Curl_alpnid2str(dstalpnid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
/* after the double quote there can be a comma if there's another
|
|
||||||
string or a semicolon if no more */
|
|
||||||
if(*p == ',') {
|
|
||||||
/* comma means another alternative is presented */
|
|
||||||
p++;
|
|
||||||
result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
|
|
||||||
if(result)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
} while(*p && (*p != ';') && (*p != '\n') && (*p != '\r'));
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return TRUE on a match
|
|
||||||
*/
|
|
||||||
bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
|
||||||
enum alpnid srcalpnid, const char *srchost,
|
|
||||||
int srcport,
|
|
||||||
struct altsvc **dstentry,
|
|
||||||
const int versions) /* one or more bits */
|
|
||||||
{
|
|
||||||
struct Curl_llist_element *e;
|
|
||||||
struct Curl_llist_element *n;
|
|
||||||
time_t now = time(NULL);
|
|
||||||
DEBUGASSERT(asi);
|
|
||||||
DEBUGASSERT(srchost);
|
|
||||||
DEBUGASSERT(dstentry);
|
|
||||||
|
|
||||||
for(e = asi->list.head; e; e = n) {
|
|
||||||
struct altsvc *as = e->ptr;
|
|
||||||
n = e->next;
|
|
||||||
if(as->expires < now) {
|
|
||||||
/* an expired entry, remove */
|
|
||||||
Curl_llist_remove(&asi->list, e, NULL);
|
|
||||||
altsvc_free(as);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if((as->src.alpnid == srcalpnid) &&
|
|
||||||
hostcompare(srchost, as->src.host) &&
|
|
||||||
(as->src.port == srcport) &&
|
|
||||||
(versions & as->dst.alpnid)) {
|
|
||||||
/* match */
|
|
||||||
*dstentry = as;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
|
|
|
@ -1,81 +0,0 @@
|
||||||
#ifndef HEADER_CURL_ALTSVC_H
|
|
||||||
#define HEADER_CURL_ALTSVC_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include "llist.h"
|
|
||||||
|
|
||||||
enum alpnid {
|
|
||||||
ALPN_none = 0,
|
|
||||||
ALPN_h1 = CURLALTSVC_H1,
|
|
||||||
ALPN_h2 = CURLALTSVC_H2,
|
|
||||||
ALPN_h3 = CURLALTSVC_H3
|
|
||||||
};
|
|
||||||
|
|
||||||
struct althost {
|
|
||||||
char *host;
|
|
||||||
unsigned short port;
|
|
||||||
enum alpnid alpnid;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct altsvc {
|
|
||||||
struct althost src;
|
|
||||||
struct althost dst;
|
|
||||||
time_t expires;
|
|
||||||
bool persist;
|
|
||||||
int prio;
|
|
||||||
struct Curl_llist_element node;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct altsvcinfo {
|
|
||||||
char *filename;
|
|
||||||
struct Curl_llist list; /* list of entries */
|
|
||||||
long flags; /* the publicly set bitmask */
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *Curl_alpnid2str(enum alpnid id);
|
|
||||||
struct altsvcinfo *Curl_altsvc_init(void);
|
|
||||||
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
|
|
||||||
CURLcode Curl_altsvc_save(struct Curl_easy *data,
|
|
||||||
struct altsvcinfo *asi, const char *file);
|
|
||||||
CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
|
|
||||||
void Curl_altsvc_cleanup(struct altsvcinfo **altsvc);
|
|
||||||
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
|
||||||
struct altsvcinfo *altsvc, const char *value,
|
|
||||||
enum alpnid srcalpn, const char *srchost,
|
|
||||||
unsigned short srcport);
|
|
||||||
bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
|
||||||
enum alpnid srcalpnid, const char *srchost,
|
|
||||||
int srcport,
|
|
||||||
struct altsvc **dstentry,
|
|
||||||
const int versions); /* CURLALTSVC_H* bits */
|
|
||||||
#else
|
|
||||||
/* disabled */
|
|
||||||
#define Curl_altsvc_save(a,b,c)
|
|
||||||
#define Curl_altsvc_cleanup(x)
|
|
||||||
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
|
|
||||||
#endif /* HEADER_CURL_ALTSVC_H */
|
|
|
@ -1,246 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#ifdef __AMIGA__
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
#include "hostip.h"
|
|
||||||
#include "amigaos.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_PROTO_BSDSOCKET_H
|
|
||||||
# if defined(__amigaos4__)
|
|
||||||
# include <bsdsocket/socketbasetags.h>
|
|
||||||
# elif !defined(USE_AMISSL)
|
|
||||||
# include <amitcp/socketbasetags.h>
|
|
||||||
# endif
|
|
||||||
# ifdef __libnix__
|
|
||||||
# include <stabs.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The last #include files should be: */
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_PROTO_BSDSOCKET_H
|
|
||||||
|
|
||||||
#ifdef __amigaos4__
|
|
||||||
/*
|
|
||||||
* AmigaOS 4.x specific code
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hostip4.c - Curl_ipv4_resolve_r() replacement code
|
|
||||||
*
|
|
||||||
* Logic that needs to be considered are the following build cases:
|
|
||||||
* - newlib networking
|
|
||||||
* - clib2 networking
|
|
||||||
* - direct bsdsocket.library networking (usually AmiSSL builds)
|
|
||||||
* Each with the threaded resolver enabled or not.
|
|
||||||
*
|
|
||||||
* With the threaded resolver enabled, try to use gethostbyname_r() where
|
|
||||||
* available, otherwise (re)open bsdsocket.library and fallback to
|
|
||||||
* gethostbyname().
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <proto/bsdsocket.h>
|
|
||||||
|
|
||||||
static struct SocketIFace *__CurlISocket = NULL;
|
|
||||||
static uint32 SocketFeatures = 0;
|
|
||||||
|
|
||||||
#define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01
|
|
||||||
#define HAVE_BSDSOCKET_GETADDRINFO 0x02
|
|
||||||
|
|
||||||
CURLcode Curl_amiga_init(void)
|
|
||||||
{
|
|
||||||
struct SocketIFace *ISocket;
|
|
||||||
struct Library *base = OpenLibrary("bsdsocket.library", 4);
|
|
||||||
|
|
||||||
if(base) {
|
|
||||||
ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
|
|
||||||
if(ISocket) {
|
|
||||||
ULONG enabled = 0;
|
|
||||||
|
|
||||||
SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE,
|
|
||||||
SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled,
|
|
||||||
TAG_DONE);
|
|
||||||
|
|
||||||
if(enabled) {
|
|
||||||
SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R;
|
|
||||||
}
|
|
||||||
|
|
||||||
__CurlISocket = ISocket;
|
|
||||||
|
|
||||||
atexit(Curl_amiga_cleanup);
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
CloseLibrary(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_amiga_cleanup(void)
|
|
||||||
{
|
|
||||||
if(__CurlISocket) {
|
|
||||||
struct Library *base = __CurlISocket->Data.LibBase;
|
|
||||||
DropInterface((struct Interface *)__CurlISocket);
|
|
||||||
CloseLibrary(base);
|
|
||||||
__CurlISocket = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CURLRES_AMIGA
|
|
||||||
/*
|
|
||||||
* Because we need to handle the different cases in hostip4.c at run-time,
|
|
||||||
* not at compile-time, based on what was detected in Curl_amiga_init(),
|
|
||||||
* we replace it completely with our own as to not complicate the baseline
|
|
||||||
* code. Assumes malloc/calloc/free are thread safe because Curl_he2ai()
|
|
||||||
* allocates memory also.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
|
||||||
int port)
|
|
||||||
{
|
|
||||||
struct Curl_addrinfo *ai = NULL;
|
|
||||||
struct hostent *h;
|
|
||||||
struct SocketIFace *ISocket = __CurlISocket;
|
|
||||||
|
|
||||||
if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) {
|
|
||||||
LONG h_errnop = 0;
|
|
||||||
struct hostent *buf;
|
|
||||||
|
|
||||||
buf = calloc(1, CURL_HOSTENT_SIZE);
|
|
||||||
if(buf) {
|
|
||||||
h = gethostbyname_r((STRPTR)hostname, buf,
|
|
||||||
(char *)buf + sizeof(struct hostent),
|
|
||||||
CURL_HOSTENT_SIZE - sizeof(struct hostent),
|
|
||||||
&h_errnop);
|
|
||||||
if(h) {
|
|
||||||
ai = Curl_he2ai(h, port);
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#ifdef CURLRES_THREADED
|
|
||||||
/* gethostbyname() is not thread safe, so we need to reopen bsdsocket
|
|
||||||
* on the thread's context
|
|
||||||
*/
|
|
||||||
struct Library *base = OpenLibrary("bsdsocket.library", 4);
|
|
||||||
if(base) {
|
|
||||||
ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
|
|
||||||
if(ISocket) {
|
|
||||||
h = gethostbyname((STRPTR)hostname);
|
|
||||||
if(h) {
|
|
||||||
ai = Curl_he2ai(h, port);
|
|
||||||
}
|
|
||||||
DropInterface((struct Interface *)ISocket);
|
|
||||||
}
|
|
||||||
CloseLibrary(base);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* not using threaded resolver - safe to use this as-is */
|
|
||||||
h = gethostbyname(hostname);
|
|
||||||
if(h) {
|
|
||||||
ai = Curl_he2ai(h, port);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return ai;
|
|
||||||
}
|
|
||||||
#endif /* CURLRES_AMIGA */
|
|
||||||
|
|
||||||
#ifdef USE_AMISSL
|
|
||||||
int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
|
|
||||||
fd_set *errorfds, struct timeval *timeout)
|
|
||||||
{
|
|
||||||
int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0);
|
|
||||||
/* Ensure Ctrl-C signal is actioned */
|
|
||||||
if((r == -1) && (SOCKERRNO == EINTR))
|
|
||||||
raise(SIGINT);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
#endif /* USE_AMISSL */
|
|
||||||
|
|
||||||
#elif !defined(USE_AMISSL) /* __amigaos4__ */
|
|
||||||
/*
|
|
||||||
* Amiga OS3 specific code
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Library *SocketBase = NULL;
|
|
||||||
extern int errno, h_errno;
|
|
||||||
|
|
||||||
#ifdef __libnix__
|
|
||||||
void __request(const char *msg);
|
|
||||||
#else
|
|
||||||
# define __request(msg) Printf(msg "\n\a")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Curl_amiga_cleanup(void)
|
|
||||||
{
|
|
||||||
if(SocketBase) {
|
|
||||||
CloseLibrary(SocketBase);
|
|
||||||
SocketBase = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_amiga_init(void)
|
|
||||||
{
|
|
||||||
if(!SocketBase)
|
|
||||||
SocketBase = OpenLibrary("bsdsocket.library", 4);
|
|
||||||
|
|
||||||
if(!SocketBase) {
|
|
||||||
__request("No TCP/IP Stack running!");
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
|
|
||||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
|
|
||||||
TAG_DONE)) {
|
|
||||||
__request("SocketBaseTags ERROR");
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef __libnix__
|
|
||||||
atexit(Curl_amiga_cleanup);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __libnix__
|
|
||||||
ADD2EXIT(Curl_amiga_cleanup, -50);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !USE_AMISSL */
|
|
||||||
|
|
||||||
#endif /* HAVE_PROTO_BSDSOCKET_H */
|
|
||||||
|
|
||||||
#endif /* __AMIGA__ */
|
|
|
@ -1,42 +0,0 @@
|
||||||
#ifndef HEADER_CURL_AMIGAOS_H
|
|
||||||
#define HEADER_CURL_AMIGAOS_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if defined(__AMIGA__) && defined(HAVE_PROTO_BSDSOCKET_H) && \
|
|
||||||
(!defined(USE_AMISSL) || defined(__amigaos4__))
|
|
||||||
|
|
||||||
CURLcode Curl_amiga_init(void);
|
|
||||||
void Curl_amiga_cleanup(void);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define Curl_amiga_init() CURLE_OK
|
|
||||||
#define Curl_amiga_cleanup() Curl_nop_stmt
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_AMIGAOS_H */
|
|
||||||
|
|
|
@ -1,110 +0,0 @@
|
||||||
#ifndef HEADER_CURL_ARPA_TELNET_H
|
|
||||||
#define HEADER_CURL_ARPA_TELNET_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef CURL_DISABLE_TELNET
|
|
||||||
/*
|
|
||||||
* Telnet option defines. Add more here if in need.
|
|
||||||
*/
|
|
||||||
#define CURL_TELOPT_BINARY 0 /* binary 8bit data */
|
|
||||||
#define CURL_TELOPT_ECHO 1 /* just echo! */
|
|
||||||
#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */
|
|
||||||
#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */
|
|
||||||
#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */
|
|
||||||
#define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */
|
|
||||||
#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
|
|
||||||
|
|
||||||
#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */
|
|
||||||
#define CURL_NEW_ENV_VAR 0
|
|
||||||
#define CURL_NEW_ENV_VALUE 1
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
|
||||||
/*
|
|
||||||
* The telnet options represented as strings
|
|
||||||
*/
|
|
||||||
static const char * const telnetoptions[]=
|
|
||||||
{
|
|
||||||
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD",
|
|
||||||
"NAME", "STATUS", "TIMING MARK", "RCTE",
|
|
||||||
"NAOL", "NAOP", "NAOCRD", "NAOHTS",
|
|
||||||
"NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD",
|
|
||||||
"NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
|
|
||||||
"DE TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION",
|
|
||||||
"TERM TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING",
|
|
||||||
"TTYLOC", "3270 REGIME", "X3 PAD", "NAWS",
|
|
||||||
"TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC",
|
|
||||||
"OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON"
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON
|
|
||||||
|
|
||||||
#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM)
|
|
||||||
#define CURL_TELOPT(x) telnetoptions[x]
|
|
||||||
|
|
||||||
#define CURL_NTELOPTS 40
|
|
||||||
|
|
||||||
/*
|
|
||||||
* First some defines
|
|
||||||
*/
|
|
||||||
#define CURL_xEOF 236 /* End Of File */
|
|
||||||
#define CURL_SE 240 /* Sub negotiation End */
|
|
||||||
#define CURL_NOP 241 /* No OPeration */
|
|
||||||
#define CURL_DM 242 /* Data Mark */
|
|
||||||
#define CURL_GA 249 /* Go Ahead, reverse the line */
|
|
||||||
#define CURL_SB 250 /* SuBnegotiation */
|
|
||||||
#define CURL_WILL 251 /* Our side WILL use this option */
|
|
||||||
#define CURL_WONT 252 /* Our side WON'T use this option */
|
|
||||||
#define CURL_DO 253 /* DO use this option! */
|
|
||||||
#define CURL_DONT 254 /* DON'T use this option! */
|
|
||||||
#define CURL_IAC 255 /* Interpret As Command */
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
|
||||||
/*
|
|
||||||
* Then those numbers represented as strings:
|
|
||||||
*/
|
|
||||||
static const char * const telnetcmds[]=
|
|
||||||
{
|
|
||||||
"EOF", "SUSP", "ABORT", "EOR", "SE",
|
|
||||||
"NOP", "DMARK", "BRK", "IP", "AO",
|
|
||||||
"AYT", "EC", "EL", "GA", "SB",
|
|
||||||
"WILL", "WONT", "DO", "DONT", "IAC"
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */
|
|
||||||
#define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */
|
|
||||||
|
|
||||||
#define CURL_TELQUAL_IS 0
|
|
||||||
#define CURL_TELQUAL_SEND 1
|
|
||||||
#define CURL_TELQUAL_INFO 2
|
|
||||||
#define CURL_TELQUAL_NAME 3
|
|
||||||
|
|
||||||
#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
|
|
||||||
((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) )
|
|
||||||
#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM]
|
|
||||||
|
|
||||||
#endif /* CURL_DISABLE_TELNET */
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_ARPA_TELNET_H */
|
|
|
@ -1,929 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* Only for ares-enabled builds
|
|
||||||
* And only for functions that fulfill the asynch resolver backend API
|
|
||||||
* as defined in asyn.h, nothing else belongs in this file!
|
|
||||||
**********************************************************************/
|
|
||||||
|
|
||||||
#ifdef CURLRES_ARES
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETDB_H
|
|
||||||
#include <netdb.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
#ifdef __VMS
|
|
||||||
#include <in.h>
|
|
||||||
#include <inet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "urldata.h"
|
|
||||||
#include "sendf.h"
|
|
||||||
#include "hostip.h"
|
|
||||||
#include "hash.h"
|
|
||||||
#include "share.h"
|
|
||||||
#include "url.h"
|
|
||||||
#include "multiif.h"
|
|
||||||
#include "inet_pton.h"
|
|
||||||
#include "connect.h"
|
|
||||||
#include "select.h"
|
|
||||||
#include "progress.h"
|
|
||||||
#include "timediff.h"
|
|
||||||
|
|
||||||
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
|
|
||||||
defined(WIN32)
|
|
||||||
# define CARES_STATICLIB
|
|
||||||
# endif
|
|
||||||
# include <ares.h>
|
|
||||||
# include <ares_version.h> /* really old c-ares didn't include this by
|
|
||||||
itself */
|
|
||||||
|
|
||||||
#if ARES_VERSION >= 0x010500
|
|
||||||
/* c-ares 1.5.0 or later, the callback proto is modified */
|
|
||||||
#define HAVE_CARES_CALLBACK_TIMEOUTS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ARES_VERSION >= 0x010601
|
|
||||||
/* IPv6 supported since 1.6.1 */
|
|
||||||
#define HAVE_CARES_IPV6 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ARES_VERSION >= 0x010704
|
|
||||||
#define HAVE_CARES_SERVERS_CSV 1
|
|
||||||
#define HAVE_CARES_LOCAL_DEV 1
|
|
||||||
#define HAVE_CARES_SET_LOCAL 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ARES_VERSION >= 0x010b00
|
|
||||||
#define HAVE_CARES_PORTS_CSV 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ARES_VERSION >= 0x011000
|
|
||||||
/* 1.16.0 or later has ares_getaddrinfo */
|
|
||||||
#define HAVE_CARES_GETADDRINFO 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
struct thread_data {
|
|
||||||
int num_pending; /* number of outstanding c-ares requests */
|
|
||||||
struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
|
|
||||||
parts */
|
|
||||||
int last_status;
|
|
||||||
#ifndef HAVE_CARES_GETADDRINFO
|
|
||||||
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
|
|
||||||
#endif
|
|
||||||
char hostname[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* How long we are willing to wait for additional parallel responses after
|
|
||||||
obtaining a "definitive" one.
|
|
||||||
|
|
||||||
This is intended to equal the c-ares default timeout. cURL always uses that
|
|
||||||
default value. Unfortunately, c-ares doesn't expose its default timeout in
|
|
||||||
its API, but it is officially documented as 5 seconds.
|
|
||||||
|
|
||||||
See query_completed_cb() for an explanation of how this is used.
|
|
||||||
*/
|
|
||||||
#define HAPPY_EYEBALLS_DNS_TIMEOUT 5000
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_global_init() - the generic low-level asynchronous name
|
|
||||||
* resolve API. Called from curl_global_init() to initialize global resolver
|
|
||||||
* environment. Initializes ares library.
|
|
||||||
*/
|
|
||||||
int Curl_resolver_global_init(void)
|
|
||||||
{
|
|
||||||
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
|
|
||||||
if(ares_library_init(ARES_LIB_INIT_ALL)) {
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_global_cleanup()
|
|
||||||
*
|
|
||||||
* Called from curl_global_cleanup() to destroy global resolver environment.
|
|
||||||
* Deinitializes ares library.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_global_cleanup(void)
|
|
||||||
{
|
|
||||||
#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
|
|
||||||
ares_library_cleanup();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void sock_state_cb(void *data, ares_socket_t socket_fd,
|
|
||||||
int readable, int writable)
|
|
||||||
{
|
|
||||||
struct Curl_easy *easy = data;
|
|
||||||
if(!readable && !writable) {
|
|
||||||
DEBUGASSERT(easy);
|
|
||||||
Curl_multi_closed(easy, socket_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_init()
|
|
||||||
*
|
|
||||||
* Called from curl_easy_init() -> Curl_open() to initialize resolver
|
|
||||||
* URL-state specific environment ('resolver' member of the UrlState
|
|
||||||
* structure). Fills the passed pointer by the initialized ares_channel.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
struct ares_options options;
|
|
||||||
int optmask = ARES_OPT_SOCK_STATE_CB;
|
|
||||||
options.sock_state_cb = sock_state_cb;
|
|
||||||
options.sock_state_cb_data = easy;
|
|
||||||
status = ares_init_options((ares_channel*)resolver, &options, optmask);
|
|
||||||
if(status != ARES_SUCCESS) {
|
|
||||||
if(status == ARES_ENOMEM)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
else
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
return CURLE_OK;
|
|
||||||
/* make sure that all other returns from this function should destroy the
|
|
||||||
ares channel before returning error! */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_cleanup()
|
|
||||||
*
|
|
||||||
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
|
|
||||||
* URL-state specific environment ('resolver' member of the UrlState
|
|
||||||
* structure). Destroys the ares channel.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_cleanup(void *resolver)
|
|
||||||
{
|
|
||||||
ares_destroy((ares_channel)resolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_duphandle()
|
|
||||||
*
|
|
||||||
* Called from curl_easy_duphandle() to duplicate resolver URL-state specific
|
|
||||||
* environment ('resolver' member of the UrlState structure). Duplicates the
|
|
||||||
* 'from' ares channel and passes the resulting channel to the 'to' pointer.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
|
|
||||||
{
|
|
||||||
(void)from;
|
|
||||||
/*
|
|
||||||
* it would be better to call ares_dup instead, but right now
|
|
||||||
* it is not possible to set 'sock_state_cb_data' outside of
|
|
||||||
* ares_init_options
|
|
||||||
*/
|
|
||||||
return Curl_resolver_init(easy, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroy_async_data(struct Curl_async *async);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Cancel all possibly still on-going resolves for this connection.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_cancel(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
if(data->state.async.resolver)
|
|
||||||
ares_cancel((ares_channel)data->state.async.resolver);
|
|
||||||
destroy_async_data(&data->state.async);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We're equivalent to Curl_resolver_cancel() for the c-ares resolver. We
|
|
||||||
* never block.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_kill(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
/* We don't need to check the resolver state because we can be called safely
|
|
||||||
at any time and we always do the same thing. */
|
|
||||||
Curl_resolver_cancel(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* destroy_async_data() cleans up async resolver data.
|
|
||||||
*/
|
|
||||||
static void destroy_async_data(struct Curl_async *async)
|
|
||||||
{
|
|
||||||
if(async->tdata) {
|
|
||||||
struct thread_data *res = async->tdata;
|
|
||||||
if(res) {
|
|
||||||
if(res->temp_ai) {
|
|
||||||
Curl_freeaddrinfo(res->temp_ai);
|
|
||||||
res->temp_ai = NULL;
|
|
||||||
}
|
|
||||||
free(res);
|
|
||||||
}
|
|
||||||
async->tdata = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_getsock() is called when someone from the outside world
|
|
||||||
* (using curl_multi_fdset()) wants to get our fd_set setup and we're talking
|
|
||||||
* with ares. The caller must make sure that this function is only called when
|
|
||||||
* we have a working ares channel.
|
|
||||||
*
|
|
||||||
* Returns: sockets-in-use-bitmap
|
|
||||||
*/
|
|
||||||
|
|
||||||
int Curl_resolver_getsock(struct Curl_easy *data,
|
|
||||||
curl_socket_t *socks)
|
|
||||||
{
|
|
||||||
struct timeval maxtime;
|
|
||||||
struct timeval timebuf;
|
|
||||||
struct timeval *timeout;
|
|
||||||
long milli;
|
|
||||||
int max = ares_getsock((ares_channel)data->state.async.resolver,
|
|
||||||
(ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
|
|
||||||
|
|
||||||
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
|
|
||||||
maxtime.tv_usec = 0;
|
|
||||||
|
|
||||||
timeout = ares_timeout((ares_channel)data->state.async.resolver, &maxtime,
|
|
||||||
&timebuf);
|
|
||||||
milli = (long)curlx_tvtoms(timeout);
|
|
||||||
if(milli == 0)
|
|
||||||
milli += 10;
|
|
||||||
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
|
||||||
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* waitperform()
|
|
||||||
*
|
|
||||||
* 1) Ask ares what sockets it currently plays with, then
|
|
||||||
* 2) wait for the timeout period to check for action on ares' sockets.
|
|
||||||
* 3) tell ares to act on all the sockets marked as "with action"
|
|
||||||
*
|
|
||||||
* return number of sockets it worked on, or -1 on error
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
|
|
||||||
{
|
|
||||||
int nfds;
|
|
||||||
int bitmask;
|
|
||||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
|
||||||
struct pollfd pfd[ARES_GETSOCK_MAXNUM];
|
|
||||||
int i;
|
|
||||||
int num = 0;
|
|
||||||
|
|
||||||
bitmask = ares_getsock((ares_channel)data->state.async.resolver, socks,
|
|
||||||
ARES_GETSOCK_MAXNUM);
|
|
||||||
|
|
||||||
for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
|
|
||||||
pfd[i].events = 0;
|
|
||||||
pfd[i].revents = 0;
|
|
||||||
if(ARES_GETSOCK_READABLE(bitmask, i)) {
|
|
||||||
pfd[i].fd = socks[i];
|
|
||||||
pfd[i].events |= POLLRDNORM|POLLIN;
|
|
||||||
}
|
|
||||||
if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
|
|
||||||
pfd[i].fd = socks[i];
|
|
||||||
pfd[i].events |= POLLWRNORM|POLLOUT;
|
|
||||||
}
|
|
||||||
if(pfd[i].events)
|
|
||||||
num++;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(num) {
|
|
||||||
nfds = Curl_poll(pfd, num, timeout_ms);
|
|
||||||
if(nfds < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nfds = 0;
|
|
||||||
|
|
||||||
if(!nfds)
|
|
||||||
/* Call ares_process() unconditionally here, even if we simply timed out
|
|
||||||
above, as otherwise the ares name resolve won't timeout! */
|
|
||||||
ares_process_fd((ares_channel)data->state.async.resolver, ARES_SOCKET_BAD,
|
|
||||||
ARES_SOCKET_BAD);
|
|
||||||
else {
|
|
||||||
/* move through the descriptors and ask for processing on them */
|
|
||||||
for(i = 0; i < num; i++)
|
|
||||||
ares_process_fd((ares_channel)data->state.async.resolver,
|
|
||||||
(pfd[i].revents & (POLLRDNORM|POLLIN))?
|
|
||||||
pfd[i].fd:ARES_SOCKET_BAD,
|
|
||||||
(pfd[i].revents & (POLLWRNORM|POLLOUT))?
|
|
||||||
pfd[i].fd:ARES_SOCKET_BAD);
|
|
||||||
}
|
|
||||||
return nfds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_is_resolved() is called repeatedly to check if a previous
|
|
||||||
* name resolve request has completed. It should also make sure to time-out if
|
|
||||||
* the operation seems to take too long.
|
|
||||||
*
|
|
||||||
* Returns normal CURLcode errors.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
|
||||||
struct Curl_dns_entry **dns)
|
|
||||||
{
|
|
||||||
struct thread_data *res = data->state.async.tdata;
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
DEBUGASSERT(dns);
|
|
||||||
*dns = NULL;
|
|
||||||
|
|
||||||
if(waitperform(data, 0) < 0)
|
|
||||||
return CURLE_UNRECOVERABLE_POLL;
|
|
||||||
|
|
||||||
#ifndef HAVE_CARES_GETADDRINFO
|
|
||||||
/* Now that we've checked for any last minute results above, see if there are
|
|
||||||
any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
|
|
||||||
expires. */
|
|
||||||
if(res
|
|
||||||
&& res->num_pending
|
|
||||||
/* This is only set to non-zero if the timer was started. */
|
|
||||||
&& (res->happy_eyeballs_dns_time.tv_sec
|
|
||||||
|| res->happy_eyeballs_dns_time.tv_usec)
|
|
||||||
&& (Curl_timediff(Curl_now(), res->happy_eyeballs_dns_time)
|
|
||||||
>= HAPPY_EYEBALLS_DNS_TIMEOUT)) {
|
|
||||||
/* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer
|
|
||||||
running. */
|
|
||||||
memset(
|
|
||||||
&res->happy_eyeballs_dns_time, 0, sizeof(res->happy_eyeballs_dns_time));
|
|
||||||
|
|
||||||
/* Cancel the raw c-ares request, which will fire query_completed_cb() with
|
|
||||||
ARES_ECANCELLED synchronously for all pending responses. This will
|
|
||||||
leave us with res->num_pending == 0, which is perfect for the next
|
|
||||||
block. */
|
|
||||||
ares_cancel((ares_channel)data->state.async.resolver);
|
|
||||||
DEBUGASSERT(res->num_pending == 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(res && !res->num_pending) {
|
|
||||||
(void)Curl_addrinfo_callback(data, res->last_status, res->temp_ai);
|
|
||||||
/* temp_ai ownership is moved to the connection, so we need not free-up
|
|
||||||
them */
|
|
||||||
res->temp_ai = NULL;
|
|
||||||
|
|
||||||
if(!data->state.async.dns)
|
|
||||||
result = Curl_resolver_error(data);
|
|
||||||
else
|
|
||||||
*dns = data->state.async.dns;
|
|
||||||
|
|
||||||
destroy_async_data(&data->state.async);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_wait_resolv()
|
|
||||||
*
|
|
||||||
* Waits for a resolve to finish. This function should be avoided since using
|
|
||||||
* this risk getting the multi interface to "hang".
|
|
||||||
*
|
|
||||||
* 'entry' MUST be non-NULL.
|
|
||||||
*
|
|
||||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
|
||||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
|
|
||||||
struct Curl_dns_entry **entry)
|
|
||||||
{
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
timediff_t timeout;
|
|
||||||
struct curltime now = Curl_now();
|
|
||||||
|
|
||||||
DEBUGASSERT(entry);
|
|
||||||
*entry = NULL; /* clear on entry */
|
|
||||||
|
|
||||||
timeout = Curl_timeleft(data, &now, TRUE);
|
|
||||||
if(timeout < 0) {
|
|
||||||
/* already expired! */
|
|
||||||
connclose(data->conn, "Timed out before name resolve started");
|
|
||||||
return CURLE_OPERATION_TIMEDOUT;
|
|
||||||
}
|
|
||||||
if(!timeout)
|
|
||||||
timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
|
|
||||||
|
|
||||||
/* Wait for the name resolve query to complete. */
|
|
||||||
while(!result) {
|
|
||||||
struct timeval *tvp, tv, store;
|
|
||||||
int itimeout;
|
|
||||||
timediff_t timeout_ms;
|
|
||||||
|
|
||||||
#if TIMEDIFF_T_MAX > INT_MAX
|
|
||||||
itimeout = (timeout > INT_MAX) ? INT_MAX : (int)timeout;
|
|
||||||
#else
|
|
||||||
itimeout = (int)timeout;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
store.tv_sec = itimeout/1000;
|
|
||||||
store.tv_usec = (itimeout%1000)*1000;
|
|
||||||
|
|
||||||
tvp = ares_timeout((ares_channel)data->state.async.resolver, &store, &tv);
|
|
||||||
|
|
||||||
/* use the timeout period ares returned to us above if less than one
|
|
||||||
second is left, otherwise just use 1000ms to make sure the progress
|
|
||||||
callback gets called frequent enough */
|
|
||||||
if(!tvp->tv_sec)
|
|
||||||
timeout_ms = (timediff_t)(tvp->tv_usec/1000);
|
|
||||||
else
|
|
||||||
timeout_ms = 1000;
|
|
||||||
|
|
||||||
if(waitperform(data, timeout_ms) < 0)
|
|
||||||
return CURLE_UNRECOVERABLE_POLL;
|
|
||||||
result = Curl_resolver_is_resolved(data, entry);
|
|
||||||
|
|
||||||
if(result || data->state.async.done)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(Curl_pgrsUpdate(data))
|
|
||||||
result = CURLE_ABORTED_BY_CALLBACK;
|
|
||||||
else {
|
|
||||||
struct curltime now2 = Curl_now();
|
|
||||||
timediff_t timediff = Curl_timediff(now2, now); /* spent time */
|
|
||||||
if(timediff <= 0)
|
|
||||||
timeout -= 1; /* always deduct at least 1 */
|
|
||||||
else if(timediff > timeout)
|
|
||||||
timeout = -1;
|
|
||||||
else
|
|
||||||
timeout -= timediff;
|
|
||||||
now = now2; /* for next loop */
|
|
||||||
}
|
|
||||||
if(timeout < 0)
|
|
||||||
result = CURLE_OPERATION_TIMEDOUT;
|
|
||||||
}
|
|
||||||
if(result)
|
|
||||||
/* failure, so we cancel the ares operation */
|
|
||||||
ares_cancel((ares_channel)data->state.async.resolver);
|
|
||||||
|
|
||||||
/* Operation complete, if the lookup was successful we now have the entry
|
|
||||||
in the cache. */
|
|
||||||
if(entry)
|
|
||||||
*entry = data->state.async.dns;
|
|
||||||
|
|
||||||
if(result)
|
|
||||||
/* close the connection, since we can't return failure here without
|
|
||||||
cleaning up this connection properly. */
|
|
||||||
connclose(data->conn, "c-ares resolve failed");
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef HAVE_CARES_GETADDRINFO
|
|
||||||
|
|
||||||
/* Connects results to the list */
|
|
||||||
static void compound_results(struct thread_data *res,
|
|
||||||
struct Curl_addrinfo *ai)
|
|
||||||
{
|
|
||||||
if(!ai)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
|
||||||
if(res->temp_ai && res->temp_ai->ai_family == PF_INET6) {
|
|
||||||
/* We have results already, put the new IPv6 entries at the head of the
|
|
||||||
list. */
|
|
||||||
struct Curl_addrinfo *temp_ai_tail = res->temp_ai;
|
|
||||||
|
|
||||||
while(temp_ai_tail->ai_next)
|
|
||||||
temp_ai_tail = temp_ai_tail->ai_next;
|
|
||||||
|
|
||||||
temp_ai_tail->ai_next = ai;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif /* CURLRES_IPV6 */
|
|
||||||
{
|
|
||||||
/* Add the new results to the list of old results. */
|
|
||||||
struct Curl_addrinfo *ai_tail = ai;
|
|
||||||
while(ai_tail->ai_next)
|
|
||||||
ai_tail = ai_tail->ai_next;
|
|
||||||
|
|
||||||
ai_tail->ai_next = res->temp_ai;
|
|
||||||
res->temp_ai = ai;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ares_query_completed_cb() is the callback that ares will call when
|
|
||||||
* the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
|
|
||||||
* when using ares, is completed either successfully or with failure.
|
|
||||||
*/
|
|
||||||
static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
|
||||||
int status,
|
|
||||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
|
||||||
int timeouts,
|
|
||||||
#endif
|
|
||||||
struct hostent *hostent)
|
|
||||||
{
|
|
||||||
struct Curl_easy *data = (struct Curl_easy *)arg;
|
|
||||||
struct thread_data *res;
|
|
||||||
|
|
||||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
|
||||||
(void)timeouts; /* ignored */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(ARES_EDESTRUCTION == status)
|
|
||||||
/* when this ares handle is getting destroyed, the 'arg' pointer may not
|
|
||||||
be valid so only defer it when we know the 'status' says its fine! */
|
|
||||||
return;
|
|
||||||
|
|
||||||
res = data->state.async.tdata;
|
|
||||||
if(res) {
|
|
||||||
res->num_pending--;
|
|
||||||
|
|
||||||
if(CURL_ASYNC_SUCCESS == status) {
|
|
||||||
struct Curl_addrinfo *ai = Curl_he2ai(hostent, data->state.async.port);
|
|
||||||
if(ai) {
|
|
||||||
compound_results(res, ai);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* A successful result overwrites any previous error */
|
|
||||||
if(res->last_status != ARES_SUCCESS)
|
|
||||||
res->last_status = status;
|
|
||||||
|
|
||||||
/* If there are responses still pending, we presume they must be the
|
|
||||||
complementary IPv4 or IPv6 lookups that we started in parallel in
|
|
||||||
Curl_resolver_getaddrinfo() (for Happy Eyeballs). If we've got a
|
|
||||||
"definitive" response from one of a set of parallel queries, we need to
|
|
||||||
think about how long we're willing to wait for more responses. */
|
|
||||||
if(res->num_pending
|
|
||||||
/* Only these c-ares status values count as "definitive" for these
|
|
||||||
purposes. For example, ARES_ENODATA is what we expect when there is
|
|
||||||
no IPv6 entry for a domain name, and that's not a reason to get more
|
|
||||||
aggressive in our timeouts for the other response. Other errors are
|
|
||||||
either a result of bad input (which should affect all parallel
|
|
||||||
requests), local or network conditions, non-definitive server
|
|
||||||
responses, or us cancelling the request. */
|
|
||||||
&& (status == ARES_SUCCESS || status == ARES_ENOTFOUND)) {
|
|
||||||
/* Right now, there can only be up to two parallel queries, so don't
|
|
||||||
bother handling any other cases. */
|
|
||||||
DEBUGASSERT(res->num_pending == 1);
|
|
||||||
|
|
||||||
/* It's possible that one of these parallel queries could succeed
|
|
||||||
quickly, but the other could always fail or timeout (when we're
|
|
||||||
talking to a pool of DNS servers that can only successfully resolve
|
|
||||||
IPv4 address, for example).
|
|
||||||
|
|
||||||
It's also possible that the other request could always just take
|
|
||||||
longer because it needs more time or only the second DNS server can
|
|
||||||
fulfill it successfully. But, to align with the philosophy of Happy
|
|
||||||
Eyeballs, we don't want to wait _too_ long or users will think
|
|
||||||
requests are slow when IPv6 lookups don't actually work (but IPv4 ones
|
|
||||||
do).
|
|
||||||
|
|
||||||
So, now that we have a usable answer (some IPv4 addresses, some IPv6
|
|
||||||
addresses, or "no such domain"), we start a timeout for the remaining
|
|
||||||
pending responses. Even though it is typical that this resolved
|
|
||||||
request came back quickly, that needn't be the case. It might be that
|
|
||||||
this completing request didn't get a result from the first DNS server
|
|
||||||
or even the first round of the whole DNS server pool. So it could
|
|
||||||
already be quite some time after we issued the DNS queries in the
|
|
||||||
first place. Without modifying c-ares, we can't know exactly where in
|
|
||||||
its retry cycle we are. We could guess based on how much time has
|
|
||||||
gone by, but it doesn't really matter. Happy Eyeballs tells us that,
|
|
||||||
given usable information in hand, we simply don't want to wait "too
|
|
||||||
much longer" after we get a result.
|
|
||||||
|
|
||||||
We simply wait an additional amount of time equal to the default
|
|
||||||
c-ares query timeout. That is enough time for a typical parallel
|
|
||||||
response to arrive without being "too long". Even on a network
|
|
||||||
where one of the two types of queries is failing or timing out
|
|
||||||
constantly, this will usually mean we wait a total of the default
|
|
||||||
c-ares timeout (5 seconds) plus the round trip time for the successful
|
|
||||||
request, which seems bearable. The downside is that c-ares might race
|
|
||||||
with us to issue one more retry just before we give up, but it seems
|
|
||||||
better to "waste" that request instead of trying to guess the perfect
|
|
||||||
timeout to prevent it. After all, we don't even know where in the
|
|
||||||
c-ares retry cycle each request is.
|
|
||||||
*/
|
|
||||||
res->happy_eyeballs_dns_time = Curl_now();
|
|
||||||
Curl_expire(data, HAPPY_EYEBALLS_DNS_TIMEOUT,
|
|
||||||
EXPIRE_HAPPY_EYEBALLS_DNS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* c-ares 1.16.0 or later */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ares2addr() converts an address list provided by c-ares to an internal
|
|
||||||
* libcurl compatible list
|
|
||||||
*/
|
|
||||||
static struct Curl_addrinfo *ares2addr(struct ares_addrinfo_node *node)
|
|
||||||
{
|
|
||||||
/* traverse the ares_addrinfo_node list */
|
|
||||||
struct ares_addrinfo_node *ai;
|
|
||||||
struct Curl_addrinfo *cafirst = NULL;
|
|
||||||
struct Curl_addrinfo *calast = NULL;
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
for(ai = node; ai != NULL; ai = ai->ai_next) {
|
|
||||||
size_t ss_size;
|
|
||||||
struct Curl_addrinfo *ca;
|
|
||||||
/* ignore elements with unsupported address family, */
|
|
||||||
/* settle family-specific sockaddr structure size. */
|
|
||||||
if(ai->ai_family == AF_INET)
|
|
||||||
ss_size = sizeof(struct sockaddr_in);
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
else if(ai->ai_family == AF_INET6)
|
|
||||||
ss_size = sizeof(struct sockaddr_in6);
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore elements without required address info */
|
|
||||||
if(!ai->ai_addr || !(ai->ai_addrlen > 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore elements with bogus address size */
|
|
||||||
if((size_t)ai->ai_addrlen < ss_size)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ca = malloc(sizeof(struct Curl_addrinfo) + ss_size);
|
|
||||||
if(!ca) {
|
|
||||||
error = EAI_MEMORY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy each structure member individually, member ordering, */
|
|
||||||
/* size, or padding might be different for each platform. */
|
|
||||||
|
|
||||||
ca->ai_flags = ai->ai_flags;
|
|
||||||
ca->ai_family = ai->ai_family;
|
|
||||||
ca->ai_socktype = ai->ai_socktype;
|
|
||||||
ca->ai_protocol = ai->ai_protocol;
|
|
||||||
ca->ai_addrlen = (curl_socklen_t)ss_size;
|
|
||||||
ca->ai_addr = NULL;
|
|
||||||
ca->ai_canonname = NULL;
|
|
||||||
ca->ai_next = NULL;
|
|
||||||
|
|
||||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
|
||||||
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
|
|
||||||
|
|
||||||
/* if the return list is empty, this becomes the first element */
|
|
||||||
if(!cafirst)
|
|
||||||
cafirst = ca;
|
|
||||||
|
|
||||||
/* add this element last in the return list */
|
|
||||||
if(calast)
|
|
||||||
calast->ai_next = ca;
|
|
||||||
calast = ca;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we failed, destroy the Curl_addrinfo list */
|
|
||||||
if(error) {
|
|
||||||
Curl_freeaddrinfo(cafirst);
|
|
||||||
cafirst = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cafirst;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addrinfo_cb(void *arg, int status, int timeouts,
|
|
||||||
struct ares_addrinfo *result)
|
|
||||||
{
|
|
||||||
struct Curl_easy *data = (struct Curl_easy *)arg;
|
|
||||||
struct thread_data *res = data->state.async.tdata;
|
|
||||||
(void)timeouts;
|
|
||||||
if(ARES_SUCCESS == status) {
|
|
||||||
res->temp_ai = ares2addr(result->nodes);
|
|
||||||
res->last_status = CURL_ASYNC_SUCCESS;
|
|
||||||
ares_freeaddrinfo(result);
|
|
||||||
}
|
|
||||||
res->num_pending--;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* Curl_resolver_getaddrinfo() - when using ares
|
|
||||||
*
|
|
||||||
* Returns name information about the given hostname and port number. If
|
|
||||||
* successful, the 'hostent' is returned and the fourth argument will point to
|
|
||||||
* memory we need to free after use. That memory *MUST* be freed with
|
|
||||||
* Curl_freeaddrinfo(), nothing else.
|
|
||||||
*/
|
|
||||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
|
||||||
const char *hostname,
|
|
||||||
int port,
|
|
||||||
int *waitp)
|
|
||||||
{
|
|
||||||
struct thread_data *res = NULL;
|
|
||||||
size_t namelen = strlen(hostname);
|
|
||||||
*waitp = 0; /* default to synchronous response */
|
|
||||||
|
|
||||||
res = calloc(sizeof(struct thread_data) + namelen, 1);
|
|
||||||
if(res) {
|
|
||||||
strcpy(res->hostname, hostname);
|
|
||||||
data->state.async.hostname = res->hostname;
|
|
||||||
data->state.async.port = port;
|
|
||||||
data->state.async.done = FALSE; /* not done */
|
|
||||||
data->state.async.status = 0; /* clear */
|
|
||||||
data->state.async.dns = NULL; /* clear */
|
|
||||||
data->state.async.tdata = res;
|
|
||||||
|
|
||||||
/* initial status - failed */
|
|
||||||
res->last_status = ARES_ENOTFOUND;
|
|
||||||
|
|
||||||
#ifdef HAVE_CARES_GETADDRINFO
|
|
||||||
{
|
|
||||||
struct ares_addrinfo_hints hints;
|
|
||||||
char service[12];
|
|
||||||
int pf = PF_INET;
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
#ifdef CURLRES_IPV6
|
|
||||||
if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
|
|
||||||
/* The stack seems to be IPv6-enabled */
|
|
||||||
pf = PF_UNSPEC;
|
|
||||||
#endif /* CURLRES_IPV6 */
|
|
||||||
hints.ai_family = pf;
|
|
||||||
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
|
|
||||||
SOCK_STREAM : SOCK_DGRAM;
|
|
||||||
/* Since the service is a numerical one, set the hint flags
|
|
||||||
* accordingly to save a call to getservbyname in inside C-Ares
|
|
||||||
*/
|
|
||||||
hints.ai_flags = ARES_AI_NUMERICSERV;
|
|
||||||
msnprintf(service, sizeof(service), "%d", port);
|
|
||||||
res->num_pending = 1;
|
|
||||||
ares_getaddrinfo((ares_channel)data->state.async.resolver, hostname,
|
|
||||||
service, &hints, addrinfo_cb, data);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef HAVE_CARES_IPV6
|
|
||||||
if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) {
|
|
||||||
/* The stack seems to be IPv6-enabled */
|
|
||||||
res->num_pending = 2;
|
|
||||||
|
|
||||||
/* areschannel is already setup in the Curl_open() function */
|
|
||||||
ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
|
|
||||||
PF_INET, query_completed_cb, data);
|
|
||||||
ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
|
|
||||||
PF_INET6, query_completed_cb, data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
res->num_pending = 1;
|
|
||||||
|
|
||||||
/* areschannel is already setup in the Curl_open() function */
|
|
||||||
ares_gethostbyname((ares_channel)data->state.async.resolver,
|
|
||||||
hostname, PF_INET,
|
|
||||||
query_completed_cb, data);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*waitp = 1; /* expect asynchronous response */
|
|
||||||
}
|
|
||||||
return NULL; /* no struct yet */
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
|
||||||
char *servers)
|
|
||||||
{
|
|
||||||
CURLcode result = CURLE_NOT_BUILT_IN;
|
|
||||||
int ares_result;
|
|
||||||
|
|
||||||
/* If server is NULL or empty, this would purge all DNS servers
|
|
||||||
* from ares library, which will cause any and all queries to fail.
|
|
||||||
* So, just return OK if none are configured and don't actually make
|
|
||||||
* any changes to c-ares. This lets c-ares use it's defaults, which
|
|
||||||
* it gets from the OS (for instance from /etc/resolv.conf on Linux).
|
|
||||||
*/
|
|
||||||
if(!(servers && servers[0]))
|
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
#ifdef HAVE_CARES_SERVERS_CSV
|
|
||||||
#ifdef HAVE_CARES_PORTS_CSV
|
|
||||||
ares_result = ares_set_servers_ports_csv(data->state.async.resolver,
|
|
||||||
servers);
|
|
||||||
#else
|
|
||||||
ares_result = ares_set_servers_csv(data->state.async.resolver, servers);
|
|
||||||
#endif
|
|
||||||
switch(ares_result) {
|
|
||||||
case ARES_SUCCESS:
|
|
||||||
result = CURLE_OK;
|
|
||||||
break;
|
|
||||||
case ARES_ENOMEM:
|
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
|
||||||
break;
|
|
||||||
case ARES_ENOTINITIALIZED:
|
|
||||||
case ARES_ENODATA:
|
|
||||||
case ARES_EBADSTR:
|
|
||||||
default:
|
|
||||||
result = CURLE_BAD_FUNCTION_ARGUMENT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else /* too old c-ares version! */
|
|
||||||
(void)data;
|
|
||||||
(void)(ares_result);
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
|
||||||
const char *interf)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_CARES_LOCAL_DEV
|
|
||||||
if(!interf)
|
|
||||||
interf = "";
|
|
||||||
|
|
||||||
ares_set_local_dev((ares_channel)data->state.async.resolver, interf);
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
#else /* c-ares version too old! */
|
|
||||||
(void)data;
|
|
||||||
(void)interf;
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
|
||||||
const char *local_ip4)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_CARES_SET_LOCAL
|
|
||||||
struct in_addr a4;
|
|
||||||
|
|
||||||
if((!local_ip4) || (local_ip4[0] == 0)) {
|
|
||||||
a4.s_addr = 0; /* disabled: do not bind to a specific address */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
|
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ares_set_local_ip4((ares_channel)data->state.async.resolver,
|
|
||||||
ntohl(a4.s_addr));
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
#else /* c-ares version too old! */
|
|
||||||
(void)data;
|
|
||||||
(void)local_ip4;
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
|
||||||
const char *local_ip6)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_CARES_SET_LOCAL) && defined(ENABLE_IPV6)
|
|
||||||
unsigned char a6[INET6_ADDRSTRLEN];
|
|
||||||
|
|
||||||
if((!local_ip6) || (local_ip6[0] == 0)) {
|
|
||||||
/* disabled: do not bind to a specific address */
|
|
||||||
memset(a6, 0, sizeof(a6));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) {
|
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ares_set_local_ip6((ares_channel)data->state.async.resolver, a6);
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
#else /* c-ares version too old! */
|
|
||||||
(void)data;
|
|
||||||
(void)local_ip6;
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /* CURLRES_ARES */
|
|
|
@ -1,756 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
#include "socketpair.h"
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* Only for threaded name resolves builds
|
|
||||||
**********************************************************************/
|
|
||||||
#ifdef CURLRES_THREADED
|
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETDB_H
|
|
||||||
#include <netdb.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
#ifdef __VMS
|
|
||||||
#include <in.h>
|
|
||||||
#include <inet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
|
||||||
# include <pthread.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
# define RESOLVER_ENOMEM EAI_MEMORY
|
|
||||||
#else
|
|
||||||
# define RESOLVER_ENOMEM ENOMEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "urldata.h"
|
|
||||||
#include "sendf.h"
|
|
||||||
#include "hostip.h"
|
|
||||||
#include "hash.h"
|
|
||||||
#include "share.h"
|
|
||||||
#include "url.h"
|
|
||||||
#include "multiif.h"
|
|
||||||
#include "inet_ntop.h"
|
|
||||||
#include "curl_threads.h"
|
|
||||||
#include "connect.h"
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
struct resdata {
|
|
||||||
struct curltime start;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_global_init()
|
|
||||||
* Called from curl_global_init() to initialize global resolver environment.
|
|
||||||
* Does nothing here.
|
|
||||||
*/
|
|
||||||
int Curl_resolver_global_init(void)
|
|
||||||
{
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_global_cleanup()
|
|
||||||
* Called from curl_global_cleanup() to destroy global resolver environment.
|
|
||||||
* Does nothing here.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_global_cleanup(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_init()
|
|
||||||
* Called from curl_easy_init() -> Curl_open() to initialize resolver
|
|
||||||
* URL-state specific environment ('resolver' member of the UrlState
|
|
||||||
* structure).
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
|
|
||||||
{
|
|
||||||
(void)easy;
|
|
||||||
*resolver = calloc(1, sizeof(struct resdata));
|
|
||||||
if(!*resolver)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_cleanup()
|
|
||||||
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
|
|
||||||
* URL-state specific environment ('resolver' member of the UrlState
|
|
||||||
* structure).
|
|
||||||
*/
|
|
||||||
void Curl_resolver_cleanup(void *resolver)
|
|
||||||
{
|
|
||||||
free(resolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_duphandle()
|
|
||||||
* Called from curl_easy_duphandle() to duplicate resolver URL state-specific
|
|
||||||
* environment ('resolver' member of the UrlState structure).
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
|
|
||||||
{
|
|
||||||
(void)from;
|
|
||||||
return Curl_resolver_init(easy, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroy_async_data(struct Curl_async *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Cancel all possibly still on-going resolves for this connection.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_cancel(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
destroy_async_data(&data->state.async);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function is used to init a threaded resolve */
|
|
||||||
static bool init_resolve_thread(struct Curl_easy *data,
|
|
||||||
const char *hostname, int port,
|
|
||||||
const struct addrinfo *hints);
|
|
||||||
|
|
||||||
|
|
||||||
/* Data for synchronization between resolver thread and its parent */
|
|
||||||
struct thread_sync_data {
|
|
||||||
curl_mutex_t *mtx;
|
|
||||||
int done;
|
|
||||||
int port;
|
|
||||||
char *hostname; /* hostname to resolve, Curl_async.hostname
|
|
||||||
duplicate */
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
struct Curl_easy *data;
|
|
||||||
curl_socket_t sock_pair[2]; /* socket pair */
|
|
||||||
#endif
|
|
||||||
int sock_error;
|
|
||||||
struct Curl_addrinfo *res;
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
struct addrinfo hints;
|
|
||||||
#endif
|
|
||||||
struct thread_data *td; /* for thread-self cleanup */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct thread_data {
|
|
||||||
curl_thread_t thread_hnd;
|
|
||||||
unsigned int poll_interval;
|
|
||||||
timediff_t interval_end;
|
|
||||||
struct thread_sync_data tsd;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct thread_sync_data *conn_thread_sync_data(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
return &(data->state.async.tdata->tsd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Destroy resolver thread synchronization data */
|
|
||||||
static
|
|
||||||
void destroy_thread_sync_data(struct thread_sync_data *tsd)
|
|
||||||
{
|
|
||||||
if(tsd->mtx) {
|
|
||||||
Curl_mutex_destroy(tsd->mtx);
|
|
||||||
free(tsd->mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(tsd->hostname);
|
|
||||||
|
|
||||||
if(tsd->res)
|
|
||||||
Curl_freeaddrinfo(tsd->res);
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
/*
|
|
||||||
* close one end of the socket pair (may be done in resolver thread);
|
|
||||||
* the other end (for reading) is always closed in the parent thread.
|
|
||||||
*/
|
|
||||||
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
|
|
||||||
sclose(tsd->sock_pair[1]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
memset(tsd, 0, sizeof(*tsd));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize resolver thread synchronization data */
|
|
||||||
static
|
|
||||||
int init_thread_sync_data(struct thread_data *td,
|
|
||||||
const char *hostname,
|
|
||||||
int port,
|
|
||||||
const struct addrinfo *hints)
|
|
||||||
{
|
|
||||||
struct thread_sync_data *tsd = &td->tsd;
|
|
||||||
|
|
||||||
memset(tsd, 0, sizeof(*tsd));
|
|
||||||
|
|
||||||
tsd->td = td;
|
|
||||||
tsd->port = port;
|
|
||||||
/* Treat the request as done until the thread actually starts so any early
|
|
||||||
* cleanup gets done properly.
|
|
||||||
*/
|
|
||||||
tsd->done = 1;
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
DEBUGASSERT(hints);
|
|
||||||
tsd->hints = *hints;
|
|
||||||
#else
|
|
||||||
(void) hints;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tsd->mtx = malloc(sizeof(curl_mutex_t));
|
|
||||||
if(!tsd->mtx)
|
|
||||||
goto err_exit;
|
|
||||||
|
|
||||||
Curl_mutex_init(tsd->mtx);
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
/* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */
|
|
||||||
if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
|
|
||||||
tsd->sock_pair[0] = CURL_SOCKET_BAD;
|
|
||||||
tsd->sock_pair[1] = CURL_SOCKET_BAD;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
tsd->sock_error = CURL_ASYNC_SUCCESS;
|
|
||||||
|
|
||||||
/* Copying hostname string because original can be destroyed by parent
|
|
||||||
* thread during gethostbyname execution.
|
|
||||||
*/
|
|
||||||
tsd->hostname = strdup(hostname);
|
|
||||||
if(!tsd->hostname)
|
|
||||||
goto err_exit;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
err_exit:
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
if(tsd->sock_pair[0] != CURL_SOCKET_BAD) {
|
|
||||||
sclose(tsd->sock_pair[0]);
|
|
||||||
tsd->sock_pair[0] = CURL_SOCKET_BAD;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
destroy_thread_sync_data(tsd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode getaddrinfo_complete(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
struct thread_sync_data *tsd = conn_thread_sync_data(data);
|
|
||||||
CURLcode result;
|
|
||||||
|
|
||||||
result = Curl_addrinfo_callback(data, tsd->sock_error, tsd->res);
|
|
||||||
/* The tsd->res structure has been copied to async.dns and perhaps the DNS
|
|
||||||
cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
|
|
||||||
*/
|
|
||||||
tsd->res = NULL;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
|
|
||||||
/*
|
|
||||||
* getaddrinfo_thread() resolves a name and then exits.
|
|
||||||
*
|
|
||||||
* For builds without ARES, but with ENABLE_IPV6, create a resolver thread
|
|
||||||
* and wait on it.
|
|
||||||
*/
|
|
||||||
static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
|
|
||||||
{
|
|
||||||
struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
|
|
||||||
struct thread_data *td = tsd->td;
|
|
||||||
char service[12];
|
|
||||||
int rc;
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
char buf[1];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
msnprintf(service, sizeof(service), "%d", tsd->port);
|
|
||||||
|
|
||||||
rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
|
|
||||||
|
|
||||||
if(rc) {
|
|
||||||
tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
|
|
||||||
if(tsd->sock_error == 0)
|
|
||||||
tsd->sock_error = RESOLVER_ENOMEM;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Curl_addrinfo_set_port(tsd->res, tsd->port);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_mutex_acquire(tsd->mtx);
|
|
||||||
if(tsd->done) {
|
|
||||||
/* too late, gotta clean up the mess */
|
|
||||||
Curl_mutex_release(tsd->mtx);
|
|
||||||
destroy_thread_sync_data(tsd);
|
|
||||||
free(td);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
|
|
||||||
/* DNS has been resolved, signal client task */
|
|
||||||
buf[0] = 1;
|
|
||||||
if(swrite(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
|
|
||||||
/* update sock_erro to errno */
|
|
||||||
tsd->sock_error = SOCKERRNO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
tsd->done = 1;
|
|
||||||
Curl_mutex_release(tsd->mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* HAVE_GETADDRINFO */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* gethostbyname_thread() resolves a name and then exits.
|
|
||||||
*/
|
|
||||||
static unsigned int CURL_STDCALL gethostbyname_thread(void *arg)
|
|
||||||
{
|
|
||||||
struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
|
|
||||||
struct thread_data *td = tsd->td;
|
|
||||||
|
|
||||||
tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
|
|
||||||
|
|
||||||
if(!tsd->res) {
|
|
||||||
tsd->sock_error = SOCKERRNO;
|
|
||||||
if(tsd->sock_error == 0)
|
|
||||||
tsd->sock_error = RESOLVER_ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_mutex_acquire(tsd->mtx);
|
|
||||||
if(tsd->done) {
|
|
||||||
/* too late, gotta clean up the mess */
|
|
||||||
Curl_mutex_release(tsd->mtx);
|
|
||||||
destroy_thread_sync_data(tsd);
|
|
||||||
free(td);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tsd->done = 1;
|
|
||||||
Curl_mutex_release(tsd->mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_GETADDRINFO */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* destroy_async_data() cleans up async resolver data and thread handle.
|
|
||||||
*/
|
|
||||||
static void destroy_async_data(struct Curl_async *async)
|
|
||||||
{
|
|
||||||
if(async->tdata) {
|
|
||||||
struct thread_data *td = async->tdata;
|
|
||||||
int done;
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
curl_socket_t sock_rd = td->tsd.sock_pair[0];
|
|
||||||
struct Curl_easy *data = td->tsd.data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if the thread is still blocking in the resolve syscall, detach it and
|
|
||||||
* let the thread do the cleanup...
|
|
||||||
*/
|
|
||||||
Curl_mutex_acquire(td->tsd.mtx);
|
|
||||||
done = td->tsd.done;
|
|
||||||
td->tsd.done = 1;
|
|
||||||
Curl_mutex_release(td->tsd.mtx);
|
|
||||||
|
|
||||||
if(!done) {
|
|
||||||
Curl_thread_destroy(td->thread_hnd);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(td->thread_hnd != curl_thread_t_null)
|
|
||||||
Curl_thread_join(&td->thread_hnd);
|
|
||||||
|
|
||||||
destroy_thread_sync_data(&td->tsd);
|
|
||||||
|
|
||||||
free(async->tdata);
|
|
||||||
}
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
/*
|
|
||||||
* ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE
|
|
||||||
* before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL
|
|
||||||
*/
|
|
||||||
Curl_multi_closed(data, sock_rd);
|
|
||||||
sclose(sock_rd);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
async->tdata = NULL;
|
|
||||||
|
|
||||||
free(async->hostname);
|
|
||||||
async->hostname = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* init_resolve_thread() starts a new thread that performs the actual
|
|
||||||
* resolve. This function returns before the resolve is done.
|
|
||||||
*
|
|
||||||
* Returns FALSE in case of failure, otherwise TRUE.
|
|
||||||
*/
|
|
||||||
static bool init_resolve_thread(struct Curl_easy *data,
|
|
||||||
const char *hostname, int port,
|
|
||||||
const struct addrinfo *hints)
|
|
||||||
{
|
|
||||||
struct thread_data *td = calloc(1, sizeof(struct thread_data));
|
|
||||||
int err = ENOMEM;
|
|
||||||
struct Curl_async *asp = &data->state.async;
|
|
||||||
|
|
||||||
data->state.async.tdata = td;
|
|
||||||
if(!td)
|
|
||||||
goto errno_exit;
|
|
||||||
|
|
||||||
asp->port = port;
|
|
||||||
asp->done = FALSE;
|
|
||||||
asp->status = 0;
|
|
||||||
asp->dns = NULL;
|
|
||||||
td->thread_hnd = curl_thread_t_null;
|
|
||||||
|
|
||||||
if(!init_thread_sync_data(td, hostname, port, hints)) {
|
|
||||||
asp->tdata = NULL;
|
|
||||||
free(td);
|
|
||||||
goto errno_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(asp->hostname);
|
|
||||||
asp->hostname = strdup(hostname);
|
|
||||||
if(!asp->hostname)
|
|
||||||
goto err_exit;
|
|
||||||
|
|
||||||
/* The thread will set this to 1 when complete. */
|
|
||||||
td->tsd.done = 0;
|
|
||||||
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
|
|
||||||
#else
|
|
||||||
td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!td->thread_hnd) {
|
|
||||||
/* The thread never started, so mark it as done here for proper cleanup. */
|
|
||||||
td->tsd.done = 1;
|
|
||||||
err = errno;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
err_exit:
|
|
||||||
destroy_async_data(asp);
|
|
||||||
|
|
||||||
errno_exit:
|
|
||||||
errno = err;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 'entry' may be NULL and then no data is returned
|
|
||||||
*/
|
|
||||||
static CURLcode thread_wait_resolv(struct Curl_easy *data,
|
|
||||||
struct Curl_dns_entry **entry,
|
|
||||||
bool report)
|
|
||||||
{
|
|
||||||
struct thread_data *td;
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
td = data->state.async.tdata;
|
|
||||||
DEBUGASSERT(td);
|
|
||||||
DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
|
|
||||||
|
|
||||||
/* wait for the thread to resolve the name */
|
|
||||||
if(Curl_thread_join(&td->thread_hnd)) {
|
|
||||||
if(entry)
|
|
||||||
result = getaddrinfo_complete(data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DEBUGASSERT(0);
|
|
||||||
|
|
||||||
data->state.async.done = TRUE;
|
|
||||||
|
|
||||||
if(entry)
|
|
||||||
*entry = data->state.async.dns;
|
|
||||||
|
|
||||||
if(!data->state.async.dns && report)
|
|
||||||
/* a name was not resolved, report error */
|
|
||||||
result = Curl_resolver_error(data);
|
|
||||||
|
|
||||||
destroy_async_data(&data->state.async);
|
|
||||||
|
|
||||||
if(!data->state.async.dns && report)
|
|
||||||
connclose(data->conn, "asynch resolve failed");
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Until we gain a way to signal the resolver threads to stop early, we must
|
|
||||||
* simply wait for them and ignore their results.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_kill(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
struct thread_data *td = data->state.async.tdata;
|
|
||||||
|
|
||||||
/* If we're still resolving, we must wait for the threads to fully clean up,
|
|
||||||
unfortunately. Otherwise, we can simply cancel to clean up any resolver
|
|
||||||
data. */
|
|
||||||
if(td && td->thread_hnd != curl_thread_t_null
|
|
||||||
&& (data->set.quick_exit != 1L))
|
|
||||||
(void)thread_wait_resolv(data, NULL, FALSE);
|
|
||||||
else
|
|
||||||
Curl_resolver_cancel(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_wait_resolv()
|
|
||||||
*
|
|
||||||
* Waits for a resolve to finish. This function should be avoided since using
|
|
||||||
* this risk getting the multi interface to "hang".
|
|
||||||
*
|
|
||||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
|
||||||
*
|
|
||||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
|
||||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
|
||||||
*
|
|
||||||
* This is the version for resolves-in-a-thread.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
|
|
||||||
struct Curl_dns_entry **entry)
|
|
||||||
{
|
|
||||||
return thread_wait_resolv(data, entry, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_is_resolved() is called repeatedly to check if a previous
|
|
||||||
* name resolve request has completed. It should also make sure to time-out if
|
|
||||||
* the operation seems to take too long.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
|
||||||
struct Curl_dns_entry **entry)
|
|
||||||
{
|
|
||||||
struct thread_data *td = data->state.async.tdata;
|
|
||||||
int done = 0;
|
|
||||||
|
|
||||||
DEBUGASSERT(entry);
|
|
||||||
*entry = NULL;
|
|
||||||
|
|
||||||
if(!td) {
|
|
||||||
DEBUGASSERT(td);
|
|
||||||
return CURLE_COULDNT_RESOLVE_HOST;
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_mutex_acquire(td->tsd.mtx);
|
|
||||||
done = td->tsd.done;
|
|
||||||
Curl_mutex_release(td->tsd.mtx);
|
|
||||||
|
|
||||||
if(done) {
|
|
||||||
getaddrinfo_complete(data);
|
|
||||||
|
|
||||||
if(!data->state.async.dns) {
|
|
||||||
CURLcode result = Curl_resolver_error(data);
|
|
||||||
destroy_async_data(&data->state.async);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
destroy_async_data(&data->state.async);
|
|
||||||
*entry = data->state.async.dns;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* poll for name lookup done with exponential backoff up to 250ms */
|
|
||||||
/* should be fine even if this converts to 32 bit */
|
|
||||||
timediff_t elapsed = Curl_timediff(Curl_now(),
|
|
||||||
data->progress.t_startsingle);
|
|
||||||
if(elapsed < 0)
|
|
||||||
elapsed = 0;
|
|
||||||
|
|
||||||
if(td->poll_interval == 0)
|
|
||||||
/* Start at 1ms poll interval */
|
|
||||||
td->poll_interval = 1;
|
|
||||||
else if(elapsed >= td->interval_end)
|
|
||||||
/* Back-off exponentially if last interval expired */
|
|
||||||
td->poll_interval *= 2;
|
|
||||||
|
|
||||||
if(td->poll_interval > 250)
|
|
||||||
td->poll_interval = 250;
|
|
||||||
|
|
||||||
td->interval_end = elapsed + td->poll_interval;
|
|
||||||
Curl_expire(data, td->poll_interval, EXPIRE_ASYNC_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
|
||||||
{
|
|
||||||
int ret_val = 0;
|
|
||||||
timediff_t milli;
|
|
||||||
timediff_t ms;
|
|
||||||
struct resdata *reslv = (struct resdata *)data->state.async.resolver;
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
struct thread_data *td = data->state.async.tdata;
|
|
||||||
#else
|
|
||||||
(void)socks;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
if(td) {
|
|
||||||
/* return read fd to client for polling the DNS resolution status */
|
|
||||||
socks[0] = td->tsd.sock_pair[0];
|
|
||||||
td->tsd.data = data;
|
|
||||||
ret_val = GETSOCK_READSOCK(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#endif
|
|
||||||
ms = Curl_timediff(Curl_now(), reslv->start);
|
|
||||||
if(ms < 3)
|
|
||||||
milli = 0;
|
|
||||||
else if(ms <= 50)
|
|
||||||
milli = ms/3;
|
|
||||||
else if(ms <= 250)
|
|
||||||
milli = 50;
|
|
||||||
else
|
|
||||||
milli = 200;
|
|
||||||
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
|
||||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return ret_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef HAVE_GETADDRINFO
|
|
||||||
/*
|
|
||||||
* Curl_getaddrinfo() - for platforms without getaddrinfo
|
|
||||||
*/
|
|
||||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
|
||||||
const char *hostname,
|
|
||||||
int port,
|
|
||||||
int *waitp)
|
|
||||||
{
|
|
||||||
struct resdata *reslv = (struct resdata *)data->state.async.resolver;
|
|
||||||
|
|
||||||
*waitp = 0; /* default to synchronous response */
|
|
||||||
|
|
||||||
reslv->start = Curl_now();
|
|
||||||
|
|
||||||
/* fire up a new resolver thread! */
|
|
||||||
if(init_resolve_thread(data, hostname, port, NULL)) {
|
|
||||||
*waitp = 1; /* expect asynchronous response */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
failf(data, "getaddrinfo() thread failed");
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !HAVE_GETADDRINFO */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_getaddrinfo() - for getaddrinfo
|
|
||||||
*/
|
|
||||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
|
||||||
const char *hostname,
|
|
||||||
int port,
|
|
||||||
int *waitp)
|
|
||||||
{
|
|
||||||
struct addrinfo hints;
|
|
||||||
int pf = PF_INET;
|
|
||||||
struct resdata *reslv = (struct resdata *)data->state.async.resolver;
|
|
||||||
|
|
||||||
*waitp = 0; /* default to synchronous response */
|
|
||||||
|
|
||||||
#ifdef CURLRES_IPV6
|
|
||||||
if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
|
|
||||||
/* The stack seems to be IPv6-enabled */
|
|
||||||
pf = PF_UNSPEC;
|
|
||||||
#endif /* CURLRES_IPV6 */
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_family = pf;
|
|
||||||
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
|
|
||||||
SOCK_STREAM : SOCK_DGRAM;
|
|
||||||
|
|
||||||
reslv->start = Curl_now();
|
|
||||||
/* fire up a new resolver thread! */
|
|
||||||
if(init_resolve_thread(data, hostname, port, &hints)) {
|
|
||||||
*waitp = 1; /* expect asynchronous response */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
failf(data, "getaddrinfo() thread failed to start");
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !HAVE_GETADDRINFO */
|
|
||||||
|
|
||||||
CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
|
||||||
char *servers)
|
|
||||||
{
|
|
||||||
(void)data;
|
|
||||||
(void)servers;
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
|
||||||
const char *interf)
|
|
||||||
{
|
|
||||||
(void)data;
|
|
||||||
(void)interf;
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
|
||||||
const char *local_ip4)
|
|
||||||
{
|
|
||||||
(void)data;
|
|
||||||
(void)local_ip4;
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
|
||||||
const char *local_ip6)
|
|
||||||
{
|
|
||||||
(void)data;
|
|
||||||
(void)local_ip6;
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CURLRES_THREADED */
|
|
|
@ -1,184 +0,0 @@
|
||||||
#ifndef HEADER_CURL_ASYN_H
|
|
||||||
#define HEADER_CURL_ASYN_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
#include "curl_addrinfo.h"
|
|
||||||
|
|
||||||
struct addrinfo;
|
|
||||||
struct hostent;
|
|
||||||
struct Curl_easy;
|
|
||||||
struct connectdata;
|
|
||||||
struct Curl_dns_entry;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This header defines all functions in the internal asynch resolver interface.
|
|
||||||
* All asynch resolvers need to provide these functions.
|
|
||||||
* asyn-ares.c and asyn-thread.c are the current implementations of asynch
|
|
||||||
* resolver backends.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_global_init()
|
|
||||||
*
|
|
||||||
* Called from curl_global_init() to initialize global resolver environment.
|
|
||||||
* Returning anything else than CURLE_OK fails curl_global_init().
|
|
||||||
*/
|
|
||||||
int Curl_resolver_global_init(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_global_cleanup()
|
|
||||||
* Called from curl_global_cleanup() to destroy global resolver environment.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_global_cleanup(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_init()
|
|
||||||
* Called from curl_easy_init() -> Curl_open() to initialize resolver
|
|
||||||
* URL-state specific environment ('resolver' member of the UrlState
|
|
||||||
* structure). Should fill the passed pointer by the initialized handler.
|
|
||||||
* Returning anything else than CURLE_OK fails curl_easy_init() with the
|
|
||||||
* correspondent code.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_cleanup()
|
|
||||||
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
|
|
||||||
* URL-state specific environment ('resolver' member of the UrlState
|
|
||||||
* structure). Should destroy the handler and free all resources connected to
|
|
||||||
* it.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_cleanup(void *resolver);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_duphandle()
|
|
||||||
* Called from curl_easy_duphandle() to duplicate resolver URL-state specific
|
|
||||||
* environment ('resolver' member of the UrlState structure). Should
|
|
||||||
* duplicate the 'from' handle and pass the resulting handle to the 'to'
|
|
||||||
* pointer. Returning anything else than CURLE_OK causes failed
|
|
||||||
* curl_easy_duphandle() call.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to,
|
|
||||||
void *from);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_cancel().
|
|
||||||
*
|
|
||||||
* It is called from inside other functions to cancel currently performing
|
|
||||||
* resolver request. Should also free any temporary resources allocated to
|
|
||||||
* perform a request. This never waits for resolver threads to complete.
|
|
||||||
*
|
|
||||||
* It is safe to call this when conn is in any state.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_cancel(struct Curl_easy *data);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_kill().
|
|
||||||
*
|
|
||||||
* This acts like Curl_resolver_cancel() except it will block until any threads
|
|
||||||
* associated with the resolver are complete. This never blocks for resolvers
|
|
||||||
* that do not use threads. This is intended to be the "last chance" function
|
|
||||||
* that cleans up an in-progress resolver completely (before its owner is about
|
|
||||||
* to die).
|
|
||||||
*
|
|
||||||
* It is safe to call this when conn is in any state.
|
|
||||||
*/
|
|
||||||
void Curl_resolver_kill(struct Curl_easy *data);
|
|
||||||
|
|
||||||
/* Curl_resolver_getsock()
|
|
||||||
*
|
|
||||||
* This function is called from the multi_getsock() function. 'sock' is a
|
|
||||||
* pointer to an array to hold the file descriptors, with 'numsock' being the
|
|
||||||
* size of that array (in number of entries). This function is supposed to
|
|
||||||
* return bitmask indicating what file descriptors (referring to array indexes
|
|
||||||
* in the 'sock' array) to wait for, read/write.
|
|
||||||
*/
|
|
||||||
int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *sock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_is_resolved()
|
|
||||||
*
|
|
||||||
* Called repeatedly to check if a previous name resolve request has
|
|
||||||
* completed. It should also make sure to time-out if the operation seems to
|
|
||||||
* take too long.
|
|
||||||
*
|
|
||||||
* Returns normal CURLcode errors.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
|
||||||
struct Curl_dns_entry **dns);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_wait_resolv()
|
|
||||||
*
|
|
||||||
* Waits for a resolve to finish. This function should be avoided since using
|
|
||||||
* this risk getting the multi interface to "hang".
|
|
||||||
*
|
|
||||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
|
||||||
*
|
|
||||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
|
||||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
|
|
||||||
struct Curl_dns_entry **dnsentry);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_resolver_getaddrinfo() - when using this resolver
|
|
||||||
*
|
|
||||||
* Returns name information about the given hostname and port number. If
|
|
||||||
* successful, the 'hostent' is returned and the fourth argument will point to
|
|
||||||
* memory we need to free after use. That memory *MUST* be freed with
|
|
||||||
* Curl_freeaddrinfo(), nothing else.
|
|
||||||
*
|
|
||||||
* Each resolver backend must of course make sure to return data in the
|
|
||||||
* correct format to comply with this.
|
|
||||||
*/
|
|
||||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
|
||||||
const char *hostname,
|
|
||||||
int port,
|
|
||||||
int *waitp);
|
|
||||||
|
|
||||||
#ifndef CURLRES_ASYNCH
|
|
||||||
/* convert these functions if an asynch resolver isn't used */
|
|
||||||
#define Curl_resolver_cancel(x) Curl_nop_stmt
|
|
||||||
#define Curl_resolver_kill(x) Curl_nop_stmt
|
|
||||||
#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
|
||||||
#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
|
|
||||||
#define Curl_resolver_duphandle(x,y,z) CURLE_OK
|
|
||||||
#define Curl_resolver_init(x,y) CURLE_OK
|
|
||||||
#define Curl_resolver_global_init() CURLE_OK
|
|
||||||
#define Curl_resolver_global_cleanup() Curl_nop_stmt
|
|
||||||
#define Curl_resolver_cleanup(x) Curl_nop_stmt
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CURLRES_ASYNCH
|
|
||||||
#define Curl_resolver_asynch() 1
|
|
||||||
#else
|
|
||||||
#define Curl_resolver_asynch() 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/********** end of generic resolver interface functions *****************/
|
|
||||||
#endif /* HEADER_CURL_ASYN_H */
|
|
|
@ -1,291 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/* Base64 encoding/decoding */
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \
|
|
||||||
!defined(CURL_DISABLE_LDAP) || \
|
|
||||||
!defined(CURL_DISABLE_SMTP) || \
|
|
||||||
!defined(CURL_DISABLE_POP3) || \
|
|
||||||
!defined(CURL_DISABLE_IMAP) || \
|
|
||||||
!defined(CURL_DISABLE_DOH) || defined(USE_SSL)
|
|
||||||
|
|
||||||
#include "urldata.h" /* for the Curl_easy definition */
|
|
||||||
#include "warnless.h"
|
|
||||||
#include "curl_base64.h"
|
|
||||||
|
|
||||||
/* The last 2 #include files should be in this order */
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
/* ---- Base64 Encoding/Decoding Table --- */
|
|
||||||
/* Padding character string starts at offset 64. */
|
|
||||||
static const char base64[]=
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
||||||
|
|
||||||
/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648
|
|
||||||
section 5 */
|
|
||||||
static const char base64url[]=
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
||||||
|
|
||||||
static const unsigned char decodetable[] =
|
|
||||||
{ 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
|
||||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28,
|
|
||||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
|
||||||
48, 49, 50, 51 };
|
|
||||||
/*
|
|
||||||
* Curl_base64_decode()
|
|
||||||
*
|
|
||||||
* Given a base64 NUL-terminated string at src, decode it and return a
|
|
||||||
* pointer in *outptr to a newly allocated memory area holding decoded
|
|
||||||
* data. Size of decoded data is returned in variable pointed by outlen.
|
|
||||||
*
|
|
||||||
* Returns CURLE_OK on success, otherwise specific error code. Function
|
|
||||||
* output shall not be considered valid unless CURLE_OK is returned.
|
|
||||||
*
|
|
||||||
* When decoded data length is 0, returns NULL in *outptr.
|
|
||||||
*
|
|
||||||
* @unittest: 1302
|
|
||||||
*/
|
|
||||||
CURLcode Curl_base64_decode(const char *src,
|
|
||||||
unsigned char **outptr, size_t *outlen)
|
|
||||||
{
|
|
||||||
size_t srclen = 0;
|
|
||||||
size_t padding = 0;
|
|
||||||
size_t i;
|
|
||||||
size_t numQuantums;
|
|
||||||
size_t fullQuantums;
|
|
||||||
size_t rawlen = 0;
|
|
||||||
unsigned char *pos;
|
|
||||||
unsigned char *newstr;
|
|
||||||
unsigned char lookup[256];
|
|
||||||
|
|
||||||
*outptr = NULL;
|
|
||||||
*outlen = 0;
|
|
||||||
srclen = strlen(src);
|
|
||||||
|
|
||||||
/* Check the length of the input string is valid */
|
|
||||||
if(!srclen || srclen % 4)
|
|
||||||
return CURLE_BAD_CONTENT_ENCODING;
|
|
||||||
|
|
||||||
/* srclen is at least 4 here */
|
|
||||||
while(src[srclen - 1 - padding] == '=') {
|
|
||||||
/* count padding characters */
|
|
||||||
padding++;
|
|
||||||
/* A maximum of two = padding characters is allowed */
|
|
||||||
if(padding > 2)
|
|
||||||
return CURLE_BAD_CONTENT_ENCODING;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the number of quantums */
|
|
||||||
numQuantums = srclen / 4;
|
|
||||||
fullQuantums = numQuantums - (padding ? 1 : 0);
|
|
||||||
|
|
||||||
/* Calculate the size of the decoded string */
|
|
||||||
rawlen = (numQuantums * 3) - padding;
|
|
||||||
|
|
||||||
/* Allocate our buffer including room for a null-terminator */
|
|
||||||
newstr = malloc(rawlen + 1);
|
|
||||||
if(!newstr)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
pos = newstr;
|
|
||||||
|
|
||||||
memset(lookup, 0xff, sizeof(lookup));
|
|
||||||
memcpy(&lookup['+'], decodetable, sizeof(decodetable));
|
|
||||||
/* replaces
|
|
||||||
{
|
|
||||||
unsigned char c;
|
|
||||||
const unsigned char *p = (const unsigned char *)base64;
|
|
||||||
for(c = 0; *p; c++, p++)
|
|
||||||
lookup[*p] = c;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Decode the complete quantums first */
|
|
||||||
for(i = 0; i < fullQuantums; i++) {
|
|
||||||
unsigned char val;
|
|
||||||
unsigned int x = 0;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
for(j = 0; j < 4; j++) {
|
|
||||||
val = lookup[(unsigned char)*src++];
|
|
||||||
if(val == 0xff) /* bad symbol */
|
|
||||||
goto bad;
|
|
||||||
x = (x << 6) | val;
|
|
||||||
}
|
|
||||||
pos[2] = x & 0xff;
|
|
||||||
pos[1] = (x >> 8) & 0xff;
|
|
||||||
pos[0] = (x >> 16) & 0xff;
|
|
||||||
pos += 3;
|
|
||||||
}
|
|
||||||
if(padding) {
|
|
||||||
/* this means either 8 or 16 bits output */
|
|
||||||
unsigned char val;
|
|
||||||
unsigned int x = 0;
|
|
||||||
int j;
|
|
||||||
size_t padc = 0;
|
|
||||||
for(j = 0; j < 4; j++) {
|
|
||||||
if(*src == '=') {
|
|
||||||
x <<= 6;
|
|
||||||
src++;
|
|
||||||
if(++padc > padding)
|
|
||||||
/* this is a badly placed '=' symbol! */
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val = lookup[(unsigned char)*src++];
|
|
||||||
if(val == 0xff) /* bad symbol */
|
|
||||||
goto bad;
|
|
||||||
x = (x << 6) | val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(padding == 1)
|
|
||||||
pos[1] = (x >> 8) & 0xff;
|
|
||||||
pos[0] = (x >> 16) & 0xff;
|
|
||||||
pos += 3 - padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero terminate */
|
|
||||||
*pos = '\0';
|
|
||||||
|
|
||||||
/* Return the decoded data */
|
|
||||||
*outptr = newstr;
|
|
||||||
*outlen = rawlen;
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
bad:
|
|
||||||
free(newstr);
|
|
||||||
return CURLE_BAD_CONTENT_ENCODING;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode base64_encode(const char *table64,
|
|
||||||
const char *inputbuff, size_t insize,
|
|
||||||
char **outptr, size_t *outlen)
|
|
||||||
{
|
|
||||||
char *output;
|
|
||||||
char *base64data;
|
|
||||||
const unsigned char *in = (unsigned char *)inputbuff;
|
|
||||||
const char *padstr = &table64[64]; /* Point to padding string. */
|
|
||||||
|
|
||||||
*outptr = NULL;
|
|
||||||
*outlen = 0;
|
|
||||||
|
|
||||||
if(!insize)
|
|
||||||
insize = strlen(inputbuff);
|
|
||||||
|
|
||||||
#if SIZEOF_SIZE_T == 4
|
|
||||||
if(insize > UINT_MAX/4)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
base64data = output = malloc((insize + 2) / 3 * 4 + 1);
|
|
||||||
if(!output)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
while(insize >= 3) {
|
|
||||||
*output++ = table64[ in[0] >> 2 ];
|
|
||||||
*output++ = table64[ ((in[0] & 0x03) << 4) | (in[1] >> 4) ];
|
|
||||||
*output++ = table64[ ((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6) ];
|
|
||||||
*output++ = table64[ in[2] & 0x3F ];
|
|
||||||
insize -= 3;
|
|
||||||
in += 3;
|
|
||||||
}
|
|
||||||
if(insize) {
|
|
||||||
/* this is only one or two bytes now */
|
|
||||||
*output++ = table64[ in[0] >> 2 ];
|
|
||||||
if(insize == 1) {
|
|
||||||
*output++ = table64[ ((in[0] & 0x03) << 4) ];
|
|
||||||
if(*padstr) {
|
|
||||||
*output++ = *padstr;
|
|
||||||
*output++ = *padstr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* insize == 2 */
|
|
||||||
*output++ = table64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4) ];
|
|
||||||
*output++ = table64[ ((in[1] & 0x0F) << 2) ];
|
|
||||||
if(*padstr)
|
|
||||||
*output++ = *padstr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero terminate */
|
|
||||||
*output = '\0';
|
|
||||||
|
|
||||||
/* Return the pointer to the new data (allocated memory) */
|
|
||||||
*outptr = base64data;
|
|
||||||
|
|
||||||
/* Return the length of the new data */
|
|
||||||
*outlen = output - base64data;
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_base64_encode()
|
|
||||||
*
|
|
||||||
* Given a pointer to an input buffer and an input size, encode it and
|
|
||||||
* return a pointer in *outptr to a newly allocated memory area holding
|
|
||||||
* encoded data. Size of encoded data is returned in variable pointed by
|
|
||||||
* outlen.
|
|
||||||
*
|
|
||||||
* Input length of 0 indicates input buffer holds a NUL-terminated string.
|
|
||||||
*
|
|
||||||
* Returns CURLE_OK on success, otherwise specific error code. Function
|
|
||||||
* output shall not be considered valid unless CURLE_OK is returned.
|
|
||||||
*
|
|
||||||
* @unittest: 1302
|
|
||||||
*/
|
|
||||||
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
|
|
||||||
char **outptr, size_t *outlen)
|
|
||||||
{
|
|
||||||
return base64_encode(base64, inputbuff, insize, outptr, outlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_base64url_encode()
|
|
||||||
*
|
|
||||||
* Given a pointer to an input buffer and an input size, encode it and
|
|
||||||
* return a pointer in *outptr to a newly allocated memory area holding
|
|
||||||
* encoded data. Size of encoded data is returned in variable pointed by
|
|
||||||
* outlen.
|
|
||||||
*
|
|
||||||
* Input length of 0 indicates input buffer holds a NUL-terminated string.
|
|
||||||
*
|
|
||||||
* Returns CURLE_OK on success, otherwise specific error code. Function
|
|
||||||
* output shall not be considered valid unless CURLE_OK is returned.
|
|
||||||
*
|
|
||||||
* @unittest: 1302
|
|
||||||
*/
|
|
||||||
CURLcode Curl_base64url_encode(const char *inputbuff, size_t insize,
|
|
||||||
char **outptr, size_t *outlen)
|
|
||||||
{
|
|
||||||
return base64_encode(base64url, inputbuff, insize, outptr, outlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* no users so disabled */
|
|
|
@ -1,129 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
#include "urldata.h"
|
|
||||||
#include "bufref.h"
|
|
||||||
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
#define SIGNATURE 0x5c48e9b2 /* Random pattern. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Init a bufref struct.
|
|
||||||
*/
|
|
||||||
void Curl_bufref_init(struct bufref *br)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(br);
|
|
||||||
br->dtor = NULL;
|
|
||||||
br->ptr = NULL;
|
|
||||||
br->len = 0;
|
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
br->signature = SIGNATURE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Free the buffer and re-init the necessary fields. It doesn't touch the
|
|
||||||
* 'signature' field and thus this buffer reference can be reused.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Curl_bufref_free(struct bufref *br)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(br);
|
|
||||||
DEBUGASSERT(br->signature == SIGNATURE);
|
|
||||||
DEBUGASSERT(br->ptr || !br->len);
|
|
||||||
|
|
||||||
if(br->ptr && br->dtor)
|
|
||||||
br->dtor((void *) br->ptr);
|
|
||||||
|
|
||||||
br->dtor = NULL;
|
|
||||||
br->ptr = NULL;
|
|
||||||
br->len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the buffer reference to new values. The previously referenced buffer
|
|
||||||
* is released before assignment.
|
|
||||||
*/
|
|
||||||
void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
|
|
||||||
void (*dtor)(void *))
|
|
||||||
{
|
|
||||||
DEBUGASSERT(ptr || !len);
|
|
||||||
DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH);
|
|
||||||
|
|
||||||
Curl_bufref_free(br);
|
|
||||||
br->ptr = (const unsigned char *) ptr;
|
|
||||||
br->len = len;
|
|
||||||
br->dtor = dtor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a pointer to the referenced buffer.
|
|
||||||
*/
|
|
||||||
const unsigned char *Curl_bufref_ptr(const struct bufref *br)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(br);
|
|
||||||
DEBUGASSERT(br->signature == SIGNATURE);
|
|
||||||
DEBUGASSERT(br->ptr || !br->len);
|
|
||||||
|
|
||||||
return br->ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the length of the referenced buffer data.
|
|
||||||
*/
|
|
||||||
size_t Curl_bufref_len(const struct bufref *br)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(br);
|
|
||||||
DEBUGASSERT(br->signature == SIGNATURE);
|
|
||||||
DEBUGASSERT(br->ptr || !br->len);
|
|
||||||
|
|
||||||
return br->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len)
|
|
||||||
{
|
|
||||||
unsigned char *cpy = NULL;
|
|
||||||
|
|
||||||
DEBUGASSERT(br);
|
|
||||||
DEBUGASSERT(br->signature == SIGNATURE);
|
|
||||||
DEBUGASSERT(br->ptr || !br->len);
|
|
||||||
DEBUGASSERT(ptr || !len);
|
|
||||||
DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH);
|
|
||||||
|
|
||||||
if(ptr) {
|
|
||||||
cpy = malloc(len + 1);
|
|
||||||
if(!cpy)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
if(len)
|
|
||||||
memcpy(cpy, ptr, len);
|
|
||||||
cpy[len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_bufref_set(br, cpy, len, curl_free);
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
#ifndef HEADER_CURL_BUFREF_H
|
|
||||||
#define HEADER_CURL_BUFREF_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generic buffer reference.
|
|
||||||
*/
|
|
||||||
struct bufref {
|
|
||||||
void (*dtor)(void *); /* Associated destructor. */
|
|
||||||
const unsigned char *ptr; /* Referenced data buffer. */
|
|
||||||
size_t len; /* The data size in bytes. */
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
int signature; /* Detect API use mistakes. */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void Curl_bufref_init(struct bufref *br);
|
|
||||||
void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
|
|
||||||
void (*dtor)(void *));
|
|
||||||
const unsigned char *Curl_bufref_ptr(const struct bufref *br);
|
|
||||||
size_t Curl_bufref_len(const struct bufref *br);
|
|
||||||
CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len);
|
|
||||||
void Curl_bufref_free(struct bufref *br);
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,60 +0,0 @@
|
||||||
#ifndef HEADER_CURL_HYPER_H
|
|
||||||
#define HEADER_CURL_HYPER_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER)
|
|
||||||
|
|
||||||
#include <hyper.h>
|
|
||||||
|
|
||||||
/* per-transfer data for the Hyper backend */
|
|
||||||
struct hyptransfer {
|
|
||||||
hyper_waker *write_waker;
|
|
||||||
hyper_waker *read_waker;
|
|
||||||
const hyper_executor *exec;
|
|
||||||
hyper_task *endtask;
|
|
||||||
hyper_waker *exp100_waker;
|
|
||||||
hyper_waker *send_body_waker;
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
|
|
||||||
uint8_t *buf, size_t buflen);
|
|
||||||
size_t Curl_hyper_send(void *userp, hyper_context *ctx,
|
|
||||||
const uint8_t *buf, size_t buflen);
|
|
||||||
CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int *didwhat,
|
|
||||||
bool *done,
|
|
||||||
int select_res);
|
|
||||||
|
|
||||||
CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers,
|
|
||||||
const char *line);
|
|
||||||
void Curl_hyper_done(struct Curl_easy *);
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define Curl_hyper_done(x)
|
|
||||||
|
|
||||||
#endif /* !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER) */
|
|
||||||
#endif /* HEADER_CURL_HYPER_H */
|
|
|
@ -1,569 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
|
|
||||||
|
|
||||||
#include "urldata.h"
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include "curl_log.h"
|
|
||||||
#include "cfilters.h"
|
|
||||||
#include "connect.h"
|
|
||||||
#include "multiif.h"
|
|
||||||
#include "cf-https-connect.h"
|
|
||||||
#include "http2.h"
|
|
||||||
#include "vquic/vquic.h"
|
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CF_HC_INIT,
|
|
||||||
CF_HC_CONNECT,
|
|
||||||
CF_HC_SUCCESS,
|
|
||||||
CF_HC_FAILURE
|
|
||||||
} cf_hc_state;
|
|
||||||
|
|
||||||
struct cf_hc_baller {
|
|
||||||
const char *name;
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
CURLcode result;
|
|
||||||
struct curltime started;
|
|
||||||
int reply_ms;
|
|
||||||
bool enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void cf_hc_baller_reset(struct cf_hc_baller *b,
|
|
||||||
struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
if(b->cf) {
|
|
||||||
Curl_conn_cf_close(b->cf, data);
|
|
||||||
Curl_conn_cf_discard_chain(&b->cf, data);
|
|
||||||
b->cf = NULL;
|
|
||||||
}
|
|
||||||
b->result = CURLE_OK;
|
|
||||||
b->reply_ms = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool cf_hc_baller_is_active(struct cf_hc_baller *b)
|
|
||||||
{
|
|
||||||
return b->enabled && b->cf && !b->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool cf_hc_baller_has_started(struct cf_hc_baller *b)
|
|
||||||
{
|
|
||||||
return !!b->cf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cf_hc_baller_reply_ms(struct cf_hc_baller *b,
|
|
||||||
struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
if(b->reply_ms < 0)
|
|
||||||
b->cf->cft->query(b->cf, data, CF_QUERY_CONNECT_REPLY_MS,
|
|
||||||
&b->reply_ms, NULL);
|
|
||||||
return b->reply_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool cf_hc_baller_data_pending(struct cf_hc_baller *b,
|
|
||||||
const struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
return b->cf && !b->result && b->cf->cft->has_data_pending(b->cf, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cf_hc_ctx {
|
|
||||||
cf_hc_state state;
|
|
||||||
const struct Curl_dns_entry *remotehost;
|
|
||||||
struct curltime started; /* when connect started */
|
|
||||||
CURLcode result; /* overall result */
|
|
||||||
struct cf_hc_baller h3_baller;
|
|
||||||
struct cf_hc_baller h21_baller;
|
|
||||||
int soft_eyeballs_timeout_ms;
|
|
||||||
int hard_eyeballs_timeout_ms;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void cf_hc_baller_init(struct cf_hc_baller *b,
|
|
||||||
struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
const char *name,
|
|
||||||
int transport)
|
|
||||||
{
|
|
||||||
struct cf_hc_ctx *ctx = cf->ctx;
|
|
||||||
struct Curl_cfilter *save = cf->next;
|
|
||||||
|
|
||||||
b->name = name;
|
|
||||||
cf->next = NULL;
|
|
||||||
b->started = Curl_now();
|
|
||||||
b->result = Curl_cf_setup_insert_after(cf, data, ctx->remotehost,
|
|
||||||
transport, CURL_CF_SSL_ENABLE);
|
|
||||||
b->cf = cf->next;
|
|
||||||
cf->next = save;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode cf_hc_baller_connect(struct cf_hc_baller *b,
|
|
||||||
struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool *done)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *save = cf->next;
|
|
||||||
|
|
||||||
cf->next = b->cf;
|
|
||||||
b->result = Curl_conn_cf_connect(cf->next, data, FALSE, done);
|
|
||||||
b->cf = cf->next; /* it might mutate */
|
|
||||||
cf->next = save;
|
|
||||||
return b->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cf_hc_reset(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
struct cf_hc_ctx *ctx = cf->ctx;
|
|
||||||
|
|
||||||
if(ctx) {
|
|
||||||
cf_hc_baller_reset(&ctx->h3_baller, data);
|
|
||||||
cf_hc_baller_reset(&ctx->h21_baller, data);
|
|
||||||
ctx->state = CF_HC_INIT;
|
|
||||||
ctx->result = CURLE_OK;
|
|
||||||
ctx->hard_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout;
|
|
||||||
ctx->soft_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode baller_connected(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
struct cf_hc_baller *winner)
|
|
||||||
{
|
|
||||||
struct cf_hc_ctx *ctx = cf->ctx;
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
DEBUGASSERT(winner->cf);
|
|
||||||
if(winner != &ctx->h3_baller)
|
|
||||||
cf_hc_baller_reset(&ctx->h3_baller, data);
|
|
||||||
if(winner != &ctx->h21_baller)
|
|
||||||
cf_hc_baller_reset(&ctx->h21_baller, data);
|
|
||||||
|
|
||||||
DEBUGF(LOG_CF(data, cf, "connect+handshake %s: %dms, 1st data: %dms",
|
|
||||||
winner->name, (int)Curl_timediff(Curl_now(), winner->started),
|
|
||||||
cf_hc_baller_reply_ms(winner, data)));
|
|
||||||
cf->next = winner->cf;
|
|
||||||
winner->cf = NULL;
|
|
||||||
|
|
||||||
switch(cf->conn->alpn) {
|
|
||||||
case CURL_HTTP_VERSION_3:
|
|
||||||
infof(data, "using HTTP/3");
|
|
||||||
break;
|
|
||||||
case CURL_HTTP_VERSION_2:
|
|
||||||
#ifdef USE_NGHTTP2
|
|
||||||
/* Using nghttp2, we add the filter "below" us, so when the conn
|
|
||||||
* closes, we tear it down for a fresh reconnect */
|
|
||||||
result = Curl_http2_switch_at(cf, data);
|
|
||||||
if(result) {
|
|
||||||
ctx->state = CF_HC_FAILURE;
|
|
||||||
ctx->result = result;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
infof(data, "using HTTP/2");
|
|
||||||
break;
|
|
||||||
case CURL_HTTP_VERSION_1_1:
|
|
||||||
infof(data, "using HTTP/1.1");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
infof(data, "using HTTP/1.x");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ctx->state = CF_HC_SUCCESS;
|
|
||||||
cf->connected = TRUE;
|
|
||||||
Curl_conn_cf_cntrl(cf->next, data, TRUE,
|
|
||||||
CF_CTRL_CONN_INFO_UPDATE, 0, NULL);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool time_to_start_h21(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
struct curltime now)
|
|
||||||
{
|
|
||||||
struct cf_hc_ctx *ctx = cf->ctx;
|
|
||||||
timediff_t elapsed_ms;
|
|
||||||
|
|
||||||
if(!ctx->h21_baller.enabled || cf_hc_baller_has_started(&ctx->h21_baller))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if(!ctx->h3_baller.enabled || !cf_hc_baller_is_active(&ctx->h3_baller))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
elapsed_ms = Curl_timediff(now, ctx->started);
|
|
||||||
if(elapsed_ms >= ctx->hard_eyeballs_timeout_ms) {
|
|
||||||
DEBUGF(LOG_CF(data, cf, "hard timeout of %dms reached, starting h21",
|
|
||||||
ctx->hard_eyeballs_timeout_ms));
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(elapsed_ms >= ctx->soft_eyeballs_timeout_ms) {
|
|
||||||
if(cf_hc_baller_reply_ms(&ctx->h3_baller, data) < 0) {
|
|
||||||
DEBUGF(LOG_CF(data, cf, "soft timeout of %dms reached, h3 has not "
|
|
||||||
"seen any data, starting h21",
|
|
||||||
ctx->soft_eyeballs_timeout_ms));
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
/* set the effective hard timeout again */
|
|
||||||
Curl_expire(data, ctx->hard_eyeballs_timeout_ms - elapsed_ms,
|
|
||||||
EXPIRE_ALPN_EYEBALLS);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool blocking, bool *done)
|
|
||||||
{
|
|
||||||
struct cf_hc_ctx *ctx = cf->ctx;
|
|
||||||
struct curltime now;
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
(void)blocking;
|
|
||||||
if(cf->connected) {
|
|
||||||
*done = TRUE;
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
*done = FALSE;
|
|
||||||
now = Curl_now();
|
|
||||||
switch(ctx->state) {
|
|
||||||
case CF_HC_INIT:
|
|
||||||
DEBUGASSERT(!ctx->h3_baller.cf);
|
|
||||||
DEBUGASSERT(!ctx->h21_baller.cf);
|
|
||||||
DEBUGASSERT(!cf->next);
|
|
||||||
DEBUGF(LOG_CF(data, cf, "connect, init"));
|
|
||||||
ctx->started = now;
|
|
||||||
if(ctx->h3_baller.enabled) {
|
|
||||||
cf_hc_baller_init(&ctx->h3_baller, cf, data, "h3", TRNSPRT_QUIC);
|
|
||||||
if(ctx->h21_baller.enabled)
|
|
||||||
Curl_expire(data, ctx->soft_eyeballs_timeout_ms, EXPIRE_ALPN_EYEBALLS);
|
|
||||||
}
|
|
||||||
else if(ctx->h21_baller.enabled)
|
|
||||||
cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21",
|
|
||||||
cf->conn->transport);
|
|
||||||
ctx->state = CF_HC_CONNECT;
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
|
|
||||||
case CF_HC_CONNECT:
|
|
||||||
if(cf_hc_baller_is_active(&ctx->h3_baller)) {
|
|
||||||
result = cf_hc_baller_connect(&ctx->h3_baller, cf, data, done);
|
|
||||||
if(!result && *done) {
|
|
||||||
result = baller_connected(cf, data, &ctx->h3_baller);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(time_to_start_h21(cf, data, now)) {
|
|
||||||
cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21",
|
|
||||||
cf->conn->transport);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cf_hc_baller_is_active(&ctx->h21_baller)) {
|
|
||||||
DEBUGF(LOG_CF(data, cf, "connect, check h21"));
|
|
||||||
result = cf_hc_baller_connect(&ctx->h21_baller, cf, data, done);
|
|
||||||
if(!result && *done) {
|
|
||||||
result = baller_connected(cf, data, &ctx->h21_baller);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((!ctx->h3_baller.enabled || ctx->h3_baller.result) &&
|
|
||||||
(!ctx->h21_baller.enabled || ctx->h21_baller.result)) {
|
|
||||||
/* both failed or disabled. we give up */
|
|
||||||
DEBUGF(LOG_CF(data, cf, "connect, all failed"));
|
|
||||||
result = ctx->result = ctx->h3_baller.enabled?
|
|
||||||
ctx->h3_baller.result : ctx->h21_baller.result;
|
|
||||||
ctx->state = CF_HC_FAILURE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
result = CURLE_OK;
|
|
||||||
*done = FALSE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CF_HC_FAILURE:
|
|
||||||
result = ctx->result;
|
|
||||||
cf->connected = FALSE;
|
|
||||||
*done = FALSE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CF_HC_SUCCESS:
|
|
||||||
result = CURLE_OK;
|
|
||||||
cf->connected = TRUE;
|
|
||||||
*done = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
DEBUGF(LOG_CF(data, cf, "connect -> %d, done=%d", result, *done));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cf_hc_get_select_socks(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
curl_socket_t *socks)
|
|
||||||
{
|
|
||||||
struct cf_hc_ctx *ctx = cf->ctx;
|
|
||||||
size_t i, j, s;
|
|
||||||
int brc, rc = GETSOCK_BLANK;
|
|
||||||
curl_socket_t bsocks[MAX_SOCKSPEREASYHANDLE];
|
|
||||||
struct cf_hc_baller *ballers[2];
|
|
||||||
|
|
||||||
if(cf->connected)
|
|
||||||
return cf->next->cft->get_select_socks(cf->next, data, socks);
|
|
||||||
|
|
||||||
ballers[0] = &ctx->h3_baller;
|
|
||||||
ballers[1] = &ctx->h21_baller;
|
|
||||||
for(i = s = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
|
|
||||||
struct cf_hc_baller *b = ballers[i];
|
|
||||||
if(!cf_hc_baller_is_active(b))
|
|
||||||
continue;
|
|
||||||
brc = Curl_conn_cf_get_select_socks(b->cf, data, bsocks);
|
|
||||||
DEBUGF(LOG_CF(data, cf, "get_selected_socks(%s) -> %x", b->name, brc));
|
|
||||||
if(!brc)
|
|
||||||
continue;
|
|
||||||
for(j = 0; j < MAX_SOCKSPEREASYHANDLE && s < MAX_SOCKSPEREASYHANDLE; ++j) {
|
|
||||||
if((brc & GETSOCK_WRITESOCK(j)) || (brc & GETSOCK_READSOCK(j))) {
|
|
||||||
socks[s] = bsocks[j];
|
|
||||||
if(brc & GETSOCK_WRITESOCK(j))
|
|
||||||
rc |= GETSOCK_WRITESOCK(s);
|
|
||||||
if(brc & GETSOCK_READSOCK(j))
|
|
||||||
rc |= GETSOCK_READSOCK(s);
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUGF(LOG_CF(data, cf, "get_selected_socks -> %x", rc));
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool cf_hc_data_pending(struct Curl_cfilter *cf,
|
|
||||||
const struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
struct cf_hc_ctx *ctx = cf->ctx;
|
|
||||||
|
|
||||||
if(cf->connected)
|
|
||||||
return cf->next->cft->has_data_pending(cf->next, data);
|
|
||||||
|
|
||||||
DEBUGF(LOG_CF((struct Curl_easy *)data, cf, "data_pending"));
|
|
||||||
return cf_hc_baller_data_pending(&ctx->h3_baller, data)
|
|
||||||
|| cf_hc_baller_data_pending(&ctx->h21_baller, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct curltime get_max_baller_time(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
int query)
|
|
||||||
{
|
|
||||||
struct cf_hc_ctx *ctx = cf->ctx;
|
|
||||||
struct Curl_cfilter *cfb;
|
|
||||||
struct curltime t, tmax;
|
|
||||||
|
|
||||||
memset(&tmax, 0, sizeof(tmax));
|
|
||||||
memset(&t, 0, sizeof(t));
|
|
||||||
cfb = ctx->h21_baller.enabled? ctx->h21_baller.cf : NULL;
|
|
||||||
if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
|
|
||||||
if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
|
|
||||||
tmax = t;
|
|
||||||
}
|
|
||||||
memset(&t, 0, sizeof(t));
|
|
||||||
cfb = ctx->h3_baller.enabled? ctx->h3_baller.cf : NULL;
|
|
||||||
if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
|
|
||||||
if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
|
|
||||||
tmax = t;
|
|
||||||
}
|
|
||||||
return tmax;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode cf_hc_query(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
int query, int *pres1, void *pres2)
|
|
||||||
{
|
|
||||||
if(!cf->connected) {
|
|
||||||
switch(query) {
|
|
||||||
case CF_QUERY_TIMER_CONNECT: {
|
|
||||||
struct curltime *when = pres2;
|
|
||||||
*when = get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
case CF_QUERY_TIMER_APPCONNECT: {
|
|
||||||
struct curltime *when = pres2;
|
|
||||||
*when = get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT);
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cf->next?
|
|
||||||
cf->next->cft->query(cf->next, data, query, pres1, pres2) :
|
|
||||||
CURLE_UNKNOWN_OPTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cf_hc_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
DEBUGF(LOG_CF(data, cf, "close"));
|
|
||||||
cf_hc_reset(cf, data);
|
|
||||||
cf->connected = FALSE;
|
|
||||||
|
|
||||||
if(cf->next) {
|
|
||||||
cf->next->cft->close(cf->next, data);
|
|
||||||
Curl_conn_cf_discard_chain(&cf->next, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cf_hc_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
struct cf_hc_ctx *ctx = cf->ctx;
|
|
||||||
|
|
||||||
(void)data;
|
|
||||||
DEBUGF(LOG_CF(data, cf, "destroy"));
|
|
||||||
cf_hc_reset(cf, data);
|
|
||||||
Curl_safefree(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Curl_cftype Curl_cft_http_connect = {
|
|
||||||
"HTTPS-CONNECT",
|
|
||||||
0,
|
|
||||||
CURL_LOG_DEFAULT,
|
|
||||||
cf_hc_destroy,
|
|
||||||
cf_hc_connect,
|
|
||||||
cf_hc_close,
|
|
||||||
Curl_cf_def_get_host,
|
|
||||||
cf_hc_get_select_socks,
|
|
||||||
cf_hc_data_pending,
|
|
||||||
Curl_cf_def_send,
|
|
||||||
Curl_cf_def_recv,
|
|
||||||
Curl_cf_def_cntrl,
|
|
||||||
Curl_cf_def_conn_is_alive,
|
|
||||||
Curl_cf_def_conn_keep_alive,
|
|
||||||
cf_hc_query,
|
|
||||||
};
|
|
||||||
|
|
||||||
static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
const struct Curl_dns_entry *remotehost,
|
|
||||||
bool try_h3, bool try_h21)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf = NULL;
|
|
||||||
struct cf_hc_ctx *ctx;
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
(void)data;
|
|
||||||
ctx = calloc(sizeof(*ctx), 1);
|
|
||||||
if(!ctx) {
|
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ctx->remotehost = remotehost;
|
|
||||||
ctx->h3_baller.enabled = try_h3;
|
|
||||||
ctx->h21_baller.enabled = try_h21;
|
|
||||||
|
|
||||||
result = Curl_cf_create(&cf, &Curl_cft_http_connect, ctx);
|
|
||||||
if(result)
|
|
||||||
goto out;
|
|
||||||
ctx = NULL;
|
|
||||||
cf_hc_reset(cf, data);
|
|
||||||
|
|
||||||
out:
|
|
||||||
*pcf = result? NULL : cf;
|
|
||||||
free(ctx);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_cf_http_connect_add(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex,
|
|
||||||
const struct Curl_dns_entry *remotehost,
|
|
||||||
bool try_h3, bool try_h21)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
result = cf_hc_create(&cf, data, remotehost, try_h3, try_h21);
|
|
||||||
if(result)
|
|
||||||
goto out;
|
|
||||||
Curl_conn_cf_add(data, conn, sockindex, cf);
|
|
||||||
out:
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode
|
|
||||||
Curl_cf_http_connect_insert_after(struct Curl_cfilter *cf_at,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
const struct Curl_dns_entry *remotehost,
|
|
||||||
bool try_h3, bool try_h21)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
CURLcode result;
|
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
result = cf_hc_create(&cf, data, remotehost, try_h3, try_h21);
|
|
||||||
if(result)
|
|
||||||
goto out;
|
|
||||||
Curl_conn_cf_insert_after(cf_at, cf);
|
|
||||||
out:
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_cf_https_setup(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex,
|
|
||||||
const struct Curl_dns_entry *remotehost)
|
|
||||||
{
|
|
||||||
bool try_h3 = FALSE, try_h21 = TRUE; /* defaults, for now */
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
(void)sockindex;
|
|
||||||
(void)remotehost;
|
|
||||||
|
|
||||||
if(!conn->bits.tls_enable_alpn)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if(data->state.httpwant == CURL_HTTP_VERSION_3ONLY) {
|
|
||||||
result = Curl_conn_may_http3(data, conn);
|
|
||||||
if(result) /* can't do it */
|
|
||||||
goto out;
|
|
||||||
try_h3 = TRUE;
|
|
||||||
try_h21 = FALSE;
|
|
||||||
}
|
|
||||||
else if(data->state.httpwant >= CURL_HTTP_VERSION_3) {
|
|
||||||
/* We assume that silently not even trying H3 is ok here */
|
|
||||||
/* TODO: should we fail instead? */
|
|
||||||
try_h3 = (Curl_conn_may_http3(data, conn) == CURLE_OK);
|
|
||||||
try_h21 = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = Curl_cf_http_connect_add(data, conn, sockindex, remotehost,
|
|
||||||
try_h3, try_h21);
|
|
||||||
out:
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */
|
|
|
@ -1,58 +0,0 @@
|
||||||
#ifndef HEADER_CURL_CF_HTTP_H
|
|
||||||
#define HEADER_CURL_CF_HTTP_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
|
|
||||||
|
|
||||||
struct Curl_cfilter;
|
|
||||||
struct Curl_easy;
|
|
||||||
struct connectdata;
|
|
||||||
struct Curl_cftype;
|
|
||||||
struct Curl_dns_entry;
|
|
||||||
|
|
||||||
extern struct Curl_cftype Curl_cft_http_connect;
|
|
||||||
|
|
||||||
CURLcode Curl_cf_http_connect_add(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex,
|
|
||||||
const struct Curl_dns_entry *remotehost,
|
|
||||||
bool try_h3, bool try_h21);
|
|
||||||
|
|
||||||
CURLcode
|
|
||||||
Curl_cf_http_connect_insert_after(struct Curl_cfilter *cf_at,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
const struct Curl_dns_entry *remotehost,
|
|
||||||
bool try_h3, bool try_h21);
|
|
||||||
|
|
||||||
|
|
||||||
CURLcode Curl_cf_https_setup(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex,
|
|
||||||
const struct Curl_dns_entry *remotehost);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */
|
|
||||||
#endif /* HEADER_CURL_CF_HTTP_H */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,185 +0,0 @@
|
||||||
#ifndef HEADER_CURL_CF_SOCKET_H
|
|
||||||
#define HEADER_CURL_CF_SOCKET_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
|
|
||||||
#include "sockaddr.h"
|
|
||||||
|
|
||||||
struct Curl_addrinfo;
|
|
||||||
struct Curl_cfilter;
|
|
||||||
struct Curl_easy;
|
|
||||||
struct connectdata;
|
|
||||||
struct Curl_sockaddr_ex;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The Curl_sockaddr_ex structure is basically libcurl's external API
|
|
||||||
* curl_sockaddr structure with enough space available to directly hold any
|
|
||||||
* protocol-specific address structures. The variable declared here will be
|
|
||||||
* used to pass / receive data to/from the fopensocket callback if this has
|
|
||||||
* been set, before that, it is initialized from parameters.
|
|
||||||
*/
|
|
||||||
struct Curl_sockaddr_ex {
|
|
||||||
int family;
|
|
||||||
int socktype;
|
|
||||||
int protocol;
|
|
||||||
unsigned int addrlen;
|
|
||||||
union {
|
|
||||||
struct sockaddr addr;
|
|
||||||
struct Curl_sockaddr_storage buff;
|
|
||||||
} _sa_ex_u;
|
|
||||||
};
|
|
||||||
#define sa_addr _sa_ex_u.addr
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a socket based on info from 'conn' and 'ai'.
|
|
||||||
*
|
|
||||||
* Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
|
|
||||||
* socket callback is set, used that!
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
CURLcode Curl_socket_open(struct Curl_easy *data,
|
|
||||||
const struct Curl_addrinfo *ai,
|
|
||||||
struct Curl_sockaddr_ex *addr,
|
|
||||||
int transport,
|
|
||||||
curl_socket_t *sockfd);
|
|
||||||
|
|
||||||
int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn,
|
|
||||||
curl_socket_t sock);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine the curl code for a socket connect() == -1 with errno.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_socket_connect_result(struct Curl_easy *data,
|
|
||||||
const char *ipaddress, int error);
|
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
/* When you run a program that uses the Windows Sockets API, you may
|
|
||||||
experience slow performance when you copy data to a TCP server.
|
|
||||||
|
|
||||||
https://support.microsoft.com/kb/823764
|
|
||||||
|
|
||||||
Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
|
|
||||||
Buffer Size
|
|
||||||
|
|
||||||
*/
|
|
||||||
void Curl_sndbufset(curl_socket_t sockfd);
|
|
||||||
#else
|
|
||||||
#define Curl_sndbufset(y) Curl_nop_stmt
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assign the address `ai` to the Curl_sockaddr_ex `dest` and
|
|
||||||
* set the transport used.
|
|
||||||
*/
|
|
||||||
void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
|
||||||
const struct Curl_addrinfo *ai,
|
|
||||||
int transport);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a cfilter that opens a TCP socket to the given address
|
|
||||||
* when calling its `connect` implementation.
|
|
||||||
* The filter will not touch any connection/data flags and can be
|
|
||||||
* used in happy eyeballing. Once selected for use, its `_active()`
|
|
||||||
* method needs to be called.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
const struct Curl_addrinfo *ai,
|
|
||||||
int transport);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a cfilter that opens a UDP socket to the given address
|
|
||||||
* when calling its `connect` implementation.
|
|
||||||
* The filter will not touch any connection/data flags and can be
|
|
||||||
* used in happy eyeballing. Once selected for use, its `_active()`
|
|
||||||
* method needs to be called.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
const struct Curl_addrinfo *ai,
|
|
||||||
int transport);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a cfilter that opens a UNIX socket to the given address
|
|
||||||
* when calling its `connect` implementation.
|
|
||||||
* The filter will not touch any connection/data flags and can be
|
|
||||||
* used in happy eyeballing. Once selected for use, its `_active()`
|
|
||||||
* method needs to be called.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
const struct Curl_addrinfo *ai,
|
|
||||||
int transport);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a cfilter that keeps a listening socket.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex,
|
|
||||||
curl_socket_t *s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace the listen socket with the accept()ed one.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex,
|
|
||||||
curl_socket_t *s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return TRUE iff `cf` is a socket filter.
|
|
||||||
*/
|
|
||||||
bool Curl_cf_is_socket(struct Curl_cfilter *cf);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Peek at the socket and remote ip/port the socket filter is using.
|
|
||||||
* The filter owns all returned values.
|
|
||||||
* @param psock pointer to hold socket descriptor or NULL
|
|
||||||
* @param paddr pointer to hold addr reference or NULL
|
|
||||||
* @param pr_ip_str pointer to hold remote addr as string or NULL
|
|
||||||
* @param pr_port pointer to hold remote port number or NULL
|
|
||||||
* @param pl_ip_str pointer to hold local addr as string or NULL
|
|
||||||
* @param pl_port pointer to hold local port number or NULL
|
|
||||||
* Returns error if the filter is of invalid type.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_cf_socket_peek(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
curl_socket_t *psock,
|
|
||||||
const struct Curl_sockaddr_ex **paddr,
|
|
||||||
const char **pr_ip_str, int *pr_port,
|
|
||||||
const char **pl_ip_str, int *pl_port);
|
|
||||||
|
|
||||||
extern struct Curl_cftype Curl_cft_tcp;
|
|
||||||
extern struct Curl_cftype Curl_cft_udp;
|
|
||||||
extern struct Curl_cftype Curl_cft_unix;
|
|
||||||
extern struct Curl_cftype Curl_cft_tcp_accept;
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_CF_SOCKET_H */
|
|
|
@ -1,663 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include "urldata.h"
|
|
||||||
#include "strerror.h"
|
|
||||||
#include "cfilters.h"
|
|
||||||
#include "connect.h"
|
|
||||||
#include "url.h" /* for Curl_safefree() */
|
|
||||||
#include "sendf.h"
|
|
||||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
|
||||||
#include "multiif.h"
|
|
||||||
#include "progress.h"
|
|
||||||
#include "warnless.h"
|
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
#ifndef ARRAYSIZE
|
|
||||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void Curl_cf_def_destroy_this(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
(void)cf;
|
|
||||||
(void)data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
cf->connected = FALSE;
|
|
||||||
if(cf->next)
|
|
||||||
cf->next->cft->close(cf->next, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_cf_def_connect(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool blocking, bool *done)
|
|
||||||
{
|
|
||||||
CURLcode result;
|
|
||||||
|
|
||||||
if(cf->connected) {
|
|
||||||
*done = TRUE;
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
if(cf->next) {
|
|
||||||
result = cf->next->cft->connect(cf->next, data, blocking, done);
|
|
||||||
if(!result && *done) {
|
|
||||||
cf->connected = TRUE;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
*done = FALSE;
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
const char **phost, const char **pdisplay_host,
|
|
||||||
int *pport)
|
|
||||||
{
|
|
||||||
if(cf->next)
|
|
||||||
cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
|
|
||||||
else {
|
|
||||||
*phost = cf->conn->host.name;
|
|
||||||
*pdisplay_host = cf->conn->host.dispname;
|
|
||||||
*pport = cf->conn->port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
curl_socket_t *socks)
|
|
||||||
{
|
|
||||||
return cf->next?
|
|
||||||
cf->next->cft->get_select_socks(cf->next, data, socks) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
|
|
||||||
const struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
return cf->next?
|
|
||||||
cf->next->cft->has_data_pending(cf->next, data) : FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
const void *buf, size_t len, CURLcode *err)
|
|
||||||
{
|
|
||||||
return cf->next?
|
|
||||||
cf->next->cft->do_send(cf->next, data, buf, len, err) :
|
|
||||||
CURLE_RECV_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
char *buf, size_t len, CURLcode *err)
|
|
||||||
{
|
|
||||||
return cf->next?
|
|
||||||
cf->next->cft->do_recv(cf->next, data, buf, len, err) :
|
|
||||||
CURLE_SEND_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool *input_pending)
|
|
||||||
{
|
|
||||||
return cf->next?
|
|
||||||
cf->next->cft->is_alive(cf->next, data, input_pending) :
|
|
||||||
FALSE; /* pessimistic in absence of data */
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
return cf->next?
|
|
||||||
cf->next->cft->keep_alive(cf->next, data) :
|
|
||||||
CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
int query, int *pres1, void *pres2)
|
|
||||||
{
|
|
||||||
return cf->next?
|
|
||||||
cf->next->cft->query(cf->next, data, query, pres1, pres2) :
|
|
||||||
CURLE_UNKNOWN_OPTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
|
|
||||||
struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cfn, *cf = *pcf;
|
|
||||||
|
|
||||||
if(cf) {
|
|
||||||
*pcf = NULL;
|
|
||||||
while(cf) {
|
|
||||||
cfn = cf->next;
|
|
||||||
/* prevent destroying filter to mess with its sub-chain, since
|
|
||||||
* we have the reference now and will call destroy on it.
|
|
||||||
*/
|
|
||||||
cf->next = NULL;
|
|
||||||
cf->cft->destroy(cf, data);
|
|
||||||
free(cf);
|
|
||||||
cf = cfn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_cf_discard_all(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn, int index)
|
|
||||||
{
|
|
||||||
Curl_conn_cf_discard_chain(&conn->cfilter[index], data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_close(struct Curl_easy *data, int index)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
|
|
||||||
DEBUGASSERT(data->conn);
|
|
||||||
/* it is valid to call that without filters being present */
|
|
||||||
cf = data->conn->cfilter[index];
|
|
||||||
if(cf) {
|
|
||||||
cf->cft->close(cf, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t Curl_conn_recv(struct Curl_easy *data, int num, char *buf,
|
|
||||||
size_t len, CURLcode *code)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
DEBUGASSERT(data->conn);
|
|
||||||
cf = data->conn->cfilter[num];
|
|
||||||
while(cf && !cf->connected) {
|
|
||||||
cf = cf->next;
|
|
||||||
}
|
|
||||||
if(cf) {
|
|
||||||
return cf->cft->do_recv(cf, data, buf, len, code);
|
|
||||||
}
|
|
||||||
failf(data, CMSGI(data->conn, num, "recv: no filter connected"));
|
|
||||||
*code = CURLE_FAILED_INIT;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t Curl_conn_send(struct Curl_easy *data, int num,
|
|
||||||
const void *mem, size_t len, CURLcode *code)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
DEBUGASSERT(data->conn);
|
|
||||||
cf = data->conn->cfilter[num];
|
|
||||||
while(cf && !cf->connected) {
|
|
||||||
cf = cf->next;
|
|
||||||
}
|
|
||||||
if(cf) {
|
|
||||||
return cf->cft->do_send(cf, data, mem, len, code);
|
|
||||||
}
|
|
||||||
failf(data, CMSGI(data->conn, num, "send: no filter connected"));
|
|
||||||
DEBUGASSERT(0);
|
|
||||||
*code = CURLE_FAILED_INIT;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
|
|
||||||
const struct Curl_cftype *cft,
|
|
||||||
void *ctx)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
DEBUGASSERT(cft);
|
|
||||||
cf = calloc(sizeof(*cf), 1);
|
|
||||||
if(!cf)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
cf->cft = cft;
|
|
||||||
cf->ctx = ctx;
|
|
||||||
result = CURLE_OK;
|
|
||||||
out:
|
|
||||||
*pcf = cf;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_cf_add(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int index,
|
|
||||||
struct Curl_cfilter *cf)
|
|
||||||
{
|
|
||||||
(void)data;
|
|
||||||
DEBUGASSERT(conn);
|
|
||||||
DEBUGASSERT(!cf->conn);
|
|
||||||
DEBUGASSERT(!cf->next);
|
|
||||||
|
|
||||||
cf->next = conn->cfilter[index];
|
|
||||||
cf->conn = conn;
|
|
||||||
cf->sockindex = index;
|
|
||||||
conn->cfilter[index] = cf;
|
|
||||||
DEBUGF(LOG_CF(data, cf, "added"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
|
|
||||||
struct Curl_cfilter *cf_new)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *tail, **pnext;
|
|
||||||
|
|
||||||
DEBUGASSERT(cf_at);
|
|
||||||
DEBUGASSERT(cf_new);
|
|
||||||
DEBUGASSERT(!cf_new->conn);
|
|
||||||
|
|
||||||
tail = cf_at->next;
|
|
||||||
cf_at->next = cf_new;
|
|
||||||
do {
|
|
||||||
cf_new->conn = cf_at->conn;
|
|
||||||
cf_new->sockindex = cf_at->sockindex;
|
|
||||||
pnext = &cf_new->next;
|
|
||||||
cf_new = cf_new->next;
|
|
||||||
} while(cf_new);
|
|
||||||
*pnext = tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter **pprev = &cf->conn->cfilter[cf->sockindex];
|
|
||||||
|
|
||||||
/* remove from chain if still in there */
|
|
||||||
DEBUGASSERT(cf);
|
|
||||||
while (*pprev) {
|
|
||||||
if (*pprev == cf) {
|
|
||||||
*pprev = cf->next;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pprev = &((*pprev)->next);
|
|
||||||
}
|
|
||||||
cf->cft->destroy(cf, data);
|
|
||||||
free(cf);
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool blocking, bool *done)
|
|
||||||
{
|
|
||||||
if(cf)
|
|
||||||
return cf->cft->connect(cf, data, blocking, done);
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
if(cf)
|
|
||||||
cf->cft->close(cf, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
curl_socket_t *socks)
|
|
||||||
{
|
|
||||||
if(cf)
|
|
||||||
return cf->cft->get_select_socks(cf, data, socks);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Curl_conn_cf_data_pending(struct Curl_cfilter *cf,
|
|
||||||
const struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
if(cf)
|
|
||||||
return cf->cft->has_data_pending(cf, data);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
const void *buf, size_t len, CURLcode *err)
|
|
||||||
{
|
|
||||||
if(cf)
|
|
||||||
return cf->cft->do_send(cf, data, buf, len, err);
|
|
||||||
*err = CURLE_SEND_ERROR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
char *buf, size_t len, CURLcode *err)
|
|
||||||
{
|
|
||||||
if(cf)
|
|
||||||
return cf->cft->do_recv(cf, data, buf, len, err);
|
|
||||||
*err = CURLE_RECV_ERROR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_conn_connect(struct Curl_easy *data,
|
|
||||||
int sockindex,
|
|
||||||
bool blocking,
|
|
||||||
bool *done)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
DEBUGASSERT(data->conn);
|
|
||||||
|
|
||||||
cf = data->conn->cfilter[sockindex];
|
|
||||||
DEBUGASSERT(cf);
|
|
||||||
if(!cf)
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
|
|
||||||
*done = cf->connected;
|
|
||||||
if(!*done) {
|
|
||||||
result = cf->cft->connect(cf, data, blocking, done);
|
|
||||||
if(!result && *done) {
|
|
||||||
Curl_conn_ev_update_info(data, data->conn);
|
|
||||||
Curl_conn_report_connect_stats(data, data->conn);
|
|
||||||
data->conn->keepalive = Curl_now();
|
|
||||||
}
|
|
||||||
else if(result) {
|
|
||||||
Curl_conn_report_connect_stats(data, data->conn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Curl_conn_is_connected(struct connectdata *conn, int sockindex)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
|
|
||||||
cf = conn->cfilter[sockindex];
|
|
||||||
return cf && cf->connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
|
|
||||||
cf = data->conn->cfilter[sockindex];
|
|
||||||
while(cf) {
|
|
||||||
if(cf->connected)
|
|
||||||
return TRUE;
|
|
||||||
if(cf->cft->flags & CF_TYPE_IP_CONNECT)
|
|
||||||
return FALSE;
|
|
||||||
cf = cf->next;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
|
|
||||||
|
|
||||||
for(; cf; cf = cf->next) {
|
|
||||||
if(cf->cft->flags & CF_TYPE_SSL)
|
|
||||||
return TRUE;
|
|
||||||
if(cf->cft->flags & CF_TYPE_IP_CONNECT)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
|
|
||||||
|
|
||||||
for(; cf; cf = cf->next) {
|
|
||||||
if(cf->cft->flags & CF_TYPE_MULTIPLEX)
|
|
||||||
return TRUE;
|
|
||||||
if(cf->cft->flags & CF_TYPE_IP_CONNECT
|
|
||||||
|| cf->cft->flags & CF_TYPE_SSL)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
|
|
||||||
(void)data;
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
DEBUGASSERT(data->conn);
|
|
||||||
|
|
||||||
cf = data->conn->cfilter[sockindex];
|
|
||||||
while(cf && !cf->connected) {
|
|
||||||
cf = cf->next;
|
|
||||||
}
|
|
||||||
if(cf) {
|
|
||||||
return cf->cft->has_data_pending(cf, data);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
|
|
||||||
curl_socket_t *socks)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
DEBUGASSERT(data->conn);
|
|
||||||
cf = data->conn->cfilter[sockindex];
|
|
||||||
|
|
||||||
/* if the next one is not yet connected, that's the one we want */
|
|
||||||
while(cf && cf->next && !cf->next->connected)
|
|
||||||
cf = cf->next;
|
|
||||||
if(cf) {
|
|
||||||
return cf->cft->get_select_socks(cf, data, socks);
|
|
||||||
}
|
|
||||||
return GETSOCK_BLANK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
|
|
||||||
const char **phost, const char **pdisplay_host,
|
|
||||||
int *pport)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
|
|
||||||
DEBUGASSERT(data->conn);
|
|
||||||
cf = data->conn->cfilter[sockindex];
|
|
||||||
if(cf) {
|
|
||||||
cf->cft->get_host(cf, data, phost, pdisplay_host, pport);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Some filter ask during shutdown for this, mainly for debugging
|
|
||||||
* purposes. We hand out the defaults, however this is not always
|
|
||||||
* accurate, as the connection might be tunneled, etc. But all that
|
|
||||||
* state is already gone here. */
|
|
||||||
*phost = data->conn->host.name;
|
|
||||||
*pdisplay_host = data->conn->host.dispname;
|
|
||||||
*pport = data->conn->remote_port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
int event, int arg1, void *arg2)
|
|
||||||
{
|
|
||||||
(void)cf;
|
|
||||||
(void)data;
|
|
||||||
(void)event;
|
|
||||||
(void)arg1;
|
|
||||||
(void)arg2;
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool ignore_result,
|
|
||||||
int event, int arg1, void *arg2)
|
|
||||||
{
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
for(; cf; cf = cf->next) {
|
|
||||||
if(Curl_cf_def_cntrl == cf->cft->cntrl)
|
|
||||||
continue;
|
|
||||||
result = cf->cft->cntrl(cf, data, event, arg1, arg2);
|
|
||||||
if(!ignore_result && result)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
curl_socket_t sock;
|
|
||||||
if(cf && !cf->cft->query(cf, data, CF_QUERY_SOCKET, NULL, &sock))
|
|
||||||
return sock;
|
|
||||||
return CURL_SOCKET_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf;
|
|
||||||
|
|
||||||
cf = data->conn? data->conn->cfilter[sockindex] : NULL;
|
|
||||||
/* if the top filter has not connected, ask it (and its sub-filters)
|
|
||||||
* for the socket. Otherwise conn->sock[sockindex] should have it.
|
|
||||||
*/
|
|
||||||
if(cf && !cf->connected)
|
|
||||||
return Curl_conn_cf_get_socket(cf, data);
|
|
||||||
return data->conn? data->conn->sock[sockindex] : CURL_SOCKET_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode cf_cntrl_all(struct connectdata *conn,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool ignore_result,
|
|
||||||
int event, int arg1, void *arg2)
|
|
||||||
{
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
|
|
||||||
result = Curl_conn_cf_cntrl(conn->cfilter[i], data, ignore_result,
|
|
||||||
event, arg1, arg2);
|
|
||||||
if(!ignore_result && result)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_ev_data_attach(struct connectdata *conn,
|
|
||||||
struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
cf_cntrl_all(conn, data, TRUE, CF_CTRL_DATA_ATTACH, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_ev_data_detach(struct connectdata *conn,
|
|
||||||
struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
cf_cntrl_all(conn, data, TRUE, CF_CTRL_DATA_DETACH, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
return cf_cntrl_all(data->conn, data, FALSE,
|
|
||||||
CF_CTRL_DATA_SETUP, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
return cf_cntrl_all(data->conn, data, FALSE,
|
|
||||||
CF_CTRL_DATA_IDLE, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify connection filters that the transfer represented by `data`
|
|
||||||
* is donw with sending data (e.g. has uploaded everything).
|
|
||||||
*/
|
|
||||||
void Curl_conn_ev_data_done_send(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE_SEND, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify connection filters that the transfer represented by `data`
|
|
||||||
* is finished - eventually premature, e.g. before being complete.
|
|
||||||
*/
|
|
||||||
void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature)
|
|
||||||
{
|
|
||||||
cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE, premature, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause)
|
|
||||||
{
|
|
||||||
return cf_cntrl_all(data->conn, data, FALSE,
|
|
||||||
CF_CTRL_DATA_PAUSE, do_pause, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_ev_update_info(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn)
|
|
||||||
{
|
|
||||||
cf_cntrl_all(conn, data, TRUE, CF_CTRL_CONN_INFO_UPDATE, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conn_report_connect_stats(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
|
|
||||||
if(cf) {
|
|
||||||
struct curltime connected;
|
|
||||||
struct curltime appconnected;
|
|
||||||
|
|
||||||
memset(&connected, 0, sizeof(connected));
|
|
||||||
cf->cft->query(cf, data, CF_QUERY_TIMER_CONNECT, NULL, &connected);
|
|
||||||
if(connected.tv_sec || connected.tv_usec)
|
|
||||||
Curl_pgrsTimeWas(data, TIMER_CONNECT, connected);
|
|
||||||
|
|
||||||
memset(&appconnected, 0, sizeof(appconnected));
|
|
||||||
cf->cft->query(cf, data, CF_QUERY_TIMER_APPCONNECT, NULL, &appconnected);
|
|
||||||
if(appconnected.tv_sec || appconnected.tv_usec)
|
|
||||||
Curl_pgrsTimeWas(data, TIMER_APPCONNECT, appconnected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn,
|
|
||||||
bool *input_pending)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
|
|
||||||
return cf && !cf->conn->bits.close &&
|
|
||||||
cf->cft->is_alive(cf, data, input_pending);
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex)
|
|
||||||
{
|
|
||||||
struct Curl_cfilter *cf = conn->cfilter[sockindex];
|
|
||||||
return cf? cf->cft->keep_alive(cf, data) : CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex)
|
|
||||||
{
|
|
||||||
CURLcode result;
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
struct Curl_cfilter *cf = conn->cfilter[sockindex];
|
|
||||||
result = cf? cf->cft->query(cf, data, CF_QUERY_MAX_CONCURRENT,
|
|
||||||
&n, NULL) : CURLE_UNKNOWN_OPTION;
|
|
||||||
return (result || n <= 0)? 1 : (size_t)n;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,539 +0,0 @@
|
||||||
#ifndef HEADER_CURL_CFILTERS_H
|
|
||||||
#define HEADER_CURL_CFILTERS_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
struct Curl_cfilter;
|
|
||||||
struct Curl_easy;
|
|
||||||
struct Curl_dns_entry;
|
|
||||||
struct connectdata;
|
|
||||||
|
|
||||||
/* Callback to destroy resources held by this filter instance.
|
|
||||||
* Implementations MUST NOT chain calls to cf->next.
|
|
||||||
*/
|
|
||||||
typedef void Curl_cft_destroy_this(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data);
|
|
||||||
|
|
||||||
typedef void Curl_cft_close(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data);
|
|
||||||
|
|
||||||
typedef CURLcode Curl_cft_connect(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool blocking, bool *done);
|
|
||||||
|
|
||||||
/* Return the hostname and port the connection goes to.
|
|
||||||
* This may change with the connection state of filters when tunneling
|
|
||||||
* is involved.
|
|
||||||
* @param cf the filter to ask
|
|
||||||
* @param data the easy handle currently active
|
|
||||||
* @param phost on return, points to the relevant, real hostname.
|
|
||||||
* this is owned by the connection.
|
|
||||||
* @param pdisplay_host on return, points to the printable hostname.
|
|
||||||
* this is owned by the connection.
|
|
||||||
* @param pport on return, contains the port number
|
|
||||||
*/
|
|
||||||
typedef void Curl_cft_get_host(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
const char **phost,
|
|
||||||
const char **pdisplay_host,
|
|
||||||
int *pport);
|
|
||||||
|
|
||||||
/* Filters may return sockets and fdset flags they are waiting for.
|
|
||||||
* The passes array has room for up to MAX_SOCKSPEREASYHANDLE sockets.
|
|
||||||
* @return read/write fdset for index in socks
|
|
||||||
* or GETSOCK_BLANK when nothing to wait on
|
|
||||||
*/
|
|
||||||
typedef int Curl_cft_get_select_socks(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
curl_socket_t *socks);
|
|
||||||
|
|
||||||
typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf,
|
|
||||||
const struct Curl_easy *data);
|
|
||||||
|
|
||||||
typedef ssize_t Curl_cft_send(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data, /* transfer */
|
|
||||||
const void *buf, /* data to write */
|
|
||||||
size_t len, /* amount to write */
|
|
||||||
CURLcode *err); /* error to return */
|
|
||||||
|
|
||||||
typedef ssize_t Curl_cft_recv(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data, /* transfer */
|
|
||||||
char *buf, /* store data here */
|
|
||||||
size_t len, /* amount to read */
|
|
||||||
CURLcode *err); /* error to return */
|
|
||||||
|
|
||||||
typedef bool Curl_cft_conn_is_alive(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool *input_pending);
|
|
||||||
|
|
||||||
typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Events/controls for connection filters, their arguments and
|
|
||||||
* return code handling. Filter callbacks are invoked "top down".
|
|
||||||
* Return code handling:
|
|
||||||
* "first fail" meaning that the first filter returning != CURLE_OK, will
|
|
||||||
* abort further event distribution and determine the result.
|
|
||||||
* "ignored" meaning return values are ignored and the event is distributed
|
|
||||||
* to all filters in the chain. Overall result is always CURLE_OK.
|
|
||||||
*/
|
|
||||||
/* data event arg1 arg2 return */
|
|
||||||
#define CF_CTRL_DATA_ATTACH 1 /* 0 NULL ignored */
|
|
||||||
#define CF_CTRL_DATA_DETACH 2 /* 0 NULL ignored */
|
|
||||||
#define CF_CTRL_DATA_SETUP 4 /* 0 NULL first fail */
|
|
||||||
#define CF_CTRL_DATA_IDLE 5 /* 0 NULL first fail */
|
|
||||||
#define CF_CTRL_DATA_PAUSE 6 /* on/off NULL first fail */
|
|
||||||
#define CF_CTRL_DATA_DONE 7 /* premature NULL ignored */
|
|
||||||
#define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */
|
|
||||||
/* update conn info at connection and data */
|
|
||||||
#define CF_CTRL_CONN_INFO_UPDATE (256+0) /* 0 NULL ignored */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle event/control for the filter.
|
|
||||||
* Implementations MUST NOT chain calls to cf->next.
|
|
||||||
*/
|
|
||||||
typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
int event, int arg1, void *arg2);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries to ask via a `Curl_cft_query *query` method on a cfilter chain.
|
|
||||||
* - MAX_CONCURRENT: the maximum number of parallel transfers the filter
|
|
||||||
* chain expects to handle at the same time.
|
|
||||||
* default: 1 if no filter overrides.
|
|
||||||
* - CONNECT_REPLY_MS: milliseconds until the first indication of a server
|
|
||||||
* response was received on a connect. For TCP, this
|
|
||||||
* reflects the time until the socket connected. On UDP
|
|
||||||
* this gives the time the first bytes from the server
|
|
||||||
* were received.
|
|
||||||
* -1 if not determined yet.
|
|
||||||
* - CF_QUERY_SOCKET: the socket used by the filter chain
|
|
||||||
*/
|
|
||||||
/* query res1 res2 */
|
|
||||||
#define CF_QUERY_MAX_CONCURRENT 1 /* number - */
|
|
||||||
#define CF_QUERY_CONNECT_REPLY_MS 2 /* number - */
|
|
||||||
#define CF_QUERY_SOCKET 3 /* - curl_socket_t */
|
|
||||||
#define CF_QUERY_TIMER_CONNECT 4 /* - struct curltime */
|
|
||||||
#define CF_QUERY_TIMER_APPCONNECT 5 /* - struct curltime */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query the cfilter for properties. Filters ignorant of a query will
|
|
||||||
* pass it "down" the filter chain.
|
|
||||||
*/
|
|
||||||
typedef CURLcode Curl_cft_query(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
int query, int *pres1, void *pres2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type flags for connection filters. A filter can have none, one or
|
|
||||||
* many of those. Use to evaluate state/capabilities of a filter chain.
|
|
||||||
*
|
|
||||||
* CF_TYPE_IP_CONNECT: provides an IP connection or sth equivalent, like
|
|
||||||
* a CONNECT tunnel, a UNIX domain socket, a QUIC
|
|
||||||
* connection, etc.
|
|
||||||
* CF_TYPE_SSL: provide SSL/TLS
|
|
||||||
* CF_TYPE_MULTIPLEX: provides multiplexing of easy handles
|
|
||||||
*/
|
|
||||||
#define CF_TYPE_IP_CONNECT (1 << 0)
|
|
||||||
#define CF_TYPE_SSL (1 << 1)
|
|
||||||
#define CF_TYPE_MULTIPLEX (1 << 2)
|
|
||||||
|
|
||||||
/* A connection filter type, e.g. specific implementation. */
|
|
||||||
struct Curl_cftype {
|
|
||||||
const char *name; /* name of the filter type */
|
|
||||||
int flags; /* flags of filter type */
|
|
||||||
int log_level; /* log level for such filters */
|
|
||||||
Curl_cft_destroy_this *destroy; /* destroy resources of this cf */
|
|
||||||
Curl_cft_connect *connect; /* establish connection */
|
|
||||||
Curl_cft_close *close; /* close conn */
|
|
||||||
Curl_cft_get_host *get_host; /* host filter talks to */
|
|
||||||
Curl_cft_get_select_socks *get_select_socks;/* sockets to select on */
|
|
||||||
Curl_cft_data_pending *has_data_pending;/* conn has data pending */
|
|
||||||
Curl_cft_send *do_send; /* send data */
|
|
||||||
Curl_cft_recv *do_recv; /* receive data */
|
|
||||||
Curl_cft_cntrl *cntrl; /* events/control */
|
|
||||||
Curl_cft_conn_is_alive *is_alive; /* FALSE if conn is dead, Jim! */
|
|
||||||
Curl_cft_conn_keep_alive *keep_alive; /* try to keep it alive */
|
|
||||||
Curl_cft_query *query; /* query filter chain */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A connection filter instance, e.g. registered at a connection */
|
|
||||||
struct Curl_cfilter {
|
|
||||||
const struct Curl_cftype *cft; /* the type providing implementation */
|
|
||||||
struct Curl_cfilter *next; /* next filter in chain */
|
|
||||||
void *ctx; /* filter type specific settings */
|
|
||||||
struct connectdata *conn; /* the connection this filter belongs to */
|
|
||||||
int sockindex; /* the index the filter is installed at */
|
|
||||||
BIT(connected); /* != 0 iff this filter is connected */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Default implementations for the type functions, implementing nop. */
|
|
||||||
void Curl_cf_def_destroy_this(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data);
|
|
||||||
|
|
||||||
/* Default implementations for the type functions, implementing pass-through
|
|
||||||
* the filter chain. */
|
|
||||||
void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data);
|
|
||||||
CURLcode Curl_cf_def_connect(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool blocking, bool *done);
|
|
||||||
void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
const char **phost, const char **pdisplay_host,
|
|
||||||
int *pport);
|
|
||||||
int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
curl_socket_t *socks);
|
|
||||||
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
|
|
||||||
const struct Curl_easy *data);
|
|
||||||
ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
const void *buf, size_t len, CURLcode *err);
|
|
||||||
ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
char *buf, size_t len, CURLcode *err);
|
|
||||||
CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
int event, int arg1, void *arg2);
|
|
||||||
bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool *input_pending);
|
|
||||||
CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data);
|
|
||||||
CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
int query, int *pres1, void *pres2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new filter instance, unattached to the filter chain.
|
|
||||||
* Use Curl_conn_cf_add() to add it to the chain.
|
|
||||||
* @param pcf on success holds the created instance
|
|
||||||
* @param cft the filter type
|
|
||||||
* @param ctx the type specific context to use
|
|
||||||
*/
|
|
||||||
CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
|
|
||||||
const struct Curl_cftype *cft,
|
|
||||||
void *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a filter instance to the `sockindex` filter chain at connection
|
|
||||||
* `conn`. The filter must not already be attached. It is inserted at
|
|
||||||
* the start of the chain (top).
|
|
||||||
*/
|
|
||||||
void Curl_conn_cf_add(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex,
|
|
||||||
struct Curl_cfilter *cf);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert a filter (chain) after `cf_at`.
|
|
||||||
* `cf_new` must not already be attached.
|
|
||||||
*/
|
|
||||||
void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
|
|
||||||
struct Curl_cfilter *cf_new);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Discard, e.g. remove and destroy a specific filter instance.
|
|
||||||
* If the filter is attached to a connection, it will be removed before
|
|
||||||
* it is destroyed.
|
|
||||||
*/
|
|
||||||
void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Discard all cfilters starting with `*pcf` and clearing it afterwards.
|
|
||||||
*/
|
|
||||||
void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
|
|
||||||
struct Curl_easy *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove and destroy all filters at chain `sockindex` on connection `conn`.
|
|
||||||
*/
|
|
||||||
void Curl_conn_cf_discard_all(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex);
|
|
||||||
|
|
||||||
|
|
||||||
CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool blocking, bool *done);
|
|
||||||
void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data);
|
|
||||||
int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
curl_socket_t *socks);
|
|
||||||
bool Curl_conn_cf_data_pending(struct Curl_cfilter *cf,
|
|
||||||
const struct Curl_easy *data);
|
|
||||||
ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
const void *buf, size_t len, CURLcode *err);
|
|
||||||
ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|
||||||
char *buf, size_t len, CURLcode *err);
|
|
||||||
CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
bool ignore_result,
|
|
||||||
int event, int arg1, void *arg2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the socket used by the filter chain starting at `cf`.
|
|
||||||
* Returns CURL_SOCKET_BAD if not available.
|
|
||||||
*/
|
|
||||||
curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf,
|
|
||||||
struct Curl_easy *data);
|
|
||||||
|
|
||||||
|
|
||||||
#define CURL_CF_SSL_DEFAULT -1
|
|
||||||
#define CURL_CF_SSL_DISABLE 0
|
|
||||||
#define CURL_CF_SSL_ENABLE 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bring the filter chain at `sockindex` for connection `data->conn` into
|
|
||||||
* connected state. Which will set `*done` to TRUE.
|
|
||||||
* This can be called on an already connected chain with no side effects.
|
|
||||||
* When not `blocking`, calls may return without error and `*done != TRUE`,
|
|
||||||
* while the individual filters negotiated the connection.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_conn_connect(struct Curl_easy *data, int sockindex,
|
|
||||||
bool blocking, bool *done);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the filter chain at `sockindex` for connection `conn` is
|
|
||||||
* completely connected.
|
|
||||||
*/
|
|
||||||
bool Curl_conn_is_connected(struct connectdata *conn, int sockindex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if we have reached the remote host on IP level, e.g.
|
|
||||||
* have a TCP connection. This turns TRUE before a possible SSL
|
|
||||||
* handshake has been started/done.
|
|
||||||
*/
|
|
||||||
bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the connection is using SSL to the remote host
|
|
||||||
* (or will be once connected). This will return FALSE, if SSL
|
|
||||||
* is only used in proxying and not for the tunnel itself.
|
|
||||||
*/
|
|
||||||
bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connection provides multiplexing of easy handles at `socketindex`.
|
|
||||||
*/
|
|
||||||
bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the filter chain at `sockindex` for connection `data->conn`.
|
|
||||||
* Filters remain in place and may be connected again afterwards.
|
|
||||||
*/
|
|
||||||
void Curl_conn_close(struct Curl_easy *data, int sockindex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return if data is pending in some connection filter at chain
|
|
||||||
* `sockindex` for connection `data->conn`.
|
|
||||||
*/
|
|
||||||
bool Curl_conn_data_pending(struct Curl_easy *data,
|
|
||||||
int sockindex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the socket used on data's connection for the index.
|
|
||||||
* Returns CURL_SOCKET_BAD if not available.
|
|
||||||
*/
|
|
||||||
curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get any select fd flags and the socket filters at chain `sockindex`
|
|
||||||
* at connection `conn` might be waiting for.
|
|
||||||
*/
|
|
||||||
int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
|
|
||||||
curl_socket_t *socks);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receive data through the filter chain at `sockindex` for connection
|
|
||||||
* `data->conn`. Copy at most `len` bytes into `buf`. Return the
|
|
||||||
* actuel number of bytes copied or a negative value on error.
|
|
||||||
* The error code is placed into `*code`.
|
|
||||||
*/
|
|
||||||
ssize_t Curl_conn_recv(struct Curl_easy *data, int sockindex, char *buf,
|
|
||||||
size_t len, CURLcode *code);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send `len` bytes of data from `buf` through the filter chain `sockindex`
|
|
||||||
* at connection `data->conn`. Return the actual number of bytes written
|
|
||||||
* or a negative value on error.
|
|
||||||
* The error code is placed into `*code`.
|
|
||||||
*/
|
|
||||||
ssize_t Curl_conn_send(struct Curl_easy *data, int sockindex,
|
|
||||||
const void *buf, size_t len, CURLcode *code);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The easy handle `data` is being attached to `conn`. This does
|
|
||||||
* not mean that data will actually do a transfer. Attachment is
|
|
||||||
* also used for temporary actions on the connection.
|
|
||||||
*/
|
|
||||||
void Curl_conn_ev_data_attach(struct connectdata *conn,
|
|
||||||
struct Curl_easy *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The easy handle `data` is being detached (no longer served)
|
|
||||||
* by connection `conn`. All filters are informed to release any resources
|
|
||||||
* related to `data`.
|
|
||||||
* Note: there may be several `data` attached to a connection at the same
|
|
||||||
* time.
|
|
||||||
*/
|
|
||||||
void Curl_conn_ev_data_detach(struct connectdata *conn,
|
|
||||||
struct Curl_easy *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify connection filters that they need to setup data for
|
|
||||||
* a transfer.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify connection filters that now would be a good time to
|
|
||||||
* perform any idle, e.g. time related, actions.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify connection filters that the transfer represented by `data`
|
|
||||||
* is donw with sending data (e.g. has uploaded everything).
|
|
||||||
*/
|
|
||||||
void Curl_conn_ev_data_done_send(struct Curl_easy *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify connection filters that the transfer represented by `data`
|
|
||||||
* is finished - eventually premature, e.g. before being complete.
|
|
||||||
*/
|
|
||||||
void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify connection filters that the transfer of data is paused/unpaused.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inform connection filters to update their info in `conn`.
|
|
||||||
*/
|
|
||||||
void Curl_conn_ev_update_info(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update connection statistics
|
|
||||||
*/
|
|
||||||
void Curl_conn_report_connect_stats(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if FIRSTSOCKET's cfilter chain deems connection alive.
|
|
||||||
*/
|
|
||||||
bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn,
|
|
||||||
bool *input_pending);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to upkeep the connection filters at sockindex.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex);
|
|
||||||
|
|
||||||
void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
|
|
||||||
const char **phost, const char **pdisplay_host,
|
|
||||||
int *pport);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the maximum number of parallel transfers the connection
|
|
||||||
* expects to be able to handle at `sockindex`.
|
|
||||||
*/
|
|
||||||
size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Types and macros used to keep the current easy handle in filter calls,
|
|
||||||
* allowing for nested invocations. See #10336.
|
|
||||||
*
|
|
||||||
* `cf_call_data` is intended to be a member of the cfilter's `ctx` type.
|
|
||||||
* A filter defines the macro `CF_CTX_CALL_DATA` to give access to that.
|
|
||||||
*
|
|
||||||
* With all values 0, the default, this indicates that there is no cfilter
|
|
||||||
* call with `data` ongoing.
|
|
||||||
* Macro `CF_DATA_SAVE` preserves the current `cf_call_data` in a local
|
|
||||||
* variable and sets the `data` given, incrementing the `depth` counter.
|
|
||||||
*
|
|
||||||
* Macro `CF_DATA_RESTORE` restores the old values from the local variable,
|
|
||||||
* while checking that `depth` values are as expected (debug build), catching
|
|
||||||
* cases where a "lower" RESTORE was not called.
|
|
||||||
*
|
|
||||||
* Finally, macro `CF_DATA_CURRENT` gives the easy handle of the current
|
|
||||||
* invocation.
|
|
||||||
*/
|
|
||||||
struct cf_call_data {
|
|
||||||
struct Curl_easy *data;
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
int depth;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* define to access the `struct cf_call_data for a cfilter. Normally
|
|
||||||
* a member in the cfilter's `ctx`.
|
|
||||||
*
|
|
||||||
* #define CF_CTX_CALL_DATA(cf) -> struct cf_call_data instance
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
|
|
||||||
#define CF_DATA_SAVE(save, cf, data) \
|
|
||||||
do { \
|
|
||||||
(save) = CF_CTX_CALL_DATA(cf); \
|
|
||||||
DEBUGASSERT((save).data == NULL || (save).depth > 0); \
|
|
||||||
CF_CTX_CALL_DATA(cf).depth++; \
|
|
||||||
CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)data; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define CF_DATA_RESTORE(cf, save) \
|
|
||||||
do { \
|
|
||||||
DEBUGASSERT(CF_CTX_CALL_DATA(cf).depth == (save).depth + 1); \
|
|
||||||
DEBUGASSERT((save).data == NULL || (save).depth > 0); \
|
|
||||||
CF_CTX_CALL_DATA(cf) = (save); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#else /* DEBUGBUILD */
|
|
||||||
|
|
||||||
#define CF_DATA_SAVE(save, cf, data) \
|
|
||||||
do { \
|
|
||||||
(save) = CF_CTX_CALL_DATA(cf); \
|
|
||||||
CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)data; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define CF_DATA_RESTORE(cf, save) \
|
|
||||||
do { \
|
|
||||||
CF_CTX_CALL_DATA(cf) = (save); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#endif /* !DEBUGBUILD */
|
|
||||||
|
|
||||||
#define CF_DATA_CURRENT(cf) \
|
|
||||||
((cf)? (CF_CTX_CALL_DATA(cf).data) : NULL)
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_CFILTERS_H */
|
|
|
@ -1,582 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) Linus Nielsen Feltzing, <linus@haxx.se>
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
#include "urldata.h"
|
|
||||||
#include "url.h"
|
|
||||||
#include "progress.h"
|
|
||||||
#include "multiif.h"
|
|
||||||
#include "sendf.h"
|
|
||||||
#include "conncache.h"
|
|
||||||
#include "share.h"
|
|
||||||
#include "sigpipe.h"
|
|
||||||
#include "connect.h"
|
|
||||||
#include "strcase.h"
|
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
#define HASHKEY_SIZE 128
|
|
||||||
|
|
||||||
static CURLcode bundle_create(struct connectbundle **bundlep)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(*bundlep == NULL);
|
|
||||||
*bundlep = malloc(sizeof(struct connectbundle));
|
|
||||||
if(!*bundlep)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
(*bundlep)->num_connections = 0;
|
|
||||||
(*bundlep)->multiuse = BUNDLE_UNKNOWN;
|
|
||||||
|
|
||||||
Curl_llist_init(&(*bundlep)->conn_list, NULL);
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bundle_destroy(struct connectbundle *bundle)
|
|
||||||
{
|
|
||||||
free(bundle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a connection to a bundle */
|
|
||||||
static void bundle_add_conn(struct connectbundle *bundle,
|
|
||||||
struct connectdata *conn)
|
|
||||||
{
|
|
||||||
Curl_llist_insert_next(&bundle->conn_list, bundle->conn_list.tail, conn,
|
|
||||||
&conn->bundle_node);
|
|
||||||
conn->bundle = bundle;
|
|
||||||
bundle->num_connections++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove a connection from a bundle */
|
|
||||||
static int bundle_remove_conn(struct connectbundle *bundle,
|
|
||||||
struct connectdata *conn)
|
|
||||||
{
|
|
||||||
struct Curl_llist_element *curr;
|
|
||||||
|
|
||||||
curr = bundle->conn_list.head;
|
|
||||||
while(curr) {
|
|
||||||
if(curr->ptr == conn) {
|
|
||||||
Curl_llist_remove(&bundle->conn_list, curr, NULL);
|
|
||||||
bundle->num_connections--;
|
|
||||||
conn->bundle = NULL;
|
|
||||||
return 1; /* we removed a handle */
|
|
||||||
}
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
DEBUGASSERT(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_bundle_hash_entry(void *freethis)
|
|
||||||
{
|
|
||||||
struct connectbundle *b = (struct connectbundle *) freethis;
|
|
||||||
|
|
||||||
bundle_destroy(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Curl_conncache_init(struct conncache *connc, int size)
|
|
||||||
{
|
|
||||||
/* allocate a new easy handle to use when closing cached connections */
|
|
||||||
connc->closure_handle = curl_easy_init();
|
|
||||||
if(!connc->closure_handle)
|
|
||||||
return 1; /* bad */
|
|
||||||
|
|
||||||
Curl_hash_init(&connc->hash, size, Curl_hash_str,
|
|
||||||
Curl_str_key_compare, free_bundle_hash_entry);
|
|
||||||
connc->closure_handle->state.conn_cache = connc;
|
|
||||||
|
|
||||||
return 0; /* good */
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conncache_destroy(struct conncache *connc)
|
|
||||||
{
|
|
||||||
if(connc)
|
|
||||||
Curl_hash_destroy(&connc->hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* creates a key to find a bundle for this connection */
|
|
||||||
static void hashkey(struct connectdata *conn, char *buf, size_t len)
|
|
||||||
{
|
|
||||||
const char *hostname;
|
|
||||||
long port = conn->remote_port;
|
|
||||||
DEBUGASSERT(len >= HASHKEY_SIZE);
|
|
||||||
#ifndef CURL_DISABLE_PROXY
|
|
||||||
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
|
|
||||||
hostname = conn->http_proxy.host.name;
|
|
||||||
port = conn->port;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if(conn->bits.conn_to_host)
|
|
||||||
hostname = conn->conn_to_host.name;
|
|
||||||
else
|
|
||||||
hostname = conn->host.name;
|
|
||||||
|
|
||||||
/* put the numbers first so that the hostname gets cut off if too long */
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
msnprintf(buf, len, "%u/%ld/%s", conn->scope_id, port, hostname);
|
|
||||||
#else
|
|
||||||
msnprintf(buf, len, "%ld/%s", port, hostname);
|
|
||||||
#endif
|
|
||||||
Curl_strntolower(buf, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns number of connections currently held in the connection cache.
|
|
||||||
Locks/unlocks the cache itself!
|
|
||||||
*/
|
|
||||||
size_t Curl_conncache_size(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
size_t num;
|
|
||||||
CONNCACHE_LOCK(data);
|
|
||||||
num = data->state.conn_cache->num_conn;
|
|
||||||
CONNCACHE_UNLOCK(data);
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look up the bundle with all the connections to the same host this
|
|
||||||
connectdata struct is setup to use.
|
|
||||||
|
|
||||||
**NOTE**: When it returns, it holds the connection cache lock! */
|
|
||||||
struct connectbundle *
|
|
||||||
Curl_conncache_find_bundle(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
struct conncache *connc)
|
|
||||||
{
|
|
||||||
struct connectbundle *bundle = NULL;
|
|
||||||
CONNCACHE_LOCK(data);
|
|
||||||
if(connc) {
|
|
||||||
char key[HASHKEY_SIZE];
|
|
||||||
hashkey(conn, key, sizeof(key));
|
|
||||||
bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
return bundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *conncache_add_bundle(struct conncache *connc,
|
|
||||||
char *key,
|
|
||||||
struct connectbundle *bundle)
|
|
||||||
{
|
|
||||||
return Curl_hash_add(&connc->hash, key, strlen(key), bundle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void conncache_remove_bundle(struct conncache *connc,
|
|
||||||
struct connectbundle *bundle)
|
|
||||||
{
|
|
||||||
struct Curl_hash_iterator iter;
|
|
||||||
struct Curl_hash_element *he;
|
|
||||||
|
|
||||||
if(!connc)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
|
||||||
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
while(he) {
|
|
||||||
if(he->ptr == bundle) {
|
|
||||||
/* The bundle is destroyed by the hash destructor function,
|
|
||||||
free_bundle_hash_entry() */
|
|
||||||
Curl_hash_delete(&connc->hash, he->key, he->key_len);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CURLcode Curl_conncache_add_conn(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
struct connectbundle *bundle = NULL;
|
|
||||||
struct connectdata *conn = data->conn;
|
|
||||||
struct conncache *connc = data->state.conn_cache;
|
|
||||||
DEBUGASSERT(conn);
|
|
||||||
|
|
||||||
/* *find_bundle() locks the connection cache */
|
|
||||||
bundle = Curl_conncache_find_bundle(data, conn, data->state.conn_cache);
|
|
||||||
if(!bundle) {
|
|
||||||
char key[HASHKEY_SIZE];
|
|
||||||
|
|
||||||
result = bundle_create(&bundle);
|
|
||||||
if(result) {
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
hashkey(conn, key, sizeof(key));
|
|
||||||
|
|
||||||
if(!conncache_add_bundle(data->state.conn_cache, key, bundle)) {
|
|
||||||
bundle_destroy(bundle);
|
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bundle_add_conn(bundle, conn);
|
|
||||||
conn->connection_id = connc->next_connection_id++;
|
|
||||||
connc->num_conn++;
|
|
||||||
|
|
||||||
DEBUGF(infof(data, "Added connection %ld. "
|
|
||||||
"The cache now contains %zu members",
|
|
||||||
conn->connection_id, connc->num_conn));
|
|
||||||
|
|
||||||
unlock:
|
|
||||||
CONNCACHE_UNLOCK(data);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Removes the connectdata object from the connection cache, but the transfer
|
|
||||||
* still owns this connection.
|
|
||||||
*
|
|
||||||
* Pass TRUE/FALSE in the 'lock' argument depending on if the parent function
|
|
||||||
* already holds the lock or not.
|
|
||||||
*/
|
|
||||||
void Curl_conncache_remove_conn(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn, bool lock)
|
|
||||||
{
|
|
||||||
struct connectbundle *bundle = conn->bundle;
|
|
||||||
struct conncache *connc = data->state.conn_cache;
|
|
||||||
|
|
||||||
/* The bundle pointer can be NULL, since this function can be called
|
|
||||||
due to a failed connection attempt, before being added to a bundle */
|
|
||||||
if(bundle) {
|
|
||||||
if(lock) {
|
|
||||||
CONNCACHE_LOCK(data);
|
|
||||||
}
|
|
||||||
bundle_remove_conn(bundle, conn);
|
|
||||||
if(bundle->num_connections == 0)
|
|
||||||
conncache_remove_bundle(connc, bundle);
|
|
||||||
conn->bundle = NULL; /* removed from it */
|
|
||||||
if(connc) {
|
|
||||||
connc->num_conn--;
|
|
||||||
DEBUGF(infof(data, "The cache now contains %zu members",
|
|
||||||
connc->num_conn));
|
|
||||||
}
|
|
||||||
if(lock) {
|
|
||||||
CONNCACHE_UNLOCK(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function iterates the entire connection cache and calls the function
|
|
||||||
func() with the connection pointer as the first argument and the supplied
|
|
||||||
'param' argument as the other.
|
|
||||||
|
|
||||||
The conncache lock is still held when the callback is called. It needs it,
|
|
||||||
so that it can safely continue traversing the lists once the callback
|
|
||||||
returns.
|
|
||||||
|
|
||||||
Returns 1 if the loop was aborted due to the callback's return code.
|
|
||||||
|
|
||||||
Return 0 from func() to continue the loop, return 1 to abort it.
|
|
||||||
*/
|
|
||||||
bool Curl_conncache_foreach(struct Curl_easy *data,
|
|
||||||
struct conncache *connc,
|
|
||||||
void *param,
|
|
||||||
int (*func)(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn, void *param))
|
|
||||||
{
|
|
||||||
struct Curl_hash_iterator iter;
|
|
||||||
struct Curl_llist_element *curr;
|
|
||||||
struct Curl_hash_element *he;
|
|
||||||
|
|
||||||
if(!connc)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
CONNCACHE_LOCK(data);
|
|
||||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
|
||||||
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
while(he) {
|
|
||||||
struct connectbundle *bundle;
|
|
||||||
|
|
||||||
bundle = he->ptr;
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
|
|
||||||
curr = bundle->conn_list.head;
|
|
||||||
while(curr) {
|
|
||||||
/* Yes, we need to update curr before calling func(), because func()
|
|
||||||
might decide to remove the connection */
|
|
||||||
struct connectdata *conn = curr->ptr;
|
|
||||||
curr = curr->next;
|
|
||||||
|
|
||||||
if(1 == func(data, conn, param)) {
|
|
||||||
CONNCACHE_UNLOCK(data);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CONNCACHE_UNLOCK(data);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the first connection found in the cache. Used when closing all
|
|
||||||
connections.
|
|
||||||
|
|
||||||
NOTE: no locking is done here as this is presumably only done when cleaning
|
|
||||||
up a cache!
|
|
||||||
*/
|
|
||||||
static struct connectdata *
|
|
||||||
conncache_find_first_connection(struct conncache *connc)
|
|
||||||
{
|
|
||||||
struct Curl_hash_iterator iter;
|
|
||||||
struct Curl_hash_element *he;
|
|
||||||
struct connectbundle *bundle;
|
|
||||||
|
|
||||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
|
||||||
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
while(he) {
|
|
||||||
struct Curl_llist_element *curr;
|
|
||||||
bundle = he->ptr;
|
|
||||||
|
|
||||||
curr = bundle->conn_list.head;
|
|
||||||
if(curr) {
|
|
||||||
return curr->ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Give ownership of a connection back to the connection cache. Might
|
|
||||||
* disconnect the oldest existing in there to make space.
|
|
||||||
*
|
|
||||||
* Return TRUE if stored, FALSE if closed.
|
|
||||||
*/
|
|
||||||
bool Curl_conncache_return_conn(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn)
|
|
||||||
{
|
|
||||||
/* data->multi->maxconnects can be negative, deal with it. */
|
|
||||||
size_t maxconnects =
|
|
||||||
(data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
|
|
||||||
data->multi->maxconnects;
|
|
||||||
struct connectdata *conn_candidate = NULL;
|
|
||||||
|
|
||||||
conn->lastused = Curl_now(); /* it was used up until now */
|
|
||||||
if(maxconnects > 0 &&
|
|
||||||
Curl_conncache_size(data) > maxconnects) {
|
|
||||||
infof(data, "Connection cache is full, closing the oldest one");
|
|
||||||
|
|
||||||
conn_candidate = Curl_conncache_extract_oldest(data);
|
|
||||||
if(conn_candidate) {
|
|
||||||
/* the winner gets the honour of being disconnected */
|
|
||||||
Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (conn_candidate == conn) ? FALSE : TRUE;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function finds the connection in the connection bundle that has been
|
|
||||||
* unused for the longest time.
|
|
||||||
*
|
|
||||||
* Does not lock the connection cache!
|
|
||||||
*
|
|
||||||
* Returns the pointer to the oldest idle connection, or NULL if none was
|
|
||||||
* found.
|
|
||||||
*/
|
|
||||||
struct connectdata *
|
|
||||||
Curl_conncache_extract_bundle(struct Curl_easy *data,
|
|
||||||
struct connectbundle *bundle)
|
|
||||||
{
|
|
||||||
struct Curl_llist_element *curr;
|
|
||||||
timediff_t highscore = -1;
|
|
||||||
timediff_t score;
|
|
||||||
struct curltime now;
|
|
||||||
struct connectdata *conn_candidate = NULL;
|
|
||||||
struct connectdata *conn;
|
|
||||||
|
|
||||||
(void)data;
|
|
||||||
|
|
||||||
now = Curl_now();
|
|
||||||
|
|
||||||
curr = bundle->conn_list.head;
|
|
||||||
while(curr) {
|
|
||||||
conn = curr->ptr;
|
|
||||||
|
|
||||||
if(!CONN_INUSE(conn)) {
|
|
||||||
/* Set higher score for the age passed since the connection was used */
|
|
||||||
score = Curl_timediff(now, conn->lastused);
|
|
||||||
|
|
||||||
if(score > highscore) {
|
|
||||||
highscore = score;
|
|
||||||
conn_candidate = conn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
if(conn_candidate) {
|
|
||||||
/* remove it to prevent another thread from nicking it */
|
|
||||||
bundle_remove_conn(bundle, conn_candidate);
|
|
||||||
data->state.conn_cache->num_conn--;
|
|
||||||
DEBUGF(infof(data, "The cache now contains %zu members",
|
|
||||||
data->state.conn_cache->num_conn));
|
|
||||||
}
|
|
||||||
|
|
||||||
return conn_candidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function finds the connection in the connection cache that has been
|
|
||||||
* unused for the longest time and extracts that from the bundle.
|
|
||||||
*
|
|
||||||
* Returns the pointer to the connection, or NULL if none was found.
|
|
||||||
*/
|
|
||||||
struct connectdata *
|
|
||||||
Curl_conncache_extract_oldest(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
struct conncache *connc = data->state.conn_cache;
|
|
||||||
struct Curl_hash_iterator iter;
|
|
||||||
struct Curl_llist_element *curr;
|
|
||||||
struct Curl_hash_element *he;
|
|
||||||
timediff_t highscore =- 1;
|
|
||||||
timediff_t score;
|
|
||||||
struct curltime now;
|
|
||||||
struct connectdata *conn_candidate = NULL;
|
|
||||||
struct connectbundle *bundle;
|
|
||||||
struct connectbundle *bundle_candidate = NULL;
|
|
||||||
|
|
||||||
now = Curl_now();
|
|
||||||
|
|
||||||
CONNCACHE_LOCK(data);
|
|
||||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
|
||||||
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
while(he) {
|
|
||||||
struct connectdata *conn;
|
|
||||||
|
|
||||||
bundle = he->ptr;
|
|
||||||
|
|
||||||
curr = bundle->conn_list.head;
|
|
||||||
while(curr) {
|
|
||||||
conn = curr->ptr;
|
|
||||||
|
|
||||||
if(!CONN_INUSE(conn) && !conn->bits.close &&
|
|
||||||
!conn->connect_only) {
|
|
||||||
/* Set higher score for the age passed since the connection was used */
|
|
||||||
score = Curl_timediff(now, conn->lastused);
|
|
||||||
|
|
||||||
if(score > highscore) {
|
|
||||||
highscore = score;
|
|
||||||
conn_candidate = conn;
|
|
||||||
bundle_candidate = bundle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
}
|
|
||||||
if(conn_candidate) {
|
|
||||||
/* remove it to prevent another thread from nicking it */
|
|
||||||
bundle_remove_conn(bundle_candidate, conn_candidate);
|
|
||||||
connc->num_conn--;
|
|
||||||
DEBUGF(infof(data, "The cache now contains %zu members",
|
|
||||||
connc->num_conn));
|
|
||||||
}
|
|
||||||
CONNCACHE_UNLOCK(data);
|
|
||||||
|
|
||||||
return conn_candidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_conncache_close_all_connections(struct conncache *connc)
|
|
||||||
{
|
|
||||||
struct connectdata *conn;
|
|
||||||
char buffer[READBUFFER_MIN + 1];
|
|
||||||
SIGPIPE_VARIABLE(pipe_st);
|
|
||||||
if(!connc->closure_handle)
|
|
||||||
return;
|
|
||||||
connc->closure_handle->state.buffer = buffer;
|
|
||||||
connc->closure_handle->set.buffer_size = READBUFFER_MIN;
|
|
||||||
|
|
||||||
conn = conncache_find_first_connection(connc);
|
|
||||||
while(conn) {
|
|
||||||
sigpipe_ignore(connc->closure_handle, &pipe_st);
|
|
||||||
/* This will remove the connection from the cache */
|
|
||||||
connclose(conn, "kill all");
|
|
||||||
Curl_conncache_remove_conn(connc->closure_handle, conn, TRUE);
|
|
||||||
Curl_disconnect(connc->closure_handle, conn, FALSE);
|
|
||||||
sigpipe_restore(&pipe_st);
|
|
||||||
|
|
||||||
conn = conncache_find_first_connection(connc);
|
|
||||||
}
|
|
||||||
|
|
||||||
connc->closure_handle->state.buffer = NULL;
|
|
||||||
sigpipe_ignore(connc->closure_handle, &pipe_st);
|
|
||||||
|
|
||||||
Curl_hostcache_clean(connc->closure_handle,
|
|
||||||
connc->closure_handle->dns.hostcache);
|
|
||||||
Curl_close(&connc->closure_handle);
|
|
||||||
sigpipe_restore(&pipe_st);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Useful for debugging the connection cache */
|
|
||||||
void Curl_conncache_print(struct conncache *connc)
|
|
||||||
{
|
|
||||||
struct Curl_hash_iterator iter;
|
|
||||||
struct Curl_llist_element *curr;
|
|
||||||
struct Curl_hash_element *he;
|
|
||||||
|
|
||||||
if(!connc)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fprintf(stderr, "=Bundle cache=\n");
|
|
||||||
|
|
||||||
Curl_hash_start_iterate(connc->hash, &iter);
|
|
||||||
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
while(he) {
|
|
||||||
struct connectbundle *bundle;
|
|
||||||
struct connectdata *conn;
|
|
||||||
|
|
||||||
bundle = he->ptr;
|
|
||||||
|
|
||||||
fprintf(stderr, "%s -", he->key);
|
|
||||||
curr = bundle->conn_list->head;
|
|
||||||
while(curr) {
|
|
||||||
conn = curr->ptr;
|
|
||||||
|
|
||||||
fprintf(stderr, " [%p %d]", (void *)conn, conn->inuse);
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
|
|
||||||
he = Curl_hash_next_element(&iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,121 +0,0 @@
|
||||||
#ifndef HEADER_CURL_CONNCACHE_H
|
|
||||||
#define HEADER_CURL_CONNCACHE_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
||||||
* Copyright (C) Linus Nielsen Feltzing, <linus@haxx.se>
|
|
||||||
*
|
|
||||||
* 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* All accesses to struct fields and changing of data in the connection cache
|
|
||||||
* and connectbundles must be done with the conncache LOCKED. The cache might
|
|
||||||
* be shared.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include "timeval.h"
|
|
||||||
|
|
||||||
struct connectdata;
|
|
||||||
|
|
||||||
struct conncache {
|
|
||||||
struct Curl_hash hash;
|
|
||||||
size_t num_conn;
|
|
||||||
long next_connection_id;
|
|
||||||
struct curltime last_cleanup;
|
|
||||||
/* handle used for closing cached connections */
|
|
||||||
struct Curl_easy *closure_handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BUNDLE_NO_MULTIUSE -1
|
|
||||||
#define BUNDLE_UNKNOWN 0 /* initial value */
|
|
||||||
#define BUNDLE_MULTIPLEX 2
|
|
||||||
|
|
||||||
#ifdef CURLDEBUG
|
|
||||||
/* the debug versions of these macros make extra certain that the lock is
|
|
||||||
never doubly locked or unlocked */
|
|
||||||
#define CONNCACHE_LOCK(x) \
|
|
||||||
do { \
|
|
||||||
if((x)->share) { \
|
|
||||||
Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, \
|
|
||||||
CURL_LOCK_ACCESS_SINGLE); \
|
|
||||||
DEBUGASSERT(!(x)->state.conncache_lock); \
|
|
||||||
(x)->state.conncache_lock = TRUE; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define CONNCACHE_UNLOCK(x) \
|
|
||||||
do { \
|
|
||||||
if((x)->share) { \
|
|
||||||
DEBUGASSERT((x)->state.conncache_lock); \
|
|
||||||
(x)->state.conncache_lock = FALSE; \
|
|
||||||
Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
#else
|
|
||||||
#define CONNCACHE_LOCK(x) if((x)->share) \
|
|
||||||
Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE)
|
|
||||||
#define CONNCACHE_UNLOCK(x) if((x)->share) \
|
|
||||||
Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct connectbundle {
|
|
||||||
int multiuse; /* supports multi-use */
|
|
||||||
size_t num_connections; /* Number of connections in the bundle */
|
|
||||||
struct Curl_llist conn_list; /* The connectdata members of the bundle */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* returns 1 on error, 0 is fine */
|
|
||||||
int Curl_conncache_init(struct conncache *, int size);
|
|
||||||
void Curl_conncache_destroy(struct conncache *connc);
|
|
||||||
|
|
||||||
/* return the correct bundle, to a host or a proxy */
|
|
||||||
struct connectbundle *Curl_conncache_find_bundle(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
struct conncache *connc);
|
|
||||||
/* returns number of connections currently held in the connection cache */
|
|
||||||
size_t Curl_conncache_size(struct Curl_easy *data);
|
|
||||||
|
|
||||||
bool Curl_conncache_return_conn(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn);
|
|
||||||
CURLcode Curl_conncache_add_conn(struct Curl_easy *data) WARN_UNUSED_RESULT;
|
|
||||||
void Curl_conncache_remove_conn(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
bool lock);
|
|
||||||
bool Curl_conncache_foreach(struct Curl_easy *data,
|
|
||||||
struct conncache *connc,
|
|
||||||
void *param,
|
|
||||||
int (*func)(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
void *param));
|
|
||||||
|
|
||||||
struct connectdata *
|
|
||||||
Curl_conncache_find_first_connection(struct conncache *connc);
|
|
||||||
|
|
||||||
struct connectdata *
|
|
||||||
Curl_conncache_extract_bundle(struct Curl_easy *data,
|
|
||||||
struct connectbundle *bundle);
|
|
||||||
struct connectdata *
|
|
||||||
Curl_conncache_extract_oldest(struct Curl_easy *data);
|
|
||||||
void Curl_conncache_close_all_connections(struct conncache *connc);
|
|
||||||
void Curl_conncache_print(struct conncache *connc);
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_CONNCACHE_H */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,157 +0,0 @@
|
||||||
#ifndef HEADER_CURL_CONNECT_H
|
|
||||||
#define HEADER_CURL_CONNECT_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
|
|
||||||
#include "sockaddr.h"
|
|
||||||
#include "timeval.h"
|
|
||||||
|
|
||||||
struct Curl_dns_entry;
|
|
||||||
|
|
||||||
/* generic function that returns how much time there's left to run, according
|
|
||||||
to the timeouts set */
|
|
||||||
timediff_t Curl_timeleft(struct Curl_easy *data,
|
|
||||||
struct curltime *nowp,
|
|
||||||
bool duringconnect);
|
|
||||||
|
|
||||||
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used to extract socket and connectdata struct for the most recent
|
|
||||||
* transfer on the given Curl_easy.
|
|
||||||
*
|
|
||||||
* The returned socket will be CURL_SOCKET_BAD in case of failure!
|
|
||||||
*/
|
|
||||||
curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
|
|
||||||
struct connectdata **connp);
|
|
||||||
|
|
||||||
bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
|
|
||||||
char *addr, int *port);
|
|
||||||
|
|
||||||
void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn,
|
|
||||||
char *local_ip, int local_port);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
|
|
||||||
* argument specifies if it is the end of a connection or a stream.
|
|
||||||
*
|
|
||||||
* For stream-based protocols (such as HTTP/2), a stream close will not cause
|
|
||||||
* a connection close. Other protocols will close the connection for both
|
|
||||||
* cases.
|
|
||||||
*
|
|
||||||
* It sets the bit.close bit to TRUE (with an explanation for debug builds),
|
|
||||||
* when the connection will close.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CONNCTRL_KEEP 0 /* undo a marked closure */
|
|
||||||
#define CONNCTRL_CONNECTION 1
|
|
||||||
#define CONNCTRL_STREAM 2
|
|
||||||
|
|
||||||
void Curl_conncontrol(struct connectdata *conn,
|
|
||||||
int closeit
|
|
||||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
|
||||||
, const char *reason
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
|
||||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM, y)
|
|
||||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y)
|
|
||||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP, y)
|
|
||||||
#else /* if !DEBUGBUILD || CURL_DISABLE_VERBOSE_STRINGS */
|
|
||||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM)
|
|
||||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION)
|
|
||||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a cfilter for making an "ip" connection to the
|
|
||||||
* given address, using parameters from `conn`. The "ip" connection
|
|
||||||
* can be a TCP socket, a UDP socket or even a QUIC connection.
|
|
||||||
*
|
|
||||||
* It MUST use only the supplied `ai` for its connection attempt.
|
|
||||||
*
|
|
||||||
* Such a filter may be used in "happy eyeball" scenarios, and its
|
|
||||||
* `connect` implementation needs to support non-blocking. Once connected,
|
|
||||||
* it MAY be installed in the connection filter chain to serve transfers.
|
|
||||||
*/
|
|
||||||
typedef CURLcode cf_ip_connect_create(struct Curl_cfilter **pcf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
const struct Curl_addrinfo *ai,
|
|
||||||
int transport);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a happy eyeball connection filter that uses the, once resolved,
|
|
||||||
* address information to connect on ip families based on connection
|
|
||||||
* configuration.
|
|
||||||
* @param pcf output, the created cfilter
|
|
||||||
* @param data easy handle used in creation
|
|
||||||
* @param conn connection the filter is created for
|
|
||||||
* @param cf_create method to create the sub-filters performing the
|
|
||||||
* actual connects.
|
|
||||||
*/
|
|
||||||
CURLcode
|
|
||||||
Curl_cf_happy_eyeballs_create(struct Curl_cfilter **pcf,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
cf_ip_connect_create *cf_create,
|
|
||||||
const struct Curl_dns_entry *remotehost,
|
|
||||||
int transport);
|
|
||||||
|
|
||||||
CURLcode Curl_cf_setup_add(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex,
|
|
||||||
const struct Curl_dns_entry *remotehost,
|
|
||||||
int transport,
|
|
||||||
int ssl_mode);
|
|
||||||
|
|
||||||
CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at,
|
|
||||||
struct Curl_easy *data,
|
|
||||||
const struct Curl_dns_entry *remotehost,
|
|
||||||
int transport,
|
|
||||||
int ssl_mode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup the cfilters at `sockindex` in connection `conn`.
|
|
||||||
* If no filter chain is installed yet, inspects the configuration
|
|
||||||
* in `data` and `conn? to install a suitable filter chain.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_conn_setup(struct Curl_easy *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
int sockindex,
|
|
||||||
const struct Curl_dns_entry *remotehost,
|
|
||||||
int ssl_mode);
|
|
||||||
|
|
||||||
extern struct Curl_cftype Curl_cft_happy_eyeballs;
|
|
||||||
extern struct Curl_cftype Curl_cft_setup;
|
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
void Curl_debug_set_transport_provider(int transport,
|
|
||||||
cf_ip_connect_create *cf_create);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_CONNECT_H */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,57 +0,0 @@
|
||||||
#ifndef HEADER_CURL_CONTENT_ENCODING_H
|
|
||||||
#define HEADER_CURL_CONTENT_ENCODING_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
struct contenc_writer {
|
|
||||||
const struct content_encoding *handler; /* Encoding handler. */
|
|
||||||
struct contenc_writer *downstream; /* Downstream writer. */
|
|
||||||
unsigned int order; /* Ordering within writer stack. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Content encoding writer. */
|
|
||||||
struct content_encoding {
|
|
||||||
const char *name; /* Encoding name. */
|
|
||||||
const char *alias; /* Encoding name alias. */
|
|
||||||
CURLcode (*init_writer)(struct Curl_easy *data,
|
|
||||||
struct contenc_writer *writer);
|
|
||||||
CURLcode (*unencode_write)(struct Curl_easy *data,
|
|
||||||
struct contenc_writer *writer,
|
|
||||||
const char *buf, size_t nbytes);
|
|
||||||
void (*close_writer)(struct Curl_easy *data,
|
|
||||||
struct contenc_writer *writer);
|
|
||||||
size_t writersize;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
|
|
||||||
const char *enclist, int is_transfer);
|
|
||||||
CURLcode Curl_unencode_write(struct Curl_easy *data,
|
|
||||||
struct contenc_writer *writer,
|
|
||||||
const char *buf, size_t nbytes);
|
|
||||||
void Curl_unencode_cleanup(struct Curl_easy *data);
|
|
||||||
char *Curl_all_content_encodings(void);
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_CONTENT_ENCODING_H */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,141 +0,0 @@
|
||||||
#ifndef HEADER_CURL_COOKIE_H
|
|
||||||
#define HEADER_CURL_COOKIE_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
struct Cookie {
|
|
||||||
struct Cookie *next; /* next in the chain */
|
|
||||||
char *name; /* <this> = value */
|
|
||||||
char *value; /* name = <this> */
|
|
||||||
char *path; /* path = <this> which is in Set-Cookie: */
|
|
||||||
char *spath; /* sanitized cookie path */
|
|
||||||
char *domain; /* domain = <this> */
|
|
||||||
curl_off_t expires; /* expires = <this> */
|
|
||||||
char *expirestr; /* the plain text version */
|
|
||||||
|
|
||||||
/* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
|
|
||||||
char *version; /* Version = <value> */
|
|
||||||
char *maxage; /* Max-Age = <value> */
|
|
||||||
|
|
||||||
bool tailmatch; /* whether we do tail-matching of the domain name */
|
|
||||||
bool secure; /* whether the 'secure' keyword was used */
|
|
||||||
bool livecookie; /* updated from a server, not a stored file */
|
|
||||||
bool httponly; /* true if the httponly directive is present */
|
|
||||||
int creationtime; /* time when the cookie was written */
|
|
||||||
unsigned char prefix; /* bitmap fields indicating which prefix are set */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Available cookie prefixes, as defined in
|
|
||||||
* draft-ietf-httpbis-rfc6265bis-02
|
|
||||||
*/
|
|
||||||
#define COOKIE_PREFIX__SECURE (1<<0)
|
|
||||||
#define COOKIE_PREFIX__HOST (1<<1)
|
|
||||||
|
|
||||||
#define COOKIE_HASH_SIZE 256
|
|
||||||
|
|
||||||
struct CookieInfo {
|
|
||||||
/* linked list of cookies we know of */
|
|
||||||
struct Cookie *cookies[COOKIE_HASH_SIZE];
|
|
||||||
|
|
||||||
char *filename; /* file we read from/write to */
|
|
||||||
long numcookies; /* number of cookies in the "jar" */
|
|
||||||
bool running; /* state info, for cookie adding information */
|
|
||||||
bool newsession; /* new session, discard session cookies on load */
|
|
||||||
int lastct; /* last creation-time used in the jar */
|
|
||||||
curl_off_t next_expiration; /* the next time at which expiration happens */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This is the maximum line length we accept for a cookie line. RFC 2109
|
|
||||||
section 6.3 says:
|
|
||||||
|
|
||||||
"at least 4096 bytes per cookie (as measured by the size of the characters
|
|
||||||
that comprise the cookie non-terminal in the syntax description of the
|
|
||||||
Set-Cookie header)"
|
|
||||||
|
|
||||||
We allow max 5000 bytes cookie header. Max 4095 bytes length per cookie
|
|
||||||
name and value. Name + value may not exceed 4096 bytes.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#define MAX_COOKIE_LINE 5000
|
|
||||||
|
|
||||||
/* Maximum length of an incoming cookie name or content we deal with. Longer
|
|
||||||
cookies are ignored. */
|
|
||||||
#define MAX_NAME 4096
|
|
||||||
#define MAX_NAME_TXT "4095"
|
|
||||||
|
|
||||||
/* Maximum size for an outgoing cookie line libcurl will use in an http
|
|
||||||
request. This is the default maximum length used in some versions of Apache
|
|
||||||
httpd. */
|
|
||||||
#define MAX_COOKIE_HEADER_LEN 8190
|
|
||||||
|
|
||||||
/* Maximum number of cookies libcurl will send in a single request, even if
|
|
||||||
there might be more cookies that match. One reason to cap the number is to
|
|
||||||
keep the maximum HTTP request within the maximum allowed size. */
|
|
||||||
#define MAX_COOKIE_SEND_AMOUNT 150
|
|
||||||
|
|
||||||
/* Maximum number of Set-Cookie: lines accepted in a single response. If more
|
|
||||||
such header lines are received, they are ignored. This value must be less
|
|
||||||
than 256 since an unsigned char is used to count. */
|
|
||||||
#define MAX_SET_COOKIE_AMOUNT 50
|
|
||||||
|
|
||||||
struct Curl_easy;
|
|
||||||
/*
|
|
||||||
* Add a cookie to the internal list of cookies. The domain and path arguments
|
|
||||||
* are only used if the header boolean is TRUE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Cookie *Curl_cookie_add(struct Curl_easy *data,
|
|
||||||
struct CookieInfo *c, bool header,
|
|
||||||
bool noexpiry, char *lineptr,
|
|
||||||
const char *domain, const char *path,
|
|
||||||
bool secure);
|
|
||||||
|
|
||||||
struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
|
|
||||||
struct CookieInfo *c, const char *host,
|
|
||||||
const char *path, bool secure);
|
|
||||||
void Curl_cookie_freelist(struct Cookie *cookies);
|
|
||||||
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
|
||||||
void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
|
||||||
|
|
||||||
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
|
|
||||||
#define Curl_cookie_list(x) NULL
|
|
||||||
#define Curl_cookie_loadfiles(x) Curl_nop_stmt
|
|
||||||
#define Curl_cookie_init(x,y,z,w) NULL
|
|
||||||
#define Curl_cookie_cleanup(x) Curl_nop_stmt
|
|
||||||
#define Curl_flush_cookies(x,y) Curl_nop_stmt
|
|
||||||
#else
|
|
||||||
void Curl_flush_cookies(struct Curl_easy *data, bool cleanup);
|
|
||||||
void Curl_cookie_cleanup(struct CookieInfo *c);
|
|
||||||
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
|
||||||
const char *file, struct CookieInfo *inc,
|
|
||||||
bool newsession);
|
|
||||||
struct curl_slist *Curl_cookie_list(struct Curl_easy *data);
|
|
||||||
void Curl_cookie_loadfiles(struct Curl_easy *data);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_COOKIE_H */
|
|
|
@ -1,592 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IN6_H
|
|
||||||
# include <netinet/in6.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETDB_H
|
|
||||||
# include <netdb.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
|
||||||
# include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_UN_H
|
|
||||||
# include <sys/un.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __VMS
|
|
||||||
# include <in.h>
|
|
||||||
# include <inet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "curl_addrinfo.h"
|
|
||||||
#include "inet_pton.h"
|
|
||||||
#include "warnless.h"
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_freeaddrinfo()
|
|
||||||
*
|
|
||||||
* This is used to free a linked list of Curl_addrinfo structs along
|
|
||||||
* with all its associated allocated storage. This function should be
|
|
||||||
* called once for each successful call to Curl_getaddrinfo_ex() or to
|
|
||||||
* any function call which actually allocates a Curl_addrinfo struct.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
|
|
||||||
defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
|
|
||||||
/* workaround icc 9.1 optimizer issue */
|
|
||||||
# define vqualifier volatile
|
|
||||||
#else
|
|
||||||
# define vqualifier
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
|
||||||
Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
|
|
||||||
{
|
|
||||||
struct Curl_addrinfo *vqualifier canext;
|
|
||||||
struct Curl_addrinfo *ca;
|
|
||||||
|
|
||||||
for(ca = cahead; ca; ca = canext) {
|
|
||||||
canext = ca->ai_next;
|
|
||||||
free(ca);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
/*
|
|
||||||
* Curl_getaddrinfo_ex()
|
|
||||||
*
|
|
||||||
* This is a wrapper function around system's getaddrinfo(), with
|
|
||||||
* the only difference that instead of returning a linked list of
|
|
||||||
* addrinfo structs this one returns a linked list of Curl_addrinfo
|
|
||||||
* ones. The memory allocated by this function *MUST* be free'd with
|
|
||||||
* Curl_freeaddrinfo(). For each successful call to this function
|
|
||||||
* there must be an associated call later to Curl_freeaddrinfo().
|
|
||||||
*
|
|
||||||
* There should be no single call to system's getaddrinfo() in the
|
|
||||||
* whole library, any such call should be 'routed' through this one.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
Curl_getaddrinfo_ex(const char *nodename,
|
|
||||||
const char *servname,
|
|
||||||
const struct addrinfo *hints,
|
|
||||||
struct Curl_addrinfo **result)
|
|
||||||
{
|
|
||||||
const struct addrinfo *ai;
|
|
||||||
struct addrinfo *aihead;
|
|
||||||
struct Curl_addrinfo *cafirst = NULL;
|
|
||||||
struct Curl_addrinfo *calast = NULL;
|
|
||||||
struct Curl_addrinfo *ca;
|
|
||||||
size_t ss_size;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
*result = NULL; /* assume failure */
|
|
||||||
|
|
||||||
error = getaddrinfo(nodename, servname, hints, &aihead);
|
|
||||||
if(error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
/* traverse the addrinfo list */
|
|
||||||
|
|
||||||
for(ai = aihead; ai != NULL; ai = ai->ai_next) {
|
|
||||||
size_t namelen = ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0;
|
|
||||||
/* ignore elements with unsupported address family, */
|
|
||||||
/* settle family-specific sockaddr structure size. */
|
|
||||||
if(ai->ai_family == AF_INET)
|
|
||||||
ss_size = sizeof(struct sockaddr_in);
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
else if(ai->ai_family == AF_INET6)
|
|
||||||
ss_size = sizeof(struct sockaddr_in6);
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore elements without required address info */
|
|
||||||
if(!ai->ai_addr || !(ai->ai_addrlen > 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore elements with bogus address size */
|
|
||||||
if((size_t)ai->ai_addrlen < ss_size)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ca = malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
|
||||||
if(!ca) {
|
|
||||||
error = EAI_MEMORY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy each structure member individually, member ordering, */
|
|
||||||
/* size, or padding might be different for each platform. */
|
|
||||||
|
|
||||||
ca->ai_flags = ai->ai_flags;
|
|
||||||
ca->ai_family = ai->ai_family;
|
|
||||||
ca->ai_socktype = ai->ai_socktype;
|
|
||||||
ca->ai_protocol = ai->ai_protocol;
|
|
||||||
ca->ai_addrlen = (curl_socklen_t)ss_size;
|
|
||||||
ca->ai_addr = NULL;
|
|
||||||
ca->ai_canonname = NULL;
|
|
||||||
ca->ai_next = NULL;
|
|
||||||
|
|
||||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
|
||||||
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
|
|
||||||
|
|
||||||
if(namelen) {
|
|
||||||
ca->ai_canonname = (void *)((char *)ca->ai_addr + ss_size);
|
|
||||||
memcpy(ca->ai_canonname, ai->ai_canonname, namelen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if the return list is empty, this becomes the first element */
|
|
||||||
if(!cafirst)
|
|
||||||
cafirst = ca;
|
|
||||||
|
|
||||||
/* add this element last in the return list */
|
|
||||||
if(calast)
|
|
||||||
calast->ai_next = ca;
|
|
||||||
calast = ca;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destroy the addrinfo list */
|
|
||||||
if(aihead)
|
|
||||||
freeaddrinfo(aihead);
|
|
||||||
|
|
||||||
/* if we failed, also destroy the Curl_addrinfo list */
|
|
||||||
if(error) {
|
|
||||||
Curl_freeaddrinfo(cafirst);
|
|
||||||
cafirst = NULL;
|
|
||||||
}
|
|
||||||
else if(!cafirst) {
|
|
||||||
#ifdef EAI_NONAME
|
|
||||||
/* rfc3493 conformant */
|
|
||||||
error = EAI_NONAME;
|
|
||||||
#else
|
|
||||||
/* rfc3493 obsoleted */
|
|
||||||
error = EAI_NODATA;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
SET_SOCKERRNO(error);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = cafirst;
|
|
||||||
|
|
||||||
/* This is not a CURLcode */
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_GETADDRINFO */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_he2ai()
|
|
||||||
*
|
|
||||||
* This function returns a pointer to the first element of a newly allocated
|
|
||||||
* Curl_addrinfo struct linked list filled with the data of a given hostent.
|
|
||||||
* Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6
|
|
||||||
* stack, but usable also for IPv4, all hosts and environments.
|
|
||||||
*
|
|
||||||
* The memory allocated by this function *MUST* be free'd later on calling
|
|
||||||
* Curl_freeaddrinfo(). For each successful call to this function there
|
|
||||||
* must be an associated call later to Curl_freeaddrinfo().
|
|
||||||
*
|
|
||||||
* Curl_addrinfo defined in "lib/curl_addrinfo.h"
|
|
||||||
*
|
|
||||||
* struct Curl_addrinfo {
|
|
||||||
* int ai_flags;
|
|
||||||
* int ai_family;
|
|
||||||
* int ai_socktype;
|
|
||||||
* int ai_protocol;
|
|
||||||
* curl_socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo *
|
|
||||||
* char *ai_canonname;
|
|
||||||
* struct sockaddr *ai_addr;
|
|
||||||
* struct Curl_addrinfo *ai_next;
|
|
||||||
* };
|
|
||||||
*
|
|
||||||
* hostent defined in <netdb.h>
|
|
||||||
*
|
|
||||||
* struct hostent {
|
|
||||||
* char *h_name;
|
|
||||||
* char **h_aliases;
|
|
||||||
* int h_addrtype;
|
|
||||||
* int h_length;
|
|
||||||
* char **h_addr_list;
|
|
||||||
* };
|
|
||||||
*
|
|
||||||
* for backward compatibility:
|
|
||||||
*
|
|
||||||
* #define h_addr h_addr_list[0]
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Curl_addrinfo *
|
|
||||||
Curl_he2ai(const struct hostent *he, int port)
|
|
||||||
{
|
|
||||||
struct Curl_addrinfo *ai;
|
|
||||||
struct Curl_addrinfo *prevai = NULL;
|
|
||||||
struct Curl_addrinfo *firstai = NULL;
|
|
||||||
struct sockaddr_in *addr;
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
struct sockaddr_in6 *addr6;
|
|
||||||
#endif
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
int i;
|
|
||||||
char *curr;
|
|
||||||
|
|
||||||
if(!he)
|
|
||||||
/* no input == no output! */
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
|
|
||||||
|
|
||||||
for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) {
|
|
||||||
size_t ss_size;
|
|
||||||
size_t namelen = strlen(he->h_name) + 1; /* include null-terminatior */
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
if(he->h_addrtype == AF_INET6)
|
|
||||||
ss_size = sizeof(struct sockaddr_in6);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
ss_size = sizeof(struct sockaddr_in);
|
|
||||||
|
|
||||||
/* allocate memory to hold the struct, the address and the name */
|
|
||||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
|
||||||
if(!ai) {
|
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* put the address after the struct */
|
|
||||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
|
||||||
/* then put the name after the address */
|
|
||||||
ai->ai_canonname = (char *)ai->ai_addr + ss_size;
|
|
||||||
memcpy(ai->ai_canonname, he->h_name, namelen);
|
|
||||||
|
|
||||||
if(!firstai)
|
|
||||||
/* store the pointer we want to return from this function */
|
|
||||||
firstai = ai;
|
|
||||||
|
|
||||||
if(prevai)
|
|
||||||
/* make the previous entry point to this */
|
|
||||||
prevai->ai_next = ai;
|
|
||||||
|
|
||||||
ai->ai_family = he->h_addrtype;
|
|
||||||
|
|
||||||
/* we return all names as STREAM, so when using this address for TFTP
|
|
||||||
the type must be ignored and conn->socktype be used instead! */
|
|
||||||
ai->ai_socktype = SOCK_STREAM;
|
|
||||||
|
|
||||||
ai->ai_addrlen = (curl_socklen_t)ss_size;
|
|
||||||
|
|
||||||
/* leave the rest of the struct filled with zero */
|
|
||||||
|
|
||||||
switch(ai->ai_family) {
|
|
||||||
case AF_INET:
|
|
||||||
addr = (void *)ai->ai_addr; /* storage area for this info */
|
|
||||||
|
|
||||||
memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
|
|
||||||
addr->sin_family = (CURL_SA_FAMILY_T)(he->h_addrtype);
|
|
||||||
addr->sin_port = htons((unsigned short)port);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
case AF_INET6:
|
|
||||||
addr6 = (void *)ai->ai_addr; /* storage area for this info */
|
|
||||||
|
|
||||||
memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
|
|
||||||
addr6->sin6_family = (CURL_SA_FAMILY_T)(he->h_addrtype);
|
|
||||||
addr6->sin6_port = htons((unsigned short)port);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
prevai = ai;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result) {
|
|
||||||
Curl_freeaddrinfo(firstai);
|
|
||||||
firstai = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return firstai;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct namebuff {
|
|
||||||
struct hostent hostentry;
|
|
||||||
union {
|
|
||||||
struct in_addr ina4;
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
struct in6_addr ina6;
|
|
||||||
#endif
|
|
||||||
} addrentry;
|
|
||||||
char *h_addr_list[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_ip2addr()
|
|
||||||
*
|
|
||||||
* This function takes an internet address, in binary form, as input parameter
|
|
||||||
* along with its address family and the string version of the address, and it
|
|
||||||
* returns a Curl_addrinfo chain filled in correctly with information for the
|
|
||||||
* given address/host
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Curl_addrinfo *
|
|
||||||
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
|
||||||
{
|
|
||||||
struct Curl_addrinfo *ai;
|
|
||||||
|
|
||||||
#if defined(__VMS) && \
|
|
||||||
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
|
|
||||||
#pragma pointer_size save
|
|
||||||
#pragma pointer_size short
|
|
||||||
#pragma message disable PTRMISMATCH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct hostent *h;
|
|
||||||
struct namebuff *buf;
|
|
||||||
char *addrentry;
|
|
||||||
char *hoststr;
|
|
||||||
size_t addrsize;
|
|
||||||
|
|
||||||
DEBUGASSERT(inaddr && hostname);
|
|
||||||
|
|
||||||
buf = malloc(sizeof(struct namebuff));
|
|
||||||
if(!buf)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
hoststr = strdup(hostname);
|
|
||||||
if(!hoststr) {
|
|
||||||
free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(af) {
|
|
||||||
case AF_INET:
|
|
||||||
addrsize = sizeof(struct in_addr);
|
|
||||||
addrentry = (void *)&buf->addrentry.ina4;
|
|
||||||
memcpy(addrentry, inaddr, sizeof(struct in_addr));
|
|
||||||
break;
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
case AF_INET6:
|
|
||||||
addrsize = sizeof(struct in6_addr);
|
|
||||||
addrentry = (void *)&buf->addrentry.ina6;
|
|
||||||
memcpy(addrentry, inaddr, sizeof(struct in6_addr));
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
free(hoststr);
|
|
||||||
free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
h = &buf->hostentry;
|
|
||||||
h->h_name = hoststr;
|
|
||||||
h->h_aliases = NULL;
|
|
||||||
h->h_addrtype = (short)af;
|
|
||||||
h->h_length = (short)addrsize;
|
|
||||||
h->h_addr_list = &buf->h_addr_list[0];
|
|
||||||
h->h_addr_list[0] = addrentry;
|
|
||||||
h->h_addr_list[1] = NULL; /* terminate list of entries */
|
|
||||||
|
|
||||||
#if defined(__VMS) && \
|
|
||||||
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
|
|
||||||
#pragma pointer_size restore
|
|
||||||
#pragma message enable PTRMISMATCH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ai = Curl_he2ai(h, port);
|
|
||||||
|
|
||||||
free(hoststr);
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
return ai;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given an IPv4 or IPv6 dotted string address, this converts it to a proper
|
|
||||||
* allocated Curl_addrinfo struct and returns it.
|
|
||||||
*/
|
|
||||||
struct Curl_addrinfo *Curl_str2addr(char *address, int port)
|
|
||||||
{
|
|
||||||
struct in_addr in;
|
|
||||||
if(Curl_inet_pton(AF_INET, address, &in) > 0)
|
|
||||||
/* This is a dotted IP address 123.123.123.123-style */
|
|
||||||
return Curl_ip2addr(AF_INET, &in, address, port);
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
{
|
|
||||||
struct in6_addr in6;
|
|
||||||
if(Curl_inet_pton(AF_INET6, address, &in6) > 0)
|
|
||||||
/* This is a dotted IPv6 address ::1-style */
|
|
||||||
return Curl_ip2addr(AF_INET6, &in6, address, port);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return NULL; /* bad input format */
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_UNIX_SOCKETS
|
|
||||||
/**
|
|
||||||
* Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo
|
|
||||||
* struct initialized with this path.
|
|
||||||
* Set '*longpath' to TRUE if the error is a too long path.
|
|
||||||
*/
|
|
||||||
struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
|
||||||
bool abstract)
|
|
||||||
{
|
|
||||||
struct Curl_addrinfo *ai;
|
|
||||||
struct sockaddr_un *sa_un;
|
|
||||||
size_t path_len;
|
|
||||||
|
|
||||||
*longpath = FALSE;
|
|
||||||
|
|
||||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_un));
|
|
||||||
if(!ai)
|
|
||||||
return NULL;
|
|
||||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
|
||||||
|
|
||||||
sa_un = (void *) ai->ai_addr;
|
|
||||||
sa_un->sun_family = AF_UNIX;
|
|
||||||
|
|
||||||
/* sun_path must be able to store the NUL-terminated path */
|
|
||||||
path_len = strlen(path) + 1;
|
|
||||||
if(path_len > sizeof(sa_un->sun_path)) {
|
|
||||||
free(ai);
|
|
||||||
*longpath = TRUE;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ai->ai_family = AF_UNIX;
|
|
||||||
ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
|
|
||||||
ai->ai_addrlen = (curl_socklen_t)
|
|
||||||
((offsetof(struct sockaddr_un, sun_path) + path_len) & 0x7FFFFFFF);
|
|
||||||
|
|
||||||
/* Abstract Unix domain socket have NULL prefix instead of suffix */
|
|
||||||
if(abstract)
|
|
||||||
memcpy(sa_un->sun_path + 1, path, path_len - 1);
|
|
||||||
else
|
|
||||||
memcpy(sa_un->sun_path, path, path_len); /* copy NUL byte */
|
|
||||||
|
|
||||||
return ai;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
|
||||||
defined(HAVE_FREEADDRINFO)
|
|
||||||
/*
|
|
||||||
* curl_dbg_freeaddrinfo()
|
|
||||||
*
|
|
||||||
* This is strictly for memory tracing and are using the same style as the
|
|
||||||
* family otherwise present in memdebug.c. I put these ones here since they
|
|
||||||
* require a bunch of structs I didn't want to include in memdebug.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
|
||||||
int line, const char *source)
|
|
||||||
{
|
|
||||||
curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n",
|
|
||||||
source, line, (void *)freethis);
|
|
||||||
#ifdef USE_LWIPSOCK
|
|
||||||
lwip_freeaddrinfo(freethis);
|
|
||||||
#else
|
|
||||||
(freeaddrinfo)(freethis);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
|
|
||||||
/*
|
|
||||||
* curl_dbg_getaddrinfo()
|
|
||||||
*
|
|
||||||
* This is strictly for memory tracing and are using the same style as the
|
|
||||||
* family otherwise present in memdebug.c. I put these ones here since they
|
|
||||||
* require a bunch of structs I didn't want to include in memdebug.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
curl_dbg_getaddrinfo(const char *hostname,
|
|
||||||
const char *service,
|
|
||||||
const struct addrinfo *hints,
|
|
||||||
struct addrinfo **result,
|
|
||||||
int line, const char *source)
|
|
||||||
{
|
|
||||||
#ifdef USE_LWIPSOCK
|
|
||||||
int res = lwip_getaddrinfo(hostname, service, hints, result);
|
|
||||||
#else
|
|
||||||
int res = (getaddrinfo)(hostname, service, hints, result);
|
|
||||||
#endif
|
|
||||||
if(0 == res)
|
|
||||||
/* success */
|
|
||||||
curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n",
|
|
||||||
source, line, (void *)*result);
|
|
||||||
else
|
|
||||||
curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n",
|
|
||||||
source, line);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */
|
|
||||||
|
|
||||||
#if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS)
|
|
||||||
/*
|
|
||||||
* Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X
|
|
||||||
* 10.11.5.
|
|
||||||
*/
|
|
||||||
void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port)
|
|
||||||
{
|
|
||||||
struct Curl_addrinfo *ca;
|
|
||||||
struct sockaddr_in *addr;
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
struct sockaddr_in6 *addr6;
|
|
||||||
#endif
|
|
||||||
for(ca = addrinfo; ca != NULL; ca = ca->ai_next) {
|
|
||||||
switch(ca->ai_family) {
|
|
||||||
case AF_INET:
|
|
||||||
addr = (void *)ca->ai_addr; /* storage area for this info */
|
|
||||||
addr->sin_port = htons((unsigned short)port);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
case AF_INET6:
|
|
||||||
addr6 = (void *)ca->ai_addr; /* storage area for this info */
|
|
||||||
addr6->sin6_port = htons((unsigned short)port);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,108 +0,0 @@
|
||||||
#ifndef HEADER_CURL_ADDRINFO_H
|
|
||||||
#define HEADER_CURL_ADDRINFO_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETDB_H
|
|
||||||
# include <netdb.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
|
||||||
# include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __VMS
|
|
||||||
# include <in.h>
|
|
||||||
# include <inet.h>
|
|
||||||
# include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_addrinfo is our internal struct definition that we use to allow
|
|
||||||
* consistent internal handling of this data. We use this even when the
|
|
||||||
* system provides an addrinfo structure definition. And we use this for
|
|
||||||
* all sorts of IPv4 and IPV6 builds.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Curl_addrinfo {
|
|
||||||
int ai_flags;
|
|
||||||
int ai_family;
|
|
||||||
int ai_socktype;
|
|
||||||
int ai_protocol;
|
|
||||||
curl_socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */
|
|
||||||
char *ai_canonname;
|
|
||||||
struct sockaddr *ai_addr;
|
|
||||||
struct Curl_addrinfo *ai_next;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
Curl_freeaddrinfo(struct Curl_addrinfo *cahead);
|
|
||||||
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
int
|
|
||||||
Curl_getaddrinfo_ex(const char *nodename,
|
|
||||||
const char *servname,
|
|
||||||
const struct addrinfo *hints,
|
|
||||||
struct Curl_addrinfo **result);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct Curl_addrinfo *
|
|
||||||
Curl_he2ai(const struct hostent *he, int port);
|
|
||||||
|
|
||||||
struct Curl_addrinfo *
|
|
||||||
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
|
|
||||||
|
|
||||||
struct Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
|
||||||
|
|
||||||
#ifdef USE_UNIX_SOCKETS
|
|
||||||
struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
|
||||||
bool abstract);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
|
||||||
defined(HAVE_FREEADDRINFO)
|
|
||||||
void
|
|
||||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
|
|
||||||
int
|
|
||||||
curl_dbg_getaddrinfo(const char *hostname, const char *service,
|
|
||||||
const struct addrinfo *hints, struct addrinfo **result,
|
|
||||||
int line, const char *source);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
#ifdef USE_RESOLVE_ON_IPS
|
|
||||||
void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port);
|
|
||||||
#else
|
|
||||||
#define Curl_addrinfo_set_port(x,y)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_ADDRINFO_H */
|
|
|
@ -1,34 +0,0 @@
|
||||||
#ifndef HEADER_CURL_BASE64_H
|
|
||||||
#define HEADER_CURL_BASE64_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
|
|
||||||
char **outptr, size_t *outlen);
|
|
||||||
CURLcode Curl_base64url_encode(const char *inputbuff, size_t insize,
|
|
||||||
char **outptr, size_t *outlen);
|
|
||||||
CURLcode Curl_base64_decode(const char *src,
|
|
||||||
unsigned char **outptr, size_t *outlen);
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_BASE64_H */
|
|
|
@ -1,798 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
/* lib/curl_config.h.in. Generated somehow by cmake. */
|
|
||||||
|
|
||||||
/* disables alt-svc */
|
|
||||||
#cmakedefine CURL_DISABLE_ALTSVC 1
|
|
||||||
|
|
||||||
/* disables cookies support */
|
|
||||||
#cmakedefine CURL_DISABLE_COOKIES 1
|
|
||||||
|
|
||||||
/* disables cryptographic authentication */
|
|
||||||
#cmakedefine CURL_DISABLE_CRYPTO_AUTH 1
|
|
||||||
|
|
||||||
/* disables DICT */
|
|
||||||
#cmakedefine CURL_DISABLE_DICT 1
|
|
||||||
|
|
||||||
/* disables DNS-over-HTTPS */
|
|
||||||
#cmakedefine CURL_DISABLE_DOH 1
|
|
||||||
|
|
||||||
/* disables FILE */
|
|
||||||
#cmakedefine CURL_DISABLE_FILE 1
|
|
||||||
|
|
||||||
/* disables FTP */
|
|
||||||
#cmakedefine CURL_DISABLE_FTP 1
|
|
||||||
|
|
||||||
/* disables GOPHER */
|
|
||||||
#cmakedefine CURL_DISABLE_GOPHER 1
|
|
||||||
|
|
||||||
/* disables HSTS support */
|
|
||||||
#cmakedefine CURL_DISABLE_HSTS 1
|
|
||||||
|
|
||||||
/* disables HTTP */
|
|
||||||
#cmakedefine CURL_DISABLE_HTTP 1
|
|
||||||
|
|
||||||
/* disables IMAP */
|
|
||||||
#cmakedefine CURL_DISABLE_IMAP 1
|
|
||||||
|
|
||||||
/* disables LDAP */
|
|
||||||
#cmakedefine CURL_DISABLE_LDAP 1
|
|
||||||
|
|
||||||
/* disables LDAPS */
|
|
||||||
#cmakedefine CURL_DISABLE_LDAPS 1
|
|
||||||
|
|
||||||
/* disables --libcurl option from the curl tool */
|
|
||||||
#cmakedefine CURL_DISABLE_LIBCURL_OPTION 1
|
|
||||||
|
|
||||||
/* disables MIME support */
|
|
||||||
#cmakedefine CURL_DISABLE_MIME 1
|
|
||||||
|
|
||||||
/* disables MQTT */
|
|
||||||
#cmakedefine CURL_DISABLE_MQTT 1
|
|
||||||
|
|
||||||
/* disables netrc parser */
|
|
||||||
#cmakedefine CURL_DISABLE_NETRC 1
|
|
||||||
|
|
||||||
/* disables NTLM support */
|
|
||||||
#cmakedefine CURL_DISABLE_NTLM 1
|
|
||||||
|
|
||||||
/* disables date parsing */
|
|
||||||
#cmakedefine CURL_DISABLE_PARSEDATE 1
|
|
||||||
|
|
||||||
/* disables POP3 */
|
|
||||||
#cmakedefine CURL_DISABLE_POP3 1
|
|
||||||
|
|
||||||
/* disables built-in progress meter */
|
|
||||||
#cmakedefine CURL_DISABLE_PROGRESS_METER 1
|
|
||||||
|
|
||||||
/* disables proxies */
|
|
||||||
#cmakedefine CURL_DISABLE_PROXY 1
|
|
||||||
|
|
||||||
/* disables RTSP */
|
|
||||||
#cmakedefine CURL_DISABLE_RTSP 1
|
|
||||||
|
|
||||||
/* disables SMB */
|
|
||||||
#cmakedefine CURL_DISABLE_SMB 1
|
|
||||||
|
|
||||||
/* disables SMTP */
|
|
||||||
#cmakedefine CURL_DISABLE_SMTP 1
|
|
||||||
|
|
||||||
/* disables use of socketpair for curl_multi_poll */
|
|
||||||
#cmakedefine CURL_DISABLE_SOCKETPAIR 1
|
|
||||||
|
|
||||||
/* disables TELNET */
|
|
||||||
#cmakedefine CURL_DISABLE_TELNET 1
|
|
||||||
|
|
||||||
/* disables TFTP */
|
|
||||||
#cmakedefine CURL_DISABLE_TFTP 1
|
|
||||||
|
|
||||||
/* disables verbose strings */
|
|
||||||
#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
|
|
||||||
|
|
||||||
/* to make a symbol visible */
|
|
||||||
#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
|
|
||||||
/* Ensure using CURL_EXTERN_SYMBOL is possible */
|
|
||||||
#ifndef CURL_EXTERN_SYMBOL
|
|
||||||
#define CURL_EXTERN_SYMBOL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Allow SMB to work on Windows */
|
|
||||||
#cmakedefine USE_WIN32_CRYPTO 1
|
|
||||||
|
|
||||||
/* Use Windows LDAP implementation */
|
|
||||||
#cmakedefine USE_WIN32_LDAP 1
|
|
||||||
|
|
||||||
/* when not building a shared library */
|
|
||||||
#cmakedefine CURL_STATICLIB 1
|
|
||||||
|
|
||||||
/* your Entropy Gathering Daemon socket pathname */
|
|
||||||
#cmakedefine EGD_SOCKET ${EGD_SOCKET}
|
|
||||||
|
|
||||||
/* Define if you want to enable IPv6 support */
|
|
||||||
#cmakedefine ENABLE_IPV6 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the alarm function. */
|
|
||||||
#cmakedefine HAVE_ALARM 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
|
||||||
#cmakedefine HAVE_ARPA_INET_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <arpa/tftp.h> header file. */
|
|
||||||
#cmakedefine HAVE_ARPA_TFTP_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have _Atomic support. */
|
|
||||||
#cmakedefine HAVE_ATOMIC 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `fchmod' function. */
|
|
||||||
#cmakedefine HAVE_FCHMOD 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `basename' function. */
|
|
||||||
#cmakedefine HAVE_BASENAME 1
|
|
||||||
|
|
||||||
/* Define to 1 if bool is an available type. */
|
|
||||||
#cmakedefine HAVE_BOOL_T 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the __builtin_available function. */
|
|
||||||
#cmakedefine HAVE_BUILTIN_AVAILABLE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the clock_gettime function and monotonic timer. */
|
|
||||||
#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `closesocket' function. */
|
|
||||||
#cmakedefine HAVE_CLOSESOCKET 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the fcntl function. */
|
|
||||||
#cmakedefine HAVE_FCNTL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
|
||||||
#cmakedefine HAVE_FCNTL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
|
|
||||||
#cmakedefine HAVE_FCNTL_O_NONBLOCK 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the freeaddrinfo function. */
|
|
||||||
#cmakedefine HAVE_FREEADDRINFO 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ftruncate function. */
|
|
||||||
#cmakedefine HAVE_FTRUNCATE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working getaddrinfo function. */
|
|
||||||
#cmakedefine HAVE_GETADDRINFO 1
|
|
||||||
|
|
||||||
/* Define to 1 if the getaddrinfo function is threadsafe. */
|
|
||||||
#cmakedefine HAVE_GETADDRINFO_THREADSAFE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `geteuid' function. */
|
|
||||||
#cmakedefine HAVE_GETEUID 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `getppid' function. */
|
|
||||||
#cmakedefine HAVE_GETPPID 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the gethostbyname_r function. */
|
|
||||||
#cmakedefine HAVE_GETHOSTBYNAME_R 1
|
|
||||||
|
|
||||||
/* gethostbyname_r() takes 3 args */
|
|
||||||
#cmakedefine HAVE_GETHOSTBYNAME_R_3 1
|
|
||||||
|
|
||||||
/* gethostbyname_r() takes 5 args */
|
|
||||||
#cmakedefine HAVE_GETHOSTBYNAME_R_5 1
|
|
||||||
|
|
||||||
/* gethostbyname_r() takes 6 args */
|
|
||||||
#cmakedefine HAVE_GETHOSTBYNAME_R_6 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the gethostname function. */
|
|
||||||
#cmakedefine HAVE_GETHOSTNAME 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working getifaddrs function. */
|
|
||||||
#cmakedefine HAVE_GETIFADDRS 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `getpass_r' function. */
|
|
||||||
#cmakedefine HAVE_GETPASS_R 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `getppid' function. */
|
|
||||||
#cmakedefine HAVE_GETPPID 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `getpeername' function. */
|
|
||||||
#cmakedefine HAVE_GETPEERNAME 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `getsockname' function. */
|
|
||||||
#cmakedefine HAVE_GETSOCKNAME 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `if_nametoindex' function. */
|
|
||||||
#cmakedefine HAVE_IF_NAMETOINDEX 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `getpwuid' function. */
|
|
||||||
#cmakedefine HAVE_GETPWUID 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `getpwuid_r' function. */
|
|
||||||
#cmakedefine HAVE_GETPWUID_R 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `getrlimit' function. */
|
|
||||||
#cmakedefine HAVE_GETRLIMIT 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `gettimeofday' function. */
|
|
||||||
#cmakedefine HAVE_GETTIMEOFDAY 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working glibc-style strerror_r function. */
|
|
||||||
#cmakedefine HAVE_GLIBC_STRERROR_R 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working gmtime_r function. */
|
|
||||||
#cmakedefine HAVE_GMTIME_R 1
|
|
||||||
|
|
||||||
/* if you have the gssapi libraries */
|
|
||||||
#cmakedefine HAVE_GSSAPI 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
|
|
||||||
#cmakedefine HAVE_GSSAPI_GSSAPI_GENERIC_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
|
|
||||||
#cmakedefine HAVE_GSSAPI_GSSAPI_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
|
|
||||||
#cmakedefine HAVE_GSSAPI_GSSAPI_KRB5_H 1
|
|
||||||
|
|
||||||
/* if you have the GNU gssapi libraries */
|
|
||||||
#cmakedefine HAVE_GSSGNU 1
|
|
||||||
|
|
||||||
/* if you have the Heimdal gssapi libraries */
|
|
||||||
#cmakedefine HAVE_GSSHEIMDAL 1
|
|
||||||
|
|
||||||
/* if you have the MIT gssapi libraries */
|
|
||||||
#cmakedefine HAVE_GSSMIT 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `idna_strerror' function. */
|
|
||||||
#cmakedefine HAVE_IDNA_STRERROR 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
|
||||||
#cmakedefine HAVE_IFADDRS_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
|
|
||||||
#cmakedefine HAVE_INET_NTOP 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a IPv6 capable working inet_pton function. */
|
|
||||||
#cmakedefine HAVE_INET_PTON 1
|
|
||||||
|
|
||||||
/* Define to 1 if symbol `sa_family_t' exists */
|
|
||||||
#cmakedefine HAVE_SA_FAMILY_T 1
|
|
||||||
|
|
||||||
/* Define to 1 if symbol `ADDRESS_FAMILY' exists */
|
|
||||||
#cmakedefine HAVE_ADDRESS_FAMILY 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
|
||||||
#cmakedefine HAVE_INTTYPES_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ioctlsocket function. */
|
|
||||||
#cmakedefine HAVE_IOCTLSOCKET 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the IoctlSocket camel case function. */
|
|
||||||
#cmakedefine HAVE_IOCTLSOCKET_CAMEL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
|
|
||||||
*/
|
|
||||||
#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
|
|
||||||
#cmakedefine HAVE_IOCTLSOCKET_FIONBIO 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working ioctl FIONBIO function. */
|
|
||||||
#cmakedefine HAVE_IOCTL_FIONBIO 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
|
|
||||||
#cmakedefine HAVE_IOCTL_SIOCGIFADDR 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <io.h> header file. */
|
|
||||||
#cmakedefine HAVE_IO_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the lber.h header file. */
|
|
||||||
#cmakedefine HAVE_LBER_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ldap.h header file. */
|
|
||||||
#cmakedefine HAVE_LDAP_H 1
|
|
||||||
|
|
||||||
/* Use LDAPS implementation */
|
|
||||||
#cmakedefine HAVE_LDAP_SSL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ldap_ssl.h header file. */
|
|
||||||
#cmakedefine HAVE_LDAP_SSL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `ldap_url_parse' function. */
|
|
||||||
#cmakedefine HAVE_LDAP_URL_PARSE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <libgen.h> header file. */
|
|
||||||
#cmakedefine HAVE_LIBGEN_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `idn2' library (-lidn2). */
|
|
||||||
#cmakedefine HAVE_LIBIDN2 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the idn2.h header file. */
|
|
||||||
#cmakedefine HAVE_IDN2_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
|
||||||
#cmakedefine HAVE_LIBSOCKET 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `ssh2' library (-lssh2). */
|
|
||||||
#cmakedefine HAVE_LIBSSH2 1
|
|
||||||
|
|
||||||
/* if zlib is available */
|
|
||||||
#cmakedefine HAVE_LIBZ 1
|
|
||||||
|
|
||||||
/* if brotli is available */
|
|
||||||
#cmakedefine HAVE_BROTLI 1
|
|
||||||
|
|
||||||
/* if your compiler supports LL */
|
|
||||||
#cmakedefine HAVE_LL 1
|
|
||||||
|
|
||||||
/* if zstd is available */
|
|
||||||
#cmakedefine HAVE_ZSTD 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <locale.h> header file. */
|
|
||||||
#cmakedefine HAVE_LOCALE_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if the compiler supports the 'long long' data type. */
|
|
||||||
#cmakedefine HAVE_LONGLONG 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the MSG_NOSIGNAL flag. */
|
|
||||||
#cmakedefine HAVE_MSG_NOSIGNAL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <netdb.h> header file. */
|
|
||||||
#cmakedefine HAVE_NETDB_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
|
||||||
#cmakedefine HAVE_NETINET_IN_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
|
||||||
#cmakedefine HAVE_NETINET_TCP_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <linux/tcp.h> header file. */
|
|
||||||
#cmakedefine HAVE_LINUX_TCP_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <net/if.h> header file. */
|
|
||||||
#cmakedefine HAVE_NET_IF_H 1
|
|
||||||
|
|
||||||
/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */
|
|
||||||
#cmakedefine HAVE_OLD_GSSMIT 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `pipe' function. */
|
|
||||||
#cmakedefine HAVE_PIPE 1
|
|
||||||
|
|
||||||
/* If you have a fine poll */
|
|
||||||
#cmakedefine HAVE_POLL_FINE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <poll.h> header file. */
|
|
||||||
#cmakedefine HAVE_POLL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working POSIX-style strerror_r function. */
|
|
||||||
#cmakedefine HAVE_POSIX_STRERROR_R 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <pthread.h> header file */
|
|
||||||
#cmakedefine HAVE_PTHREAD_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <pwd.h> header file. */
|
|
||||||
#cmakedefine HAVE_PWD_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `RAND_egd' function. */
|
|
||||||
#cmakedefine HAVE_RAND_EGD 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the recv function. */
|
|
||||||
#cmakedefine HAVE_RECV 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the select function. */
|
|
||||||
#cmakedefine HAVE_SELECT 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the send function. */
|
|
||||||
#cmakedefine HAVE_SEND 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the 'fsetxattr' function. */
|
|
||||||
#cmakedefine HAVE_FSETXATTR 1
|
|
||||||
|
|
||||||
/* fsetxattr() takes 5 args */
|
|
||||||
#cmakedefine HAVE_FSETXATTR_5 1
|
|
||||||
|
|
||||||
/* fsetxattr() takes 6 args */
|
|
||||||
#cmakedefine HAVE_FSETXATTR_6 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
|
||||||
#cmakedefine HAVE_SETJMP_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `setlocale' function. */
|
|
||||||
#cmakedefine HAVE_SETLOCALE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `setmode' function. */
|
|
||||||
#cmakedefine HAVE_SETMODE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `setrlimit' function. */
|
|
||||||
#cmakedefine HAVE_SETRLIMIT 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
|
|
||||||
#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the sigaction function. */
|
|
||||||
#cmakedefine HAVE_SIGACTION 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the siginterrupt function. */
|
|
||||||
#cmakedefine HAVE_SIGINTERRUPT 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the signal function. */
|
|
||||||
#cmakedefine HAVE_SIGNAL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <signal.h> header file. */
|
|
||||||
#cmakedefine HAVE_SIGNAL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the sigsetjmp function or macro. */
|
|
||||||
#cmakedefine HAVE_SIGSETJMP 1
|
|
||||||
|
|
||||||
/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
|
|
||||||
#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `socket' function. */
|
|
||||||
#cmakedefine HAVE_SOCKET 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the socketpair function. */
|
|
||||||
#cmakedefine HAVE_SOCKETPAIR 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <ssl.h> header file. */
|
|
||||||
#cmakedefine HAVE_SSL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdatomic.h> header file. */
|
|
||||||
#cmakedefine HAVE_STDATOMIC_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdbool.h> header file. */
|
|
||||||
#cmakedefine HAVE_STDBOOL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdint.h> header file. */
|
|
||||||
#cmakedefine HAVE_STDINT_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
|
||||||
#cmakedefine HAVE_STDLIB_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the strcasecmp function. */
|
|
||||||
#cmakedefine HAVE_STRCASECMP 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the strcmpi function. */
|
|
||||||
#cmakedefine HAVE_STRCMPI 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the strdup function. */
|
|
||||||
#cmakedefine HAVE_STRDUP 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the strerror_r function. */
|
|
||||||
#cmakedefine HAVE_STRERROR_R 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the stricmp function. */
|
|
||||||
#cmakedefine HAVE_STRICMP 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <strings.h> header file. */
|
|
||||||
#cmakedefine HAVE_STRINGS_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <string.h> header file. */
|
|
||||||
#cmakedefine HAVE_STRING_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stropts.h> header file. */
|
|
||||||
#cmakedefine HAVE_STROPTS_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the strtok_r function. */
|
|
||||||
#cmakedefine HAVE_STRTOK_R 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the strtoll function. */
|
|
||||||
#cmakedefine HAVE_STRTOLL 1
|
|
||||||
|
|
||||||
/* if struct sockaddr_storage is defined */
|
|
||||||
#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the timeval struct. */
|
|
||||||
#cmakedefine HAVE_STRUCT_TIMEVAL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/filio.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_FILIO_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_IOCTL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_PARAM_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_POLL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_RESOURCE_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_SELECT_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_SOCKET_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_SOCKIO_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_STAT_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_TIME_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_TYPES_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/un.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_UN_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/utime.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_UTIME_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <termios.h> header file. */
|
|
||||||
#cmakedefine HAVE_TERMIOS_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <termio.h> header file. */
|
|
||||||
#cmakedefine HAVE_TERMIO_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <time.h> header file. */
|
|
||||||
#cmakedefine HAVE_TIME_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
|
||||||
#cmakedefine HAVE_UNISTD_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `utime' function. */
|
|
||||||
#cmakedefine HAVE_UTIME 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `utimes' function. */
|
|
||||||
#cmakedefine HAVE_UTIMES 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <utime.h> header file. */
|
|
||||||
#cmakedefine HAVE_UTIME_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if compiler supports C99 variadic macro style. */
|
|
||||||
#cmakedefine HAVE_VARIADIC_MACROS_C99 1
|
|
||||||
|
|
||||||
/* Define to 1 if compiler supports old gcc variadic macro style. */
|
|
||||||
#cmakedefine HAVE_VARIADIC_MACROS_GCC 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the windows.h header file. */
|
|
||||||
#cmakedefine HAVE_WINDOWS_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the winldap.h header file. */
|
|
||||||
#cmakedefine HAVE_WINLDAP_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the winsock2.h header file. */
|
|
||||||
#cmakedefine HAVE_WINSOCK2_H 1
|
|
||||||
|
|
||||||
/* Define this symbol if your OS supports changing the contents of argv */
|
|
||||||
#cmakedefine HAVE_WRITABLE_ARGV 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ws2tcpip.h header file. */
|
|
||||||
#cmakedefine HAVE_WS2TCPIP_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you need the lber.h header file even with ldap.h */
|
|
||||||
#cmakedefine NEED_LBER_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
|
|
||||||
#cmakedefine NEED_MALLOC_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
|
|
||||||
#cmakedefine NEED_REENTRANT 1
|
|
||||||
|
|
||||||
/* cpu-machine-OS */
|
|
||||||
#cmakedefine OS ${OS}
|
|
||||||
|
|
||||||
/* Name of package */
|
|
||||||
#cmakedefine PACKAGE ${PACKAGE}
|
|
||||||
|
|
||||||
/* Define to the address where bug reports for this package should be sent. */
|
|
||||||
#cmakedefine PACKAGE_BUGREPORT ${PACKAGE_BUGREPORT}
|
|
||||||
|
|
||||||
/* Define to the full name of this package. */
|
|
||||||
#cmakedefine PACKAGE_NAME ${PACKAGE_NAME}
|
|
||||||
|
|
||||||
/* Define to the full name and version of this package. */
|
|
||||||
#cmakedefine PACKAGE_STRING ${PACKAGE_STRING}
|
|
||||||
|
|
||||||
/* Define to the one symbol short name of this package. */
|
|
||||||
#cmakedefine PACKAGE_TARNAME ${PACKAGE_TARNAME}
|
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
|
||||||
#cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION}
|
|
||||||
|
|
||||||
/* a suitable file to read random data from */
|
|
||||||
#cmakedefine RANDOM_FILE "${RANDOM_FILE}"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Note: SIZEOF_* variables are fetched with CMake through check_type_size().
|
|
||||||
As per CMake documentation on CheckTypeSize, C preprocessor code is
|
|
||||||
generated by CMake into SIZEOF_*_CODE. This is what we use in the
|
|
||||||
following statements.
|
|
||||||
|
|
||||||
Reference: https://cmake.org/cmake/help/latest/module/CheckTypeSize.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* The size of `int', as computed by sizeof. */
|
|
||||||
${SIZEOF_INT_CODE}
|
|
||||||
|
|
||||||
/* The size of `short', as computed by sizeof. */
|
|
||||||
${SIZEOF_SHORT_CODE}
|
|
||||||
|
|
||||||
/* The size of `long', as computed by sizeof. */
|
|
||||||
${SIZEOF_LONG_CODE}
|
|
||||||
|
|
||||||
/* The size of `long long', as computed by sizeof. */
|
|
||||||
${SIZEOF_LONG_LONG_CODE}
|
|
||||||
|
|
||||||
/* The size of `__int64', as computed by sizeof. */
|
|
||||||
${SIZEOF___INT64_CODE}
|
|
||||||
|
|
||||||
/* The size of `off_t', as computed by sizeof. */
|
|
||||||
${SIZEOF_OFF_T_CODE}
|
|
||||||
|
|
||||||
/* The size of `curl_off_t', as computed by sizeof. */
|
|
||||||
${SIZEOF_CURL_OFF_T_CODE}
|
|
||||||
|
|
||||||
/* The size of `size_t', as computed by sizeof. */
|
|
||||||
${SIZEOF_SIZE_T_CODE}
|
|
||||||
|
|
||||||
/* The size of `ssize_t', as computed by sizeof. */
|
|
||||||
${SIZEOF_SSIZE_T_CODE}
|
|
||||||
|
|
||||||
/* The size of `time_t', as computed by sizeof. */
|
|
||||||
${SIZEOF_TIME_T_CODE}
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
|
||||||
#cmakedefine STDC_HEADERS 1
|
|
||||||
|
|
||||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
|
||||||
#cmakedefine TIME_WITH_SYS_TIME 1
|
|
||||||
|
|
||||||
/* Define if you want to enable c-ares support */
|
|
||||||
#cmakedefine USE_ARES 1
|
|
||||||
|
|
||||||
/* Define if you want to enable POSIX threaded DNS lookup */
|
|
||||||
#cmakedefine USE_THREADS_POSIX 1
|
|
||||||
|
|
||||||
/* Define if you want to enable WIN32 threaded DNS lookup */
|
|
||||||
#cmakedefine USE_THREADS_WIN32 1
|
|
||||||
|
|
||||||
/* if GnuTLS is enabled */
|
|
||||||
#cmakedefine USE_GNUTLS 1
|
|
||||||
|
|
||||||
/* if Secure Transport is enabled */
|
|
||||||
#cmakedefine USE_SECTRANSP 1
|
|
||||||
|
|
||||||
/* if mbedTLS is enabled */
|
|
||||||
#cmakedefine USE_MBEDTLS 1
|
|
||||||
|
|
||||||
/* if BearSSL is enabled */
|
|
||||||
#cmakedefine USE_BEARSSL 1
|
|
||||||
|
|
||||||
/* if WolfSSL is enabled */
|
|
||||||
#cmakedefine USE_WOLFSSL 1
|
|
||||||
|
|
||||||
/* if libSSH is in use */
|
|
||||||
#cmakedefine USE_LIBSSH 1
|
|
||||||
|
|
||||||
/* if libSSH2 is in use */
|
|
||||||
#cmakedefine USE_LIBSSH2 1
|
|
||||||
|
|
||||||
/* if libPSL is in use */
|
|
||||||
#cmakedefine USE_LIBPSL 1
|
|
||||||
|
|
||||||
/* If you want to build curl with the built-in manual */
|
|
||||||
#cmakedefine USE_MANUAL 1
|
|
||||||
|
|
||||||
/* if NSS is enabled */
|
|
||||||
#cmakedefine USE_NSS 1
|
|
||||||
|
|
||||||
/* if you have the PK11_CreateManagedGenericObject function */
|
|
||||||
#cmakedefine HAVE_PK11_CREATEMANAGEDGENERICOBJECT 1
|
|
||||||
|
|
||||||
/* if you want to use OpenLDAP code instead of legacy ldap implementation */
|
|
||||||
#cmakedefine USE_OPENLDAP 1
|
|
||||||
|
|
||||||
/* if OpenSSL is in use */
|
|
||||||
#cmakedefine USE_OPENSSL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you don't want the OpenSSL configuration to be loaded
|
|
||||||
automatically */
|
|
||||||
#cmakedefine CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG 1
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
/* to enable msh3 */
|
|
||||||
#cmakedefine USE_MSH3 1
|
|
||||||
|
|
||||||
/* if Unix domain sockets are enabled */
|
|
||||||
#cmakedefine USE_UNIX_SOCKETS
|
|
||||||
|
|
||||||
/* to enable SSPI support */
|
|
||||||
#cmakedefine USE_WINDOWS_SSPI 1
|
|
||||||
|
|
||||||
/* to enable Windows SSL */
|
|
||||||
#cmakedefine USE_SCHANNEL 1
|
|
||||||
|
|
||||||
/* enable multiple SSL backends */
|
|
||||||
#cmakedefine CURL_WITH_MULTI_SSL 1
|
|
||||||
|
|
||||||
/* Version number of package */
|
|
||||||
#cmakedefine VERSION ${VERSION}
|
|
||||||
|
|
||||||
/* Define to 1 if OS is AIX. */
|
|
||||||
#ifndef _ALL_SOURCE
|
|
||||||
# undef _ALL_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
|
||||||
#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS}
|
|
||||||
|
|
||||||
/* Define for large files, on AIX-style hosts. */
|
|
||||||
#cmakedefine _LARGE_FILES ${_LARGE_FILES}
|
|
||||||
|
|
||||||
/* define this if you need it to compile thread-safe code */
|
|
||||||
#cmakedefine _THREAD_SAFE ${_THREAD_SAFE}
|
|
||||||
|
|
||||||
/* Define to empty if `const' does not conform to ANSI C. */
|
|
||||||
#cmakedefine const ${const}
|
|
||||||
|
|
||||||
/* Type to use in place of in_addr_t when system does not provide it. */
|
|
||||||
#cmakedefine in_addr_t ${in_addr_t}
|
|
||||||
|
|
||||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
|
||||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#undef inline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
|
||||||
#cmakedefine size_t ${size_t}
|
|
||||||
|
|
||||||
/* the signed version of size_t */
|
|
||||||
#ifndef SIZEOF_SSIZE_T
|
|
||||||
# if SIZEOF_LONG == SIZEOF_SIZE_T
|
|
||||||
typedef long ssize_t;
|
|
||||||
# elif SIZEOF_LONG_LONG == SIZEOF_SIZE_T
|
|
||||||
typedef long long ssize_t;
|
|
||||||
# elif SIZEOF___INT64 == SIZEOF_SIZE_T
|
|
||||||
typedef __int64 ssize_t;
|
|
||||||
# else
|
|
||||||
typedef int ssize_t;
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define to 1 if you have the mach_absolute_time function. */
|
|
||||||
#cmakedefine HAVE_MACH_ABSOLUTE_TIME 1
|
|
||||||
|
|
||||||
/* to enable Windows IDN */
|
|
||||||
#cmakedefine USE_WIN32_IDN 1
|
|
||||||
|
|
||||||
/* Define to 1 to enable websocket support. */
|
|
||||||
#cmakedefine USE_WEBSOCKETS 1
|
|
|
@ -1,47 +0,0 @@
|
||||||
#ifndef HEADER_CURL_CTYPE_H
|
|
||||||
#define HEADER_CURL_CTYPE_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#define ISLOWHEXALHA(x) (((x) >= 'a') && ((x) <= 'f'))
|
|
||||||
#define ISUPHEXALHA(x) (((x) >= 'A') && ((x) <= 'F'))
|
|
||||||
|
|
||||||
#define ISLOWCNTRL(x) ((unsigned char)(x) <= 0x1f)
|
|
||||||
#define IS7F(x) ((x) == 0x7f)
|
|
||||||
|
|
||||||
#define ISLOWPRINT(x) (((x) >= 9) && ((x) <= 0x0d))
|
|
||||||
|
|
||||||
#define ISPRINT(x) (ISLOWPRINT(x) || (((x) >= ' ') && ((x) <= 0x7e)))
|
|
||||||
#define ISGRAPH(x) (ISLOWPRINT(x) || (((x) > ' ') && ((x) <= 0x7e)))
|
|
||||||
#define ISCNTRL(x) (ISLOWCNTRL(x) || IS7F(x))
|
|
||||||
#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x))
|
|
||||||
#define ISXDIGIT(x) (ISDIGIT(x) || ISLOWHEXALHA(x) || ISUPHEXALHA(x))
|
|
||||||
#define ISALNUM(x) (ISDIGIT(x) || ISLOWER(x) || ISUPPER(x))
|
|
||||||
#define ISUPPER(x) (((x) >= 'A') && ((x) <= 'Z'))
|
|
||||||
#define ISLOWER(x) (((x) >= 'a') && ((x) <= 'z'))
|
|
||||||
#define ISDIGIT(x) (((x) >= '0') && ((x) <= '9'))
|
|
||||||
#define ISBLANK(x) (((x) == ' ') || ((x) == '\t'))
|
|
||||||
#define ISSPACE(x) (ISBLANK(x) || (((x) >= 0xa) && ((x) <= 0x0d)))
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_CTYPE_H */
|
|
|
@ -1,70 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) Steve Holme, <steve_holme@hotmail.com>.
|
|
||||||
*
|
|
||||||
* 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) && \
|
|
||||||
(defined(USE_GNUTLS) || \
|
|
||||||
defined(USE_NSS) || \
|
|
||||||
defined(USE_SECTRANSP) || \
|
|
||||||
defined(USE_OS400CRYPTO) || \
|
|
||||||
defined(USE_WIN32_CRYPTO))
|
|
||||||
|
|
||||||
#include "curl_des.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_des_set_odd_parity()
|
|
||||||
*
|
|
||||||
* This is used to apply odd parity to the given byte array. It is typically
|
|
||||||
* used by when a cryptography engines doesn't have it's own version.
|
|
||||||
*
|
|
||||||
* The function is a port of the Java based oddParity() function over at:
|
|
||||||
*
|
|
||||||
* https://davenport.sourceforge.net/ntlm.html
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* bytes [in/out] - The data whose parity bits are to be adjusted for
|
|
||||||
* odd parity.
|
|
||||||
* len [out] - The length of the data.
|
|
||||||
*/
|
|
||||||
void Curl_des_set_odd_parity(unsigned char *bytes, size_t len)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
unsigned char b = bytes[i];
|
|
||||||
|
|
||||||
bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^
|
|
||||||
(b >> 4) ^ (b >> 3) ^ (b >> 2) ^
|
|
||||||
(b >> 1)) & 0x01) == 0;
|
|
||||||
|
|
||||||
if(needs_parity)
|
|
||||||
bytes[i] |= 0x01;
|
|
||||||
else
|
|
||||||
bytes[i] &= 0xfe;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,41 +0,0 @@
|
||||||
#ifndef HEADER_CURL_DES_H
|
|
||||||
#define HEADER_CURL_DES_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) Steve Holme, <steve_holme@hotmail.com>.
|
|
||||||
*
|
|
||||||
* 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) && \
|
|
||||||
(defined(USE_GNUTLS) || \
|
|
||||||
defined(USE_NSS) || \
|
|
||||||
defined(USE_SECTRANSP) || \
|
|
||||||
defined(USE_OS400CRYPTO) || \
|
|
||||||
defined(USE_WIN32_CRYPTO))
|
|
||||||
|
|
||||||
/* Applies odd parity to the given byte array */
|
|
||||||
void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_DES_H */
|
|
|
@ -1,84 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include "curl_endian.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_read16_le()
|
|
||||||
*
|
|
||||||
* This function converts a 16-bit integer from the little endian format, as
|
|
||||||
* used in the incoming package to whatever endian format we're using
|
|
||||||
* natively.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* buf [in] - A pointer to a 2 byte buffer.
|
|
||||||
*
|
|
||||||
* Returns the integer.
|
|
||||||
*/
|
|
||||||
unsigned short Curl_read16_le(const unsigned char *buf)
|
|
||||||
{
|
|
||||||
return (unsigned short)(((unsigned short)buf[0]) |
|
|
||||||
((unsigned short)buf[1] << 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_read32_le()
|
|
||||||
*
|
|
||||||
* This function converts a 32-bit integer from the little endian format, as
|
|
||||||
* used in the incoming package to whatever endian format we're using
|
|
||||||
* natively.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* buf [in] - A pointer to a 4 byte buffer.
|
|
||||||
*
|
|
||||||
* Returns the integer.
|
|
||||||
*/
|
|
||||||
unsigned int Curl_read32_le(const unsigned char *buf)
|
|
||||||
{
|
|
||||||
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
|
|
||||||
((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_read16_be()
|
|
||||||
*
|
|
||||||
* This function converts a 16-bit integer from the big endian format, as
|
|
||||||
* used in the incoming package to whatever endian format we're using
|
|
||||||
* natively.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* buf [in] - A pointer to a 2 byte buffer.
|
|
||||||
*
|
|
||||||
* Returns the integer.
|
|
||||||
*/
|
|
||||||
unsigned short Curl_read16_be(const unsigned char *buf)
|
|
||||||
{
|
|
||||||
return (unsigned short)(((unsigned short)buf[0] << 8) |
|
|
||||||
((unsigned short)buf[1]));
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
#ifndef HEADER_CURL_ENDIAN_H
|
|
||||||
#define HEADER_CURL_ENDIAN_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/* Converts a 16-bit integer from little endian */
|
|
||||||
unsigned short Curl_read16_le(const unsigned char *buf);
|
|
||||||
|
|
||||||
/* Converts a 32-bit integer from little endian */
|
|
||||||
unsigned int Curl_read32_le(const unsigned char *buf);
|
|
||||||
|
|
||||||
/* Converts a 16-bit integer from big endian */
|
|
||||||
unsigned short Curl_read16_be(const unsigned char *buf);
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_ENDIAN_H */
|
|
|
@ -1,390 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
#ifndef CURL_DISABLE_FTP
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
#include "curl_fnmatch.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
|
|
||||||
/* The last #include file should be: */
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
#ifndef HAVE_FNMATCH
|
|
||||||
|
|
||||||
#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
|
|
||||||
#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
|
|
||||||
|
|
||||||
#define CURLFNM_NEGATE CURLFNM_CHARSET_LEN
|
|
||||||
|
|
||||||
#define CURLFNM_ALNUM (CURLFNM_CHARSET_LEN + 1)
|
|
||||||
#define CURLFNM_DIGIT (CURLFNM_CHARSET_LEN + 2)
|
|
||||||
#define CURLFNM_XDIGIT (CURLFNM_CHARSET_LEN + 3)
|
|
||||||
#define CURLFNM_ALPHA (CURLFNM_CHARSET_LEN + 4)
|
|
||||||
#define CURLFNM_PRINT (CURLFNM_CHARSET_LEN + 5)
|
|
||||||
#define CURLFNM_BLANK (CURLFNM_CHARSET_LEN + 6)
|
|
||||||
#define CURLFNM_LOWER (CURLFNM_CHARSET_LEN + 7)
|
|
||||||
#define CURLFNM_GRAPH (CURLFNM_CHARSET_LEN + 8)
|
|
||||||
#define CURLFNM_SPACE (CURLFNM_CHARSET_LEN + 9)
|
|
||||||
#define CURLFNM_UPPER (CURLFNM_CHARSET_LEN + 10)
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CURLFNM_SCHS_DEFAULT = 0,
|
|
||||||
CURLFNM_SCHS_RIGHTBR,
|
|
||||||
CURLFNM_SCHS_RIGHTBRLEFTBR
|
|
||||||
} setcharset_state;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CURLFNM_PKW_INIT = 0,
|
|
||||||
CURLFNM_PKW_DDOT
|
|
||||||
} parsekey_state;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CCLASS_OTHER = 0,
|
|
||||||
CCLASS_DIGIT,
|
|
||||||
CCLASS_UPPER,
|
|
||||||
CCLASS_LOWER
|
|
||||||
} char_class;
|
|
||||||
|
|
||||||
#define SETCHARSET_OK 1
|
|
||||||
#define SETCHARSET_FAIL 0
|
|
||||||
|
|
||||||
static int parsekeyword(unsigned char **pattern, unsigned char *charset)
|
|
||||||
{
|
|
||||||
parsekey_state state = CURLFNM_PKW_INIT;
|
|
||||||
#define KEYLEN 10
|
|
||||||
char keyword[KEYLEN] = { 0 };
|
|
||||||
int i;
|
|
||||||
unsigned char *p = *pattern;
|
|
||||||
bool found = FALSE;
|
|
||||||
for(i = 0; !found; i++) {
|
|
||||||
char c = *p++;
|
|
||||||
if(i >= KEYLEN)
|
|
||||||
return SETCHARSET_FAIL;
|
|
||||||
switch(state) {
|
|
||||||
case CURLFNM_PKW_INIT:
|
|
||||||
if(ISLOWER(c))
|
|
||||||
keyword[i] = c;
|
|
||||||
else if(c == ':')
|
|
||||||
state = CURLFNM_PKW_DDOT;
|
|
||||||
else
|
|
||||||
return SETCHARSET_FAIL;
|
|
||||||
break;
|
|
||||||
case CURLFNM_PKW_DDOT:
|
|
||||||
if(c == ']')
|
|
||||||
found = TRUE;
|
|
||||||
else
|
|
||||||
return SETCHARSET_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#undef KEYLEN
|
|
||||||
|
|
||||||
*pattern = p; /* move caller's pattern pointer */
|
|
||||||
if(strcmp(keyword, "digit") == 0)
|
|
||||||
charset[CURLFNM_DIGIT] = 1;
|
|
||||||
else if(strcmp(keyword, "alnum") == 0)
|
|
||||||
charset[CURLFNM_ALNUM] = 1;
|
|
||||||
else if(strcmp(keyword, "alpha") == 0)
|
|
||||||
charset[CURLFNM_ALPHA] = 1;
|
|
||||||
else if(strcmp(keyword, "xdigit") == 0)
|
|
||||||
charset[CURLFNM_XDIGIT] = 1;
|
|
||||||
else if(strcmp(keyword, "print") == 0)
|
|
||||||
charset[CURLFNM_PRINT] = 1;
|
|
||||||
else if(strcmp(keyword, "graph") == 0)
|
|
||||||
charset[CURLFNM_GRAPH] = 1;
|
|
||||||
else if(strcmp(keyword, "space") == 0)
|
|
||||||
charset[CURLFNM_SPACE] = 1;
|
|
||||||
else if(strcmp(keyword, "blank") == 0)
|
|
||||||
charset[CURLFNM_BLANK] = 1;
|
|
||||||
else if(strcmp(keyword, "upper") == 0)
|
|
||||||
charset[CURLFNM_UPPER] = 1;
|
|
||||||
else if(strcmp(keyword, "lower") == 0)
|
|
||||||
charset[CURLFNM_LOWER] = 1;
|
|
||||||
else
|
|
||||||
return SETCHARSET_FAIL;
|
|
||||||
return SETCHARSET_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the character class. */
|
|
||||||
static char_class charclass(unsigned char c)
|
|
||||||
{
|
|
||||||
if(ISUPPER(c))
|
|
||||||
return CCLASS_UPPER;
|
|
||||||
if(ISLOWER(c))
|
|
||||||
return CCLASS_LOWER;
|
|
||||||
if(ISDIGIT(c))
|
|
||||||
return CCLASS_DIGIT;
|
|
||||||
return CCLASS_OTHER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Include a character or a range in set. */
|
|
||||||
static void setcharorrange(unsigned char **pp, unsigned char *charset)
|
|
||||||
{
|
|
||||||
unsigned char *p = (*pp)++;
|
|
||||||
unsigned char c = *p++;
|
|
||||||
|
|
||||||
charset[c] = 1;
|
|
||||||
if(ISALNUM(c) && *p++ == '-') {
|
|
||||||
char_class cc = charclass(c);
|
|
||||||
unsigned char endrange = *p++;
|
|
||||||
|
|
||||||
if(endrange == '\\')
|
|
||||||
endrange = *p++;
|
|
||||||
if(endrange >= c && charclass(endrange) == cc) {
|
|
||||||
while(c++ != endrange)
|
|
||||||
if(charclass(c) == cc) /* Chars in class may be not consecutive. */
|
|
||||||
charset[c] = 1;
|
|
||||||
*pp = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
|
|
||||||
static int setcharset(unsigned char **p, unsigned char *charset)
|
|
||||||
{
|
|
||||||
setcharset_state state = CURLFNM_SCHS_DEFAULT;
|
|
||||||
bool something_found = FALSE;
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
memset(charset, 0, CURLFNM_CHSET_SIZE);
|
|
||||||
for(;;) {
|
|
||||||
c = **p;
|
|
||||||
if(!c)
|
|
||||||
return SETCHARSET_FAIL;
|
|
||||||
|
|
||||||
switch(state) {
|
|
||||||
case CURLFNM_SCHS_DEFAULT:
|
|
||||||
if(c == ']') {
|
|
||||||
if(something_found)
|
|
||||||
return SETCHARSET_OK;
|
|
||||||
something_found = TRUE;
|
|
||||||
state = CURLFNM_SCHS_RIGHTBR;
|
|
||||||
charset[c] = 1;
|
|
||||||
(*p)++;
|
|
||||||
}
|
|
||||||
else if(c == '[') {
|
|
||||||
unsigned char *pp = *p + 1;
|
|
||||||
|
|
||||||
if(*pp++ == ':' && parsekeyword(&pp, charset))
|
|
||||||
*p = pp;
|
|
||||||
else {
|
|
||||||
charset[c] = 1;
|
|
||||||
(*p)++;
|
|
||||||
}
|
|
||||||
something_found = TRUE;
|
|
||||||
}
|
|
||||||
else if(c == '^' || c == '!') {
|
|
||||||
if(!something_found) {
|
|
||||||
if(charset[CURLFNM_NEGATE]) {
|
|
||||||
charset[c] = 1;
|
|
||||||
something_found = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
charset[CURLFNM_NEGATE] = 1; /* negate charset */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
charset[c] = 1;
|
|
||||||
(*p)++;
|
|
||||||
}
|
|
||||||
else if(c == '\\') {
|
|
||||||
c = *(++(*p));
|
|
||||||
if(c)
|
|
||||||
setcharorrange(p, charset);
|
|
||||||
else
|
|
||||||
charset['\\'] = 1;
|
|
||||||
something_found = TRUE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setcharorrange(p, charset);
|
|
||||||
something_found = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CURLFNM_SCHS_RIGHTBR:
|
|
||||||
if(c == '[') {
|
|
||||||
state = CURLFNM_SCHS_RIGHTBRLEFTBR;
|
|
||||||
charset[c] = 1;
|
|
||||||
(*p)++;
|
|
||||||
}
|
|
||||||
else if(c == ']') {
|
|
||||||
return SETCHARSET_OK;
|
|
||||||
}
|
|
||||||
else if(ISPRINT(c)) {
|
|
||||||
charset[c] = 1;
|
|
||||||
(*p)++;
|
|
||||||
state = CURLFNM_SCHS_DEFAULT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a
|
|
||||||
* nonsense warning 'statement not reached' at end of the fnc when
|
|
||||||
* compiling on Solaris */
|
|
||||||
goto fail;
|
|
||||||
break;
|
|
||||||
case CURLFNM_SCHS_RIGHTBRLEFTBR:
|
|
||||||
if(c == ']')
|
|
||||||
return SETCHARSET_OK;
|
|
||||||
state = CURLFNM_SCHS_DEFAULT;
|
|
||||||
charset[c] = 1;
|
|
||||||
(*p)++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fail:
|
|
||||||
return SETCHARSET_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int loop(const unsigned char *pattern, const unsigned char *string,
|
|
||||||
int maxstars)
|
|
||||||
{
|
|
||||||
unsigned char *p = (unsigned char *)pattern;
|
|
||||||
unsigned char *s = (unsigned char *)string;
|
|
||||||
unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
unsigned char *pp;
|
|
||||||
|
|
||||||
switch(*p) {
|
|
||||||
case '*':
|
|
||||||
if(!maxstars)
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
/* Regroup consecutive stars and question marks. This can be done because
|
|
||||||
'*?*?*' can be expressed as '??*'. */
|
|
||||||
for(;;) {
|
|
||||||
if(*++p == '\0')
|
|
||||||
return CURL_FNMATCH_MATCH;
|
|
||||||
if(*p == '?') {
|
|
||||||
if(!*s++)
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
}
|
|
||||||
else if(*p != '*')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Skip string characters until we find a match with pattern suffix. */
|
|
||||||
for(maxstars--; *s; s++) {
|
|
||||||
if(loop(p, s, maxstars) == CURL_FNMATCH_MATCH)
|
|
||||||
return CURL_FNMATCH_MATCH;
|
|
||||||
}
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
case '?':
|
|
||||||
if(!*s)
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
s++;
|
|
||||||
p++;
|
|
||||||
break;
|
|
||||||
case '\0':
|
|
||||||
return *s? CURL_FNMATCH_NOMATCH: CURL_FNMATCH_MATCH;
|
|
||||||
case '\\':
|
|
||||||
if(p[1])
|
|
||||||
p++;
|
|
||||||
if(*s++ != *p++)
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
break;
|
|
||||||
case '[':
|
|
||||||
pp = p + 1; /* Copy in case of syntax error in set. */
|
|
||||||
if(setcharset(&pp, charset)) {
|
|
||||||
int found = FALSE;
|
|
||||||
if(!*s)
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
if(charset[(unsigned int)*s])
|
|
||||||
found = TRUE;
|
|
||||||
else if(charset[CURLFNM_ALNUM])
|
|
||||||
found = ISALNUM(*s);
|
|
||||||
else if(charset[CURLFNM_ALPHA])
|
|
||||||
found = ISALPHA(*s);
|
|
||||||
else if(charset[CURLFNM_DIGIT])
|
|
||||||
found = ISDIGIT(*s);
|
|
||||||
else if(charset[CURLFNM_XDIGIT])
|
|
||||||
found = ISXDIGIT(*s);
|
|
||||||
else if(charset[CURLFNM_PRINT])
|
|
||||||
found = ISPRINT(*s);
|
|
||||||
else if(charset[CURLFNM_SPACE])
|
|
||||||
found = ISSPACE(*s);
|
|
||||||
else if(charset[CURLFNM_UPPER])
|
|
||||||
found = ISUPPER(*s);
|
|
||||||
else if(charset[CURLFNM_LOWER])
|
|
||||||
found = ISLOWER(*s);
|
|
||||||
else if(charset[CURLFNM_BLANK])
|
|
||||||
found = ISBLANK(*s);
|
|
||||||
else if(charset[CURLFNM_GRAPH])
|
|
||||||
found = ISGRAPH(*s);
|
|
||||||
|
|
||||||
if(charset[CURLFNM_NEGATE])
|
|
||||||
found = !found;
|
|
||||||
|
|
||||||
if(!found)
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
p = pp + 1;
|
|
||||||
s++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Syntax error in set; mismatch! */
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if(*p++ != *s++)
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @unittest: 1307
|
|
||||||
*/
|
|
||||||
int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
|
|
||||||
{
|
|
||||||
(void)ptr; /* the argument is specified by the curl_fnmatch_callback
|
|
||||||
prototype, but not used by Curl_fnmatch() */
|
|
||||||
if(!pattern || !string) {
|
|
||||||
return CURL_FNMATCH_FAIL;
|
|
||||||
}
|
|
||||||
return loop((unsigned char *)pattern, (unsigned char *)string, 2);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#include <fnmatch.h>
|
|
||||||
/*
|
|
||||||
* @unittest: 1307
|
|
||||||
*/
|
|
||||||
int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
|
|
||||||
{
|
|
||||||
(void)ptr; /* the argument is specified by the curl_fnmatch_callback
|
|
||||||
prototype, but not used by Curl_fnmatch() */
|
|
||||||
if(!pattern || !string) {
|
|
||||||
return CURL_FNMATCH_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(fnmatch(pattern, string, 0)) {
|
|
||||||
case 0:
|
|
||||||
return CURL_FNMATCH_MATCH;
|
|
||||||
case FNM_NOMATCH:
|
|
||||||
return CURL_FNMATCH_NOMATCH;
|
|
||||||
default:
|
|
||||||
return CURL_FNMATCH_FAIL;
|
|
||||||
}
|
|
||||||
/* not reached */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* if FTP is disabled */
|
|
|
@ -1,46 +0,0 @@
|
||||||
#ifndef HEADER_CURL_FNMATCH_H
|
|
||||||
#define HEADER_CURL_FNMATCH_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#define CURL_FNMATCH_MATCH 0
|
|
||||||
#define CURL_FNMATCH_NOMATCH 1
|
|
||||||
#define CURL_FNMATCH_FAIL 2
|
|
||||||
|
|
||||||
/* default pattern matching function
|
|
||||||
* =================================
|
|
||||||
* Implemented with recursive backtracking, if you want to use Curl_fnmatch,
|
|
||||||
* please note that there is not implemented UTF/UNICODE support.
|
|
||||||
*
|
|
||||||
* Implemented features:
|
|
||||||
* '?' notation, does not match UTF characters
|
|
||||||
* '*' can also work with UTF string
|
|
||||||
* [a-zA-Z0-9] enumeration support
|
|
||||||
*
|
|
||||||
* keywords: alnum, digit, xdigit, alpha, print, blank, lower, graph, space
|
|
||||||
* and upper (use as "[[:alnum:]]")
|
|
||||||
*/
|
|
||||||
int Curl_fnmatch(void *ptr, const char *pattern, const char *string);
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_FNMATCH_H */
|
|
|
@ -1,86 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
|
|
||||||
!defined(CURL_DISABLE_HSTS) || !defined(CURL_DISABLE_NETRC)
|
|
||||||
|
|
||||||
#include "curl_get_line.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
/* The last #include file should be: */
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_get_line() makes sure to only return complete whole lines that fit in
|
|
||||||
* 'len' bytes and end with a newline.
|
|
||||||
*/
|
|
||||||
char *Curl_get_line(char *buf, int len, FILE *input)
|
|
||||||
{
|
|
||||||
bool partial = FALSE;
|
|
||||||
while(1) {
|
|
||||||
char *b = fgets(buf, len, input);
|
|
||||||
|
|
||||||
if(b) {
|
|
||||||
size_t rlen = strlen(b);
|
|
||||||
|
|
||||||
if(!rlen)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(b[rlen-1] == '\n') {
|
|
||||||
/* b is \n terminated */
|
|
||||||
if(partial) {
|
|
||||||
partial = FALSE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
else if(feof(input)) {
|
|
||||||
if(partial)
|
|
||||||
/* Line is already too large to return, ignore rest */
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(rlen + 1 < (size_t) len) {
|
|
||||||
/* b is EOF terminated, insert missing \n */
|
|
||||||
b[rlen] = '\n';
|
|
||||||
b[rlen + 1] = '\0';
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* Maximum buffersize reached + EOF
|
|
||||||
* This line is impossible to add a \n to so we'll ignore it
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* Maximum buffersize reached */
|
|
||||||
partial = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* if not disabled */
|
|
|
@ -1,31 +0,0 @@
|
||||||
#ifndef HEADER_CURL_GET_LINE_H
|
|
||||||
#define HEADER_CURL_GET_LINE_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/* get_line() makes sure to only return complete whole lines that fit in 'len'
|
|
||||||
* bytes and end with a newline. */
|
|
||||||
char *Curl_get_line(char *buf, int len, FILE *input);
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_GET_LINE_H */
|
|
|
@ -1,102 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include "curl_gethostname.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_gethostname() is a wrapper around gethostname() which allows
|
|
||||||
* overriding the host name that the function would normally return.
|
|
||||||
* This capability is used by the test suite to verify exact matching
|
|
||||||
* of NTLM authentication, which exercises libcurl's MD4 and DES code
|
|
||||||
* as well as by the SMTP module when a hostname is not provided.
|
|
||||||
*
|
|
||||||
* For libcurl debug enabled builds host name overriding takes place
|
|
||||||
* when environment variable CURL_GETHOSTNAME is set, using the value
|
|
||||||
* held by the variable to override returned host name.
|
|
||||||
*
|
|
||||||
* Note: The function always returns the un-qualified hostname rather
|
|
||||||
* than being provider dependent.
|
|
||||||
*
|
|
||||||
* For libcurl shared library release builds the test suite preloads
|
|
||||||
* another shared library named libhostname using the LD_PRELOAD
|
|
||||||
* mechanism which intercepts, and might override, the gethostname()
|
|
||||||
* function call. In this case a given platform must support the
|
|
||||||
* LD_PRELOAD mechanism and additionally have environment variable
|
|
||||||
* CURL_GETHOSTNAME set in order to override the returned host name.
|
|
||||||
*
|
|
||||||
* For libcurl static library release builds no overriding takes place.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
|
|
||||||
{
|
|
||||||
#ifndef HAVE_GETHOSTNAME
|
|
||||||
|
|
||||||
/* Allow compilation and return failure when unavailable */
|
|
||||||
(void) name;
|
|
||||||
(void) namelen;
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#else
|
|
||||||
int err;
|
|
||||||
char *dot;
|
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
|
|
||||||
/* Override host name when environment variable CURL_GETHOSTNAME is set */
|
|
||||||
const char *force_hostname = getenv("CURL_GETHOSTNAME");
|
|
||||||
if(force_hostname) {
|
|
||||||
strncpy(name, force_hostname, namelen);
|
|
||||||
err = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
name[0] = '\0';
|
|
||||||
err = gethostname(name, namelen);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* DEBUGBUILD */
|
|
||||||
|
|
||||||
/* The call to system's gethostname() might get intercepted by the
|
|
||||||
libhostname library when libcurl is built as a non-debug shared
|
|
||||||
library when running the test suite. */
|
|
||||||
name[0] = '\0';
|
|
||||||
err = gethostname(name, namelen);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
name[namelen - 1] = '\0';
|
|
||||||
|
|
||||||
if(err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* Truncate domain, leave only machine name */
|
|
||||||
dot = strchr(name, '.');
|
|
||||||
if(dot)
|
|
||||||
*dot = '\0';
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
#ifndef HEADER_CURL_GETHOSTNAME_H
|
|
||||||
#define HEADER_CURL_GETHOSTNAME_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/* Hostname buffer size */
|
|
||||||
#define HOSTNAME_MAX 1024
|
|
||||||
|
|
||||||
/* This returns the local machine's un-qualified hostname */
|
|
||||||
int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen);
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_GETHOSTNAME_H */
|
|
|
@ -1,152 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_GSSAPI
|
|
||||||
|
|
||||||
#include "curl_gssapi.h"
|
|
||||||
#include "sendf.h"
|
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#define CURL_ALIGN8 __attribute__ ((aligned(8)))
|
|
||||||
#else
|
|
||||||
#define CURL_ALIGN8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gss_OID_desc Curl_spnego_mech_oid CURL_ALIGN8 = {
|
|
||||||
6, (char *)"\x2b\x06\x01\x05\x05\x02"
|
|
||||||
};
|
|
||||||
gss_OID_desc Curl_krb5_mech_oid CURL_ALIGN8 = {
|
|
||||||
9, (char *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"
|
|
||||||
};
|
|
||||||
|
|
||||||
OM_uint32 Curl_gss_init_sec_context(
|
|
||||||
struct Curl_easy *data,
|
|
||||||
OM_uint32 *minor_status,
|
|
||||||
gss_ctx_id_t *context,
|
|
||||||
gss_name_t target_name,
|
|
||||||
gss_OID mech_type,
|
|
||||||
gss_channel_bindings_t input_chan_bindings,
|
|
||||||
gss_buffer_t input_token,
|
|
||||||
gss_buffer_t output_token,
|
|
||||||
const bool mutual_auth,
|
|
||||||
OM_uint32 *ret_flags)
|
|
||||||
{
|
|
||||||
OM_uint32 req_flags = GSS_C_REPLAY_FLAG;
|
|
||||||
|
|
||||||
if(mutual_auth)
|
|
||||||
req_flags |= GSS_C_MUTUAL_FLAG;
|
|
||||||
|
|
||||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
|
|
||||||
#ifdef GSS_C_DELEG_POLICY_FLAG
|
|
||||||
req_flags |= GSS_C_DELEG_POLICY_FLAG;
|
|
||||||
#else
|
|
||||||
infof(data, "WARNING: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
|
|
||||||
"compiled in");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
|
|
||||||
req_flags |= GSS_C_DELEG_FLAG;
|
|
||||||
|
|
||||||
return gss_init_sec_context(minor_status,
|
|
||||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
|
||||||
context,
|
|
||||||
target_name,
|
|
||||||
mech_type,
|
|
||||||
req_flags,
|
|
||||||
0, /* time_req */
|
|
||||||
input_chan_bindings,
|
|
||||||
input_token,
|
|
||||||
NULL, /* actual_mech_type */
|
|
||||||
output_token,
|
|
||||||
ret_flags,
|
|
||||||
NULL /* time_rec */);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GSS_LOG_BUFFER_LEN 1024
|
|
||||||
static size_t display_gss_error(OM_uint32 status, int type,
|
|
||||||
char *buf, size_t len) {
|
|
||||||
OM_uint32 maj_stat;
|
|
||||||
OM_uint32 min_stat;
|
|
||||||
OM_uint32 msg_ctx = 0;
|
|
||||||
gss_buffer_desc status_string = GSS_C_EMPTY_BUFFER;
|
|
||||||
|
|
||||||
do {
|
|
||||||
maj_stat = gss_display_status(&min_stat,
|
|
||||||
status,
|
|
||||||
type,
|
|
||||||
GSS_C_NO_OID,
|
|
||||||
&msg_ctx,
|
|
||||||
&status_string);
|
|
||||||
if(maj_stat == GSS_S_COMPLETE && status_string.length > 0) {
|
|
||||||
if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) {
|
|
||||||
len += msnprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
|
|
||||||
"%.*s. ", (int)status_string.length,
|
|
||||||
(char *)status_string.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gss_release_buffer(&min_stat, &status_string);
|
|
||||||
} while(!GSS_ERROR(maj_stat) && msg_ctx);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_gss_log_error()
|
|
||||||
*
|
|
||||||
* This is used to log a GSS-API error status.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* data [in] - The session handle.
|
|
||||||
* prefix [in] - The prefix of the log message.
|
|
||||||
* major [in] - The major status code.
|
|
||||||
* minor [in] - The minor status code.
|
|
||||||
*/
|
|
||||||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
|
||||||
OM_uint32 major, OM_uint32 minor)
|
|
||||||
{
|
|
||||||
char buf[GSS_LOG_BUFFER_LEN];
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
if(major != GSS_S_FAILURE)
|
|
||||||
len = display_gss_error(major, GSS_C_GSS_CODE, buf, len);
|
|
||||||
|
|
||||||
display_gss_error(minor, GSS_C_MECH_CODE, buf, len);
|
|
||||||
|
|
||||||
infof(data, "%s%s", prefix, buf);
|
|
||||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
|
||||||
(void)data;
|
|
||||||
(void)prefix;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_GSSAPI */
|
|
|
@ -1,63 +0,0 @@
|
||||||
#ifndef HEADER_CURL_GSSAPI_H
|
|
||||||
#define HEADER_CURL_GSSAPI_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
#include "urldata.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_GSSAPI
|
|
||||||
extern gss_OID_desc Curl_spnego_mech_oid;
|
|
||||||
extern gss_OID_desc Curl_krb5_mech_oid;
|
|
||||||
|
|
||||||
/* Common method for using GSS-API */
|
|
||||||
OM_uint32 Curl_gss_init_sec_context(
|
|
||||||
struct Curl_easy *data,
|
|
||||||
OM_uint32 *minor_status,
|
|
||||||
gss_ctx_id_t *context,
|
|
||||||
gss_name_t target_name,
|
|
||||||
gss_OID mech_type,
|
|
||||||
gss_channel_bindings_t input_chan_bindings,
|
|
||||||
gss_buffer_t input_token,
|
|
||||||
gss_buffer_t output_token,
|
|
||||||
const bool mutual_auth,
|
|
||||||
OM_uint32 *ret_flags);
|
|
||||||
|
|
||||||
/* Helper to log a GSS-API error status */
|
|
||||||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
|
||||||
OM_uint32 major, OM_uint32 minor);
|
|
||||||
|
|
||||||
/* Provide some definitions missing in old headers */
|
|
||||||
#ifdef HAVE_OLD_GSSMIT
|
|
||||||
#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
|
|
||||||
#define NCOMPAT 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define our privacy and integrity protection values */
|
|
||||||
#define GSSAUTH_P_NONE 1
|
|
||||||
#define GSSAUTH_P_INTEGRITY 2
|
|
||||||
#define GSSAUTH_P_PRIVACY 4
|
|
||||||
|
|
||||||
#endif /* HAVE_GSSAPI */
|
|
||||||
#endif /* HEADER_CURL_GSSAPI_H */
|
|
|
@ -1,76 +0,0 @@
|
||||||
#ifndef HEADER_CURL_HMAC_H
|
|
||||||
#define HEADER_CURL_HMAC_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
#define HMAC_MD5_LENGTH 16
|
|
||||||
|
|
||||||
typedef CURLcode (* HMAC_hinit_func)(void *context);
|
|
||||||
typedef void (* HMAC_hupdate_func)(void *context,
|
|
||||||
const unsigned char *data,
|
|
||||||
unsigned int len);
|
|
||||||
typedef void (* HMAC_hfinal_func)(unsigned char *result, void *context);
|
|
||||||
|
|
||||||
|
|
||||||
/* Per-hash function HMAC parameters. */
|
|
||||||
struct HMAC_params {
|
|
||||||
HMAC_hinit_func
|
|
||||||
hmac_hinit; /* Initialize context procedure. */
|
|
||||||
HMAC_hupdate_func hmac_hupdate; /* Update context with data. */
|
|
||||||
HMAC_hfinal_func hmac_hfinal; /* Get final result procedure. */
|
|
||||||
unsigned int hmac_ctxtsize; /* Context structure size. */
|
|
||||||
unsigned int hmac_maxkeylen; /* Maximum key length (bytes). */
|
|
||||||
unsigned int hmac_resultlen; /* Result length (bytes). */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* HMAC computation context. */
|
|
||||||
struct HMAC_context {
|
|
||||||
const struct HMAC_params *hmac_hash; /* Hash function definition. */
|
|
||||||
void *hmac_hashctxt1; /* Hash function context 1. */
|
|
||||||
void *hmac_hashctxt2; /* Hash function context 2. */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Prototypes. */
|
|
||||||
struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams,
|
|
||||||
const unsigned char *key,
|
|
||||||
unsigned int keylen);
|
|
||||||
int Curl_HMAC_update(struct HMAC_context *context,
|
|
||||||
const unsigned char *data,
|
|
||||||
unsigned int len);
|
|
||||||
int Curl_HMAC_final(struct HMAC_context *context, unsigned char *result);
|
|
||||||
|
|
||||||
CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
|
|
||||||
const unsigned char *key, const size_t keylen,
|
|
||||||
const unsigned char *data, const size_t datalen,
|
|
||||||
unsigned char *output);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_HMAC_H */
|
|
|
@ -1,52 +0,0 @@
|
||||||
#ifndef HEADER_CURL_KRB5_H
|
|
||||||
#define HEADER_CURL_KRB5_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
struct Curl_sec_client_mech {
|
|
||||||
const char *name;
|
|
||||||
size_t size;
|
|
||||||
int (*init)(void *);
|
|
||||||
int (*auth)(void *, struct Curl_easy *data, struct connectdata *);
|
|
||||||
void (*end)(void *);
|
|
||||||
int (*check_prot)(void *, int);
|
|
||||||
int (*encode)(void *, const void *, int, int, void **);
|
|
||||||
int (*decode)(void *, void *, int, int, struct connectdata *);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define AUTH_OK 0
|
|
||||||
#define AUTH_CONTINUE 1
|
|
||||||
#define AUTH_ERROR 2
|
|
||||||
|
|
||||||
#ifdef HAVE_GSSAPI
|
|
||||||
int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn, char *,
|
|
||||||
enum protection_level);
|
|
||||||
void Curl_sec_end(struct connectdata *);
|
|
||||||
CURLcode Curl_sec_login(struct Curl_easy *, struct connectdata *);
|
|
||||||
int Curl_sec_request_prot(struct connectdata *conn, const char *level);
|
|
||||||
#else
|
|
||||||
#define Curl_sec_end(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_KRB5_H */
|
|
|
@ -1,36 +0,0 @@
|
||||||
#ifndef HEADER_CURL_LDAP_H
|
|
||||||
#define HEADER_CURL_LDAP_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef CURL_DISABLE_LDAP
|
|
||||||
extern const struct Curl_handler Curl_handler_ldap;
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_LDAPS) && \
|
|
||||||
((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
|
|
||||||
(!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
|
|
||||||
extern const struct Curl_handler Curl_handler_ldaps;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif /* HEADER_CURL_LDAP_H */
|
|
|
@ -1,223 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
#include "curl_log.h"
|
|
||||||
#include "urldata.h"
|
|
||||||
#include "easyif.h"
|
|
||||||
#include "cfilters.h"
|
|
||||||
#include "timeval.h"
|
|
||||||
#include "multiif.h"
|
|
||||||
#include "strcase.h"
|
|
||||||
|
|
||||||
#include "cf-socket.h"
|
|
||||||
#include "connect.h"
|
|
||||||
#include "http2.h"
|
|
||||||
#include "http_proxy.h"
|
|
||||||
#include "cf-https-connect.h"
|
|
||||||
#include "socks.h"
|
|
||||||
#include "strtok.h"
|
|
||||||
#include "vtls/vtls.h"
|
|
||||||
#include "vquic/vquic.h"
|
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
|
|
||||||
void Curl_debug(struct Curl_easy *data, curl_infotype type,
|
|
||||||
char *ptr, size_t size)
|
|
||||||
{
|
|
||||||
if(data->set.verbose) {
|
|
||||||
static const char s_infotype[CURLINFO_END][3] = {
|
|
||||||
"* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
|
|
||||||
if(data->set.fdebug) {
|
|
||||||
bool inCallback = Curl_is_in_callback(data);
|
|
||||||
Curl_set_in_callback(data, true);
|
|
||||||
(void)(*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
|
|
||||||
Curl_set_in_callback(data, inCallback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch(type) {
|
|
||||||
case CURLINFO_TEXT:
|
|
||||||
case CURLINFO_HEADER_OUT:
|
|
||||||
case CURLINFO_HEADER_IN:
|
|
||||||
fwrite(s_infotype[type], 2, 1, data->set.err);
|
|
||||||
fwrite(ptr, size, 1, data->set.err);
|
|
||||||
break;
|
|
||||||
default: /* nada */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Curl_failf() is for messages stating why we failed.
|
|
||||||
* The message SHALL NOT include any LF or CR.
|
|
||||||
*/
|
|
||||||
void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
|
||||||
if(data->set.verbose || data->set.errorbuffer) {
|
|
||||||
va_list ap;
|
|
||||||
int len;
|
|
||||||
char error[CURL_ERROR_SIZE + 2];
|
|
||||||
va_start(ap, fmt);
|
|
||||||
len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
|
||||||
|
|
||||||
if(data->set.errorbuffer && !data->state.errorbuf) {
|
|
||||||
strcpy(data->set.errorbuffer, error);
|
|
||||||
data->state.errorbuf = TRUE; /* wrote error string */
|
|
||||||
}
|
|
||||||
error[len++] = '\n';
|
|
||||||
error[len] = '\0';
|
|
||||||
Curl_debug(data, CURLINFO_TEXT, error, len);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Curl_infof() is for info message along the way */
|
|
||||||
#define MAXINFO 2048
|
|
||||||
|
|
||||||
void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
|
||||||
if(data && data->set.verbose) {
|
|
||||||
va_list ap;
|
|
||||||
int len;
|
|
||||||
char buffer[MAXINFO + 2];
|
|
||||||
va_start(ap, fmt);
|
|
||||||
len = mvsnprintf(buffer, MAXINFO, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
buffer[len++] = '\n';
|
|
||||||
buffer[len] = '\0';
|
|
||||||
Curl_debug(data, CURLINFO_TEXT, buffer, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
|
|
||||||
void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
|
|
||||||
const char *fmt, ...)
|
|
||||||
{
|
|
||||||
DEBUGASSERT(cf);
|
|
||||||
if(data && Curl_log_cf_is_debug(cf)) {
|
|
||||||
va_list ap;
|
|
||||||
int len;
|
|
||||||
char buffer[MAXINFO + 2];
|
|
||||||
len = msnprintf(buffer, MAXINFO, "[CONN-%ld%s-%s] ",
|
|
||||||
cf->conn->connection_id, cf->sockindex? "/2" : "",
|
|
||||||
cf->cft->name);
|
|
||||||
va_start(ap, fmt);
|
|
||||||
len += mvsnprintf(buffer + len, MAXINFO - len, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
buffer[len++] = '\n';
|
|
||||||
buffer[len] = '\0';
|
|
||||||
Curl_debug(data, CURLINFO_TEXT, buffer, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct Curl_cftype *cf_types[] = {
|
|
||||||
&Curl_cft_tcp,
|
|
||||||
&Curl_cft_udp,
|
|
||||||
&Curl_cft_unix,
|
|
||||||
&Curl_cft_tcp_accept,
|
|
||||||
&Curl_cft_happy_eyeballs,
|
|
||||||
&Curl_cft_setup,
|
|
||||||
#ifdef USE_NGHTTP2
|
|
||||||
&Curl_cft_nghttp2,
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SSL
|
|
||||||
&Curl_cft_ssl,
|
|
||||||
&Curl_cft_ssl_proxy,
|
|
||||||
#endif
|
|
||||||
#if !defined(CURL_DISABLE_PROXY)
|
|
||||||
#if !defined(CURL_DISABLE_HTTP)
|
|
||||||
&Curl_cft_http_proxy,
|
|
||||||
#endif /* !CURL_DISABLE_HTTP */
|
|
||||||
&Curl_cft_haproxy,
|
|
||||||
&Curl_cft_socks_proxy,
|
|
||||||
#endif /* !CURL_DISABLE_PROXY */
|
|
||||||
#ifdef ENABLE_QUIC
|
|
||||||
&Curl_cft_http3,
|
|
||||||
#endif
|
|
||||||
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
|
|
||||||
&Curl_cft_http_connect,
|
|
||||||
#endif
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef ARRAYSIZE
|
|
||||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CURLcode Curl_log_init(void)
|
|
||||||
{
|
|
||||||
const char *setting = getenv("CURL_DEBUG");
|
|
||||||
if(setting) {
|
|
||||||
char *token, *tok_buf, *tmp;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
tmp = strdup(setting);
|
|
||||||
if(!tmp)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
token = strtok_r(tmp, ", ", &tok_buf);
|
|
||||||
while(token) {
|
|
||||||
for(i = 0; cf_types[i]; ++i) {
|
|
||||||
if(strcasecompare(token, cf_types[i]->name)) {
|
|
||||||
cf_types[i]->log_level = CURL_LOG_DEBUG;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
token = strtok_r(NULL, ", ", &tok_buf);
|
|
||||||
}
|
|
||||||
free(tmp);
|
|
||||||
}
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
#else /* DEBUGBUILD */
|
|
||||||
|
|
||||||
CURLcode Curl_log_init(void)
|
|
||||||
{
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
|
|
||||||
void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
|
|
||||||
const char *fmt, ...)
|
|
||||||
{
|
|
||||||
(void)data;
|
|
||||||
(void)cf;
|
|
||||||
(void)fmt;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !DEBUGBUILD */
|
|
|
@ -1,138 +0,0 @@
|
||||||
#ifndef HEADER_CURL_LOG_H
|
|
||||||
#define HEADER_CURL_LOG_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
struct Curl_easy;
|
|
||||||
struct Curl_cfilter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init logging, return != 0 on failure.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_log_init(void);
|
|
||||||
|
|
||||||
|
|
||||||
void Curl_infof(struct Curl_easy *, const char *fmt, ...);
|
|
||||||
void Curl_failf(struct Curl_easy *, const char *fmt, ...);
|
|
||||||
|
|
||||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
|
||||||
|
|
||||||
#if defined(HAVE_VARIADIC_MACROS_C99)
|
|
||||||
#define infof(...) Curl_nop_stmt
|
|
||||||
#elif defined(HAVE_VARIADIC_MACROS_GCC)
|
|
||||||
#define infof(x...) Curl_nop_stmt
|
|
||||||
#else
|
|
||||||
#error "missing VARIADIC macro define, fix and rebuild!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* CURL_DISABLE_VERBOSE_STRINGS */
|
|
||||||
|
|
||||||
#define infof Curl_infof
|
|
||||||
|
|
||||||
#endif /* CURL_DISABLE_VERBOSE_STRINGS */
|
|
||||||
|
|
||||||
#define failf Curl_failf
|
|
||||||
|
|
||||||
|
|
||||||
#define CURL_LOG_DEFAULT 0
|
|
||||||
#define CURL_LOG_DEBUG 1
|
|
||||||
#define CURL_LOG_TRACE 2
|
|
||||||
|
|
||||||
|
|
||||||
/* the function used to output verbose information */
|
|
||||||
void Curl_debug(struct Curl_easy *data, curl_infotype type,
|
|
||||||
char *ptr, size_t size);
|
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
|
|
||||||
/* explainer: we have some mix configuration and werror settings
|
|
||||||
* that define HAVE_VARIADIC_MACROS_C99 even though C89 is enforced
|
|
||||||
* on gnuc and some other compiler. Need to treat carefully.
|
|
||||||
*/
|
|
||||||
#if defined(HAVE_VARIADIC_MACROS_C99) && \
|
|
||||||
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
|
||||||
|
|
||||||
#define LOG_CF(data, cf, ...) \
|
|
||||||
do { if(Curl_log_cf_is_debug(cf)) \
|
|
||||||
Curl_log_cf_debug(data, cf, __VA_ARGS__); } while(0)
|
|
||||||
#else
|
|
||||||
#define LOG_CF Curl_log_cf_debug
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
|
|
||||||
#if defined(__GNUC__) && !defined(printf) && \
|
|
||||||
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
|
||||||
!defined(__MINGW32__)
|
|
||||||
const char *fmt, ...)
|
|
||||||
__attribute__((format(printf, 3, 4)));
|
|
||||||
#else
|
|
||||||
const char *fmt, ...);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Curl_log_cf_is_debug(cf) \
|
|
||||||
((cf) && (cf)->cft->log_level >= CURL_LOG_DEBUG)
|
|
||||||
|
|
||||||
#else /* !DEBUGBUILD */
|
|
||||||
|
|
||||||
#if defined(HAVE_VARIADIC_MACROS_C99) && \
|
|
||||||
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
|
||||||
#define LOG_CF(...) Curl_nop_stmt
|
|
||||||
#define Curl_log_cf_debug(...) Curl_nop_stmt
|
|
||||||
#elif defined(HAVE_VARIADIC_MACROS_GCC) && \
|
|
||||||
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
|
||||||
#define LOG_CF(x...) Curl_nop_stmt
|
|
||||||
#define Curl_log_cf_debug(x...) Curl_nop_stmt
|
|
||||||
#else
|
|
||||||
#define LOG_CF Curl_log_cf_debug
|
|
||||||
/* without c99, we seem unable to completely define away this function. */
|
|
||||||
void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
|
|
||||||
const char *fmt, ...);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Curl_log_cf_is_debug(x) ((void)(x), FALSE)
|
|
||||||
|
|
||||||
#endif /* !DEBUGBUILD */
|
|
||||||
|
|
||||||
#define LOG_CF_IS_DEBUG(x) Curl_log_cf_is_debug(x)
|
|
||||||
|
|
||||||
/* Macros intended for DEBUGF logging, use like:
|
|
||||||
* DEBUGF(infof(data, CFMSG(cf, "this filter %s rocks"), "very much"));
|
|
||||||
* and it will output:
|
|
||||||
* [CONN-1-0][CF-SSL] this filter very much rocks
|
|
||||||
* on connection #1 with sockindex 0 for filter of type "SSL". */
|
|
||||||
#define DMSG(d,msg) \
|
|
||||||
"[CONN-%ld] "msg, (d)->conn->connection_id
|
|
||||||
#define DMSGI(d,i,msg) \
|
|
||||||
"[CONN-%ld-%d] "msg, (d)->conn->connection_id, (i)
|
|
||||||
#define CMSG(c,msg) \
|
|
||||||
"[CONN-%ld] "msg, (c)->connection_id
|
|
||||||
#define CMSGI(c,i,msg) \
|
|
||||||
"[CONN-%ld-%d] "msg, (c)->connection_id, (i)
|
|
||||||
#define CFMSG(cf,msg) \
|
|
||||||
"[CONN-%ld-%d][CF-%s] "msg, (cf)->conn->connection_id, \
|
|
||||||
(cf)->sockindex, (cf)->cft->name
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_LOG_H */
|
|
|
@ -1,38 +0,0 @@
|
||||||
#ifndef HEADER_CURL_MD4_H
|
|
||||||
#define HEADER_CURL_MD4_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
|
|
||||||
|
|
||||||
#define MD4_DIGEST_LENGTH 16
|
|
||||||
|
|
||||||
void Curl_md4it(unsigned char *output, const unsigned char *input,
|
|
||||||
const size_t len);
|
|
||||||
|
|
||||||
#endif /* !defined(CURL_DISABLE_CRYPTO_AUTH) */
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_MD4_H */
|
|
|
@ -1,65 +0,0 @@
|
||||||
#ifndef HEADER_CURL_MD5_H
|
|
||||||
#define HEADER_CURL_MD5_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
|
||||||
#include "curl_hmac.h"
|
|
||||||
|
|
||||||
#define MD5_DIGEST_LEN 16
|
|
||||||
|
|
||||||
typedef CURLcode (* Curl_MD5_init_func)(void *context);
|
|
||||||
typedef void (* Curl_MD5_update_func)(void *context,
|
|
||||||
const unsigned char *data,
|
|
||||||
unsigned int len);
|
|
||||||
typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context);
|
|
||||||
|
|
||||||
struct MD5_params {
|
|
||||||
Curl_MD5_init_func md5_init_func; /* Initialize context procedure */
|
|
||||||
Curl_MD5_update_func md5_update_func; /* Update context with data */
|
|
||||||
Curl_MD5_final_func md5_final_func; /* Get final result procedure */
|
|
||||||
unsigned int md5_ctxtsize; /* Context structure size */
|
|
||||||
unsigned int md5_resultlen; /* Result length (bytes) */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MD5_context {
|
|
||||||
const struct MD5_params *md5_hash; /* Hash function definition */
|
|
||||||
void *md5_hashctx; /* Hash function context */
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct MD5_params Curl_DIGEST_MD5[1];
|
|
||||||
extern const struct HMAC_params Curl_HMAC_MD5[1];
|
|
||||||
|
|
||||||
CURLcode Curl_md5it(unsigned char *output, const unsigned char *input,
|
|
||||||
const size_t len);
|
|
||||||
|
|
||||||
struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params);
|
|
||||||
CURLcode Curl_MD5_update(struct MD5_context *context,
|
|
||||||
const unsigned char *data,
|
|
||||||
unsigned int len);
|
|
||||||
CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_MD5_H */
|
|
|
@ -1,158 +0,0 @@
|
||||||
#ifndef HEADER_CURL_MEMORY_H
|
|
||||||
#define HEADER_CURL_MEMORY_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Nasty internal details ahead...
|
|
||||||
*
|
|
||||||
* File curl_memory.h must be included by _all_ *.c source files
|
|
||||||
* that use memory related functions strdup, malloc, calloc, realloc
|
|
||||||
* or free, and given source file is used to build libcurl library.
|
|
||||||
* It should be included immediately before memdebug.h as the last files
|
|
||||||
* included to avoid undesired interaction with other memory function
|
|
||||||
* headers in dependent libraries.
|
|
||||||
*
|
|
||||||
* There is nearly no exception to above rule. All libcurl source
|
|
||||||
* files in 'lib' subdirectory as well as those living deep inside
|
|
||||||
* 'packages' subdirectories and linked together in order to build
|
|
||||||
* libcurl library shall follow it.
|
|
||||||
*
|
|
||||||
* File lib/strdup.c is an exception, given that it provides a strdup
|
|
||||||
* clone implementation while using malloc. Extra care needed inside
|
|
||||||
* this one.
|
|
||||||
*
|
|
||||||
* The need for curl_memory.h inclusion is due to libcurl's feature
|
|
||||||
* of allowing library user to provide memory replacement functions,
|
|
||||||
* memory callbacks, at runtime with curl_global_init_mem()
|
|
||||||
*
|
|
||||||
* Any *.c source file used to build libcurl library that does not
|
|
||||||
* include curl_memory.h and uses any memory function of the five
|
|
||||||
* mentioned above will compile without any indication, but it will
|
|
||||||
* trigger weird memory related issues at runtime.
|
|
||||||
*
|
|
||||||
* OTOH some source files from 'lib' subdirectory may additionally be
|
|
||||||
* used directly as source code when using some curlx_ functions by
|
|
||||||
* third party programs that don't even use libcurl at all. When using
|
|
||||||
* these source files in this way it is necessary these are compiled
|
|
||||||
* with CURLX_NO_MEMORY_CALLBACKS defined, in order to ensure that no
|
|
||||||
* attempt of calling libcurl's memory callbacks is done from code
|
|
||||||
* which can not use this machinery.
|
|
||||||
*
|
|
||||||
* Notice that libcurl's 'memory tracking' system works chaining into
|
|
||||||
* the memory callback machinery. This implies that when compiling
|
|
||||||
* 'lib' source files with CURLX_NO_MEMORY_CALLBACKS defined this file
|
|
||||||
* disengages usage of libcurl's 'memory tracking' system, defining
|
|
||||||
* MEMDEBUG_NODEFINES and overriding CURLDEBUG purpose.
|
|
||||||
*
|
|
||||||
* CURLX_NO_MEMORY_CALLBACKS takes precedence over CURLDEBUG. This is
|
|
||||||
* done in order to allow building a 'memory tracking' enabled libcurl
|
|
||||||
* and at the same time allow building programs which do not use it.
|
|
||||||
*
|
|
||||||
* Programs and libraries in 'tests' subdirectories have specific
|
|
||||||
* purposes and needs, and as such each one will use whatever fits
|
|
||||||
* best, depending additionally whether it links with libcurl or not.
|
|
||||||
*
|
|
||||||
* Caveat emptor. Proper curlx_* separation is a work in progress
|
|
||||||
* the same as CURLX_NO_MEMORY_CALLBACKS usage, some adjustments may
|
|
||||||
* still be required. IOW don't use them yet, there are sharp edges.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HEADER_CURL_MEMDEBUG_H
|
|
||||||
#error "Header memdebug.h shall not be included before curl_memory.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CURLX_NO_MEMORY_CALLBACKS
|
|
||||||
|
|
||||||
#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */
|
|
||||||
/*
|
|
||||||
* The following memory function replacement typedef's are COPIED from
|
|
||||||
* curl/curl.h and MUST match the originals. We copy them to avoid having to
|
|
||||||
* include curl/curl.h here. We avoid that include since it includes stdio.h
|
|
||||||
* and other headers that may get messed up with defines done here.
|
|
||||||
*/
|
|
||||||
typedef void *(*curl_malloc_callback)(size_t size);
|
|
||||||
typedef void (*curl_free_callback)(void *ptr);
|
|
||||||
typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
|
|
||||||
typedef char *(*curl_strdup_callback)(const char *str);
|
|
||||||
typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
|
|
||||||
#define CURL_DID_MEMORY_FUNC_TYPEDEFS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern curl_malloc_callback Curl_cmalloc;
|
|
||||||
extern curl_free_callback Curl_cfree;
|
|
||||||
extern curl_realloc_callback Curl_crealloc;
|
|
||||||
extern curl_strdup_callback Curl_cstrdup;
|
|
||||||
extern curl_calloc_callback Curl_ccalloc;
|
|
||||||
#if defined(WIN32) && defined(UNICODE)
|
|
||||||
extern curl_wcsdup_callback Curl_cwcsdup;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CURLDEBUG
|
|
||||||
|
|
||||||
/*
|
|
||||||
* libcurl's 'memory tracking' system defines strdup, malloc, calloc,
|
|
||||||
* realloc and free, along with others, in memdebug.h in a different
|
|
||||||
* way although still using memory callbacks forward declared above.
|
|
||||||
* When using the 'memory tracking' system (CURLDEBUG defined) we do
|
|
||||||
* not define here the five memory functions given that definitions
|
|
||||||
* from memdebug.h are the ones that shall be used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#undef strdup
|
|
||||||
#define strdup(ptr) Curl_cstrdup(ptr)
|
|
||||||
#undef malloc
|
|
||||||
#define malloc(size) Curl_cmalloc(size)
|
|
||||||
#undef calloc
|
|
||||||
#define calloc(nbelem,size) Curl_ccalloc(nbelem, size)
|
|
||||||
#undef realloc
|
|
||||||
#define realloc(ptr,size) Curl_crealloc(ptr, size)
|
|
||||||
#undef free
|
|
||||||
#define free(ptr) Curl_cfree(ptr)
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
# ifdef UNICODE
|
|
||||||
# undef wcsdup
|
|
||||||
# define wcsdup(ptr) Curl_cwcsdup(ptr)
|
|
||||||
# undef _wcsdup
|
|
||||||
# define _wcsdup(ptr) Curl_cwcsdup(ptr)
|
|
||||||
# undef _tcsdup
|
|
||||||
# define _tcsdup(ptr) Curl_cwcsdup(ptr)
|
|
||||||
# else
|
|
||||||
# undef _tcsdup
|
|
||||||
# define _tcsdup(ptr) Curl_cstrdup(ptr)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CURLDEBUG */
|
|
||||||
|
|
||||||
#else /* CURLX_NO_MEMORY_CALLBACKS */
|
|
||||||
|
|
||||||
#ifndef MEMDEBUG_NODEFINES
|
|
||||||
#define MEMDEBUG_NODEFINES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CURLX_NO_MEMORY_CALLBACKS */
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_MEMORY_H */
|
|
|
@ -1,64 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
#include "curl_memrchr.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
|
|
||||||
/* The last #include file should be: */
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
#ifndef HAVE_MEMRCHR
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_memrchr()
|
|
||||||
*
|
|
||||||
* Our memrchr() function clone for systems which lack this function. The
|
|
||||||
* memrchr() function is like the memchr() function, except that it searches
|
|
||||||
* backwards from the end of the n bytes pointed to by s instead of forward
|
|
||||||
* from the beginning.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void *
|
|
||||||
Curl_memrchr(const void *s, int c, size_t n)
|
|
||||||
{
|
|
||||||
if(n > 0) {
|
|
||||||
const unsigned char *p = s;
|
|
||||||
const unsigned char *q = s;
|
|
||||||
|
|
||||||
p += n - 1;
|
|
||||||
|
|
||||||
while(p >= q) {
|
|
||||||
if(*p == (unsigned char)c)
|
|
||||||
return (void *)p;
|
|
||||||
p--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_MEMRCHR */
|
|
|
@ -1,46 +0,0 @@
|
||||||
#ifndef HEADER_CURL_MEMRCHR_H
|
|
||||||
#define HEADER_CURL_MEMRCHR_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_MEMRCHR
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
# include <string.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRINGS_H
|
|
||||||
# include <strings.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* HAVE_MEMRCHR */
|
|
||||||
|
|
||||||
void *Curl_memrchr(const void *s, int c, size_t n);
|
|
||||||
|
|
||||||
#define memrchr(x,y,z) Curl_memrchr((x),(y),(z))
|
|
||||||
|
|
||||||
#endif /* HAVE_MEMRCHR */
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_MEMRCHR_H */
|
|
|
@ -1,179 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is 'mem-include-scan' clean, which means memdebug.h and
|
|
||||||
* curl_memory.h are purposely not included in this file. See test 1132.
|
|
||||||
*
|
|
||||||
* The functions in this file are curlx functions which are not tracked by the
|
|
||||||
* curl memory tracker memdebug.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if defined(WIN32)
|
|
||||||
|
|
||||||
#include "curl_multibyte.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MultiByte conversions using Windows kernel32 library.
|
|
||||||
*/
|
|
||||||
|
|
||||||
wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8)
|
|
||||||
{
|
|
||||||
wchar_t *str_w = NULL;
|
|
||||||
|
|
||||||
if(str_utf8) {
|
|
||||||
int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
|
|
||||||
str_utf8, -1, NULL, 0);
|
|
||||||
if(str_w_len > 0) {
|
|
||||||
str_w = malloc(str_w_len * sizeof(wchar_t));
|
|
||||||
if(str_w) {
|
|
||||||
if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
|
||||||
str_w_len) == 0) {
|
|
||||||
free(str_w);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return str_w;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
|
|
||||||
{
|
|
||||||
char *str_utf8 = NULL;
|
|
||||||
|
|
||||||
if(str_w) {
|
|
||||||
int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1,
|
|
||||||
NULL, 0, NULL, NULL);
|
|
||||||
if(bytes > 0) {
|
|
||||||
str_utf8 = malloc(bytes);
|
|
||||||
if(str_utf8) {
|
|
||||||
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes,
|
|
||||||
NULL, NULL) == 0) {
|
|
||||||
free(str_utf8);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return str_utf8;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* WIN32 */
|
|
||||||
|
|
||||||
#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES)
|
|
||||||
|
|
||||||
int curlx_win32_open(const char *filename, int oflag, ...)
|
|
||||||
{
|
|
||||||
int pmode = 0;
|
|
||||||
|
|
||||||
#ifdef _UNICODE
|
|
||||||
int result = -1;
|
|
||||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
va_list param;
|
|
||||||
va_start(param, oflag);
|
|
||||||
if(oflag & O_CREAT)
|
|
||||||
pmode = va_arg(param, int);
|
|
||||||
va_end(param);
|
|
||||||
|
|
||||||
#ifdef _UNICODE
|
|
||||||
if(filename_w) {
|
|
||||||
result = _wopen(filename_w, oflag, pmode);
|
|
||||||
curlx_unicodefree(filename_w);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
errno = EINVAL;
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
return (_open)(filename, oflag, pmode);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
|
||||||
{
|
|
||||||
#ifdef _UNICODE
|
|
||||||
FILE *result = NULL;
|
|
||||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
|
||||||
wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
|
|
||||||
if(filename_w && mode_w)
|
|
||||||
result = _wfopen(filename_w, mode_w);
|
|
||||||
else
|
|
||||||
errno = EINVAL;
|
|
||||||
curlx_unicodefree(filename_w);
|
|
||||||
curlx_unicodefree(mode_w);
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
return (fopen)(filename, mode);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int curlx_win32_stat(const char *path, struct_stat *buffer)
|
|
||||||
{
|
|
||||||
#ifdef _UNICODE
|
|
||||||
int result = -1;
|
|
||||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
|
||||||
if(path_w) {
|
|
||||||
#if defined(USE_WIN32_SMALL_FILES)
|
|
||||||
result = _wstat(path_w, buffer);
|
|
||||||
#else
|
|
||||||
result = _wstati64(path_w, buffer);
|
|
||||||
#endif
|
|
||||||
curlx_unicodefree(path_w);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
errno = EINVAL;
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
#if defined(USE_WIN32_SMALL_FILES)
|
|
||||||
return _stat(path, buffer);
|
|
||||||
#else
|
|
||||||
return _stati64(path, buffer);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int curlx_win32_access(const char *path, int mode)
|
|
||||||
{
|
|
||||||
#if defined(_UNICODE)
|
|
||||||
int result = -1;
|
|
||||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
|
||||||
if(path_w) {
|
|
||||||
result = _waccess(path_w, mode);
|
|
||||||
curlx_unicodefree(path_w);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
errno = EINVAL;
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
return _access(path, mode);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
|
|
|
@ -1,91 +0,0 @@
|
||||||
#ifndef HEADER_CURL_MULTIBYTE_H
|
|
||||||
#define HEADER_CURL_MULTIBYTE_H
|
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if defined(WIN32)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MultiByte conversions using Windows kernel32 library.
|
|
||||||
*/
|
|
||||||
|
|
||||||
wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8);
|
|
||||||
char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w);
|
|
||||||
#endif /* WIN32 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Macros curlx_convert_UTF8_to_tchar(), curlx_convert_tchar_to_UTF8()
|
|
||||||
* and curlx_unicodefree() main purpose is to minimize the number of
|
|
||||||
* preprocessor conditional directives needed by code using these
|
|
||||||
* to differentiate UNICODE from non-UNICODE builds.
|
|
||||||
*
|
|
||||||
* In the case of a non-UNICODE build the tchar strings are char strings that
|
|
||||||
* are duplicated via strdup and remain in whatever the passed in encoding is,
|
|
||||||
* which is assumed to be UTF-8 but may be other encoding. Therefore the
|
|
||||||
* significance of the conversion functions is primarily for UNICODE builds.
|
|
||||||
*
|
|
||||||
* Allocated memory should be free'd with curlx_unicodefree().
|
|
||||||
*
|
|
||||||
* Note: Because these are curlx functions their memory usage is not tracked
|
|
||||||
* by the curl memory tracker memdebug. You'll notice that curlx function-like
|
|
||||||
* macros call free and strdup in parentheses, eg (strdup)(ptr), and that's to
|
|
||||||
* ensure that the curl memdebug override macros do not replace them.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(UNICODE) && defined(WIN32)
|
|
||||||
|
|
||||||
#define curlx_convert_UTF8_to_tchar(ptr) curlx_convert_UTF8_to_wchar((ptr))
|
|
||||||
#define curlx_convert_tchar_to_UTF8(ptr) curlx_convert_wchar_to_UTF8((ptr))
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
unsigned short *tchar_ptr;
|
|
||||||
const unsigned short *const_tchar_ptr;
|
|
||||||
unsigned short *tbyte_ptr;
|
|
||||||
const unsigned short *const_tbyte_ptr;
|
|
||||||
} xcharp_u;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define curlx_convert_UTF8_to_tchar(ptr) (strdup)(ptr)
|
|
||||||
#define curlx_convert_tchar_to_UTF8(ptr) (strdup)(ptr)
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
char *tchar_ptr;
|
|
||||||
const char *const_tchar_ptr;
|
|
||||||
unsigned char *tbyte_ptr;
|
|
||||||
const unsigned char *const_tbyte_ptr;
|
|
||||||
} xcharp_u;
|
|
||||||
|
|
||||||
#endif /* UNICODE && WIN32 */
|
|
||||||
|
|
||||||
#define curlx_unicodefree(ptr) \
|
|
||||||
do { \
|
|
||||||
if(ptr) { \
|
|
||||||
(free)(ptr); \
|
|
||||||
(ptr) = NULL; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#endif /* HEADER_CURL_MULTIBYTE_H */
|
|
|
@ -1,724 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
* _ _ ____ _
|
|
||||||
* Project ___| | | | _ \| |
|
|
||||||
* / __| | | | |_) | |
|
|
||||||
* | (__| |_| | _ <| |___
|
|
||||||
* \___|\___/|_| \_\_____|
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.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.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: curl
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "curl_setup.h"
|
|
||||||
|
|
||||||
#if defined(USE_CURL_NTLM_CORE)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NTLM details:
|
|
||||||
*
|
|
||||||
* https://davenport.sourceforge.net/ntlm.html
|
|
||||||
* https://www.innovation.ch/java/ntlm.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Please keep the SSL backend-specific #if branches in this order:
|
|
||||||
|
|
||||||
1. USE_OPENSSL
|
|
||||||
2. USE_WOLFSSL
|
|
||||||
3. USE_GNUTLS
|
|
||||||
4. USE_NSS
|
|
||||||
5. USE_MBEDTLS
|
|
||||||
6. USE_SECTRANSP
|
|
||||||
7. USE_OS400CRYPTO
|
|
||||||
8. USE_WIN32_CRYPTO
|
|
||||||
|
|
||||||
This ensures that:
|
|
||||||
- the same SSL branch gets activated throughout this source
|
|
||||||
file even if multiple backends are enabled at the same time.
|
|
||||||
- OpenSSL and NSS have higher priority than Windows Crypt, due
|
|
||||||
to issues with the latter supporting NTLM2Session responses
|
|
||||||
in NTLM type-3 messages.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(USE_OPENSSL)
|
|
||||||
#include <openssl/opensslconf.h>
|
|
||||||
#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
|
||||||
#define USE_OPENSSL_DES
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL)
|
|
||||||
|
|
||||||
#if defined(USE_OPENSSL)
|
|
||||||
# include <openssl/des.h>
|
|
||||||
# include <openssl/md5.h>
|
|
||||||
# include <openssl/ssl.h>
|
|
||||||
# include <openssl/rand.h>
|
|
||||||
#else
|
|
||||||
# include <wolfssl/options.h>
|
|
||||||
# include <wolfssl/openssl/des.h>
|
|
||||||
# include <wolfssl/openssl/md5.h>
|
|
||||||
# include <wolfssl/openssl/ssl.h>
|
|
||||||
# include <wolfssl/openssl/rand.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# if (defined(OPENSSL_VERSION_NUMBER) && \
|
|
||||||
(OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
|
|
||||||
# define DES_key_schedule des_key_schedule
|
|
||||||
# define DES_cblock des_cblock
|
|
||||||
# define DES_set_odd_parity des_set_odd_parity
|
|
||||||
# define DES_set_key des_set_key
|
|
||||||
# define DES_ecb_encrypt des_ecb_encrypt
|
|
||||||
# define DESKEY(x) x
|
|
||||||
# define DESKEYARG(x) x
|
|
||||||
# else
|
|
||||||
# define DESKEYARG(x) *x
|
|
||||||
# define DESKEY(x) &x
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(USE_GNUTLS)
|
|
||||||
|
|
||||||
# include <nettle/des.h>
|
|
||||||
|
|
||||||
#elif defined(USE_NSS)
|
|
||||||
|
|
||||||
# include <nss.h>
|
|
||||||
# include <pk11pub.h>
|
|
||||||
# include <hasht.h>
|
|
||||||
|
|
||||||
#elif defined(USE_MBEDTLS)
|
|
||||||
|
|
||||||
# include <mbedtls/des.h>
|
|
||||||
|
|
||||||
#elif defined(USE_SECTRANSP)
|
|
||||||
|
|
||||||
# include <CommonCrypto/CommonCryptor.h>
|
|
||||||
# include <CommonCrypto/CommonDigest.h>
|
|
||||||
|
|
||||||
#elif defined(USE_OS400CRYPTO)
|
|
||||||
# include "cipher.mih" /* mih/cipher */
|
|
||||||
#elif defined(USE_WIN32_CRYPTO)
|
|
||||||
# include <wincrypt.h>
|
|
||||||
#else
|
|
||||||
# error "Can't compile NTLM support without a crypto library with DES."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "urldata.h"
|
|
||||||
#include "strcase.h"
|
|
||||||
#include "curl_ntlm_core.h"
|
|
||||||
#include "curl_md5.h"
|
|
||||||
#include "curl_hmac.h"
|
|
||||||
#include "warnless.h"
|
|
||||||
#include "curl_endian.h"
|
|
||||||
#include "curl_des.h"
|
|
||||||
#include "curl_md4.h"
|
|
||||||
/* The last 3 #include files should be in this order */
|
|
||||||
#include "curl_printf.h"
|
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "memdebug.h"
|
|
||||||
|
|
||||||
#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
|
|
||||||
#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Turns a 56-bit key into being 64-bit wide.
|
|
||||||
*/
|
|
||||||
static void extend_key_56_to_64(const unsigned char *key_56, char *key)
|
|
||||||
{
|
|
||||||
key[0] = key_56[0];
|
|
||||||
key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
|
|
||||||
key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
|
|
||||||
key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
|
|
||||||
key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
|
|
||||||
key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
|
|
||||||
key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
|
|
||||||
key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL)
|
|
||||||
/*
|
|
||||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
|
||||||
* key schedule ks is also set.
|
|
||||||
*/
|
|
||||||
static void setup_des_key(const unsigned char *key_56,
|
|
||||||
DES_key_schedule DESKEYARG(ks))
|
|
||||||
{
|
|
||||||
DES_cblock key;
|
|
||||||
|
|
||||||
/* Expand the 56-bit key to 64-bits */
|
|
||||||
extend_key_56_to_64(key_56, (char *) &key);
|
|
||||||
|
|
||||||
/* Set the key parity to odd */
|
|
||||||
DES_set_odd_parity(&key);
|
|
||||||
|
|
||||||
/* Set the key */
|
|
||||||
DES_set_key_unchecked(&key, ks);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(USE_GNUTLS)
|
|
||||||
|
|
||||||
static void setup_des_key(const unsigned char *key_56,
|
|
||||||
struct des_ctx *des)
|
|
||||||
{
|
|
||||||
char key[8];
|
|
||||||
|
|
||||||
/* Expand the 56-bit key to 64-bits */
|
|
||||||
extend_key_56_to_64(key_56, key);
|
|
||||||
|
|
||||||
/* Set the key parity to odd */
|
|
||||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
|
||||||
|
|
||||||
/* Set the key */
|
|
||||||
des_set_key(des, (const uint8_t *) key);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(USE_NSS)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* encrypt_des() expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of
|
|
||||||
* data, using the expanded key. IN should point to 64 bits of source data,
|
|
||||||
* OUT to a 64 bit output buffer.
|
|
||||||
*/
|
|
||||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
|
||||||
const unsigned char *key_56)
|
|
||||||
{
|
|
||||||
const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
|
|
||||||
char key[8]; /* expanded 64 bit key */
|
|
||||||
SECItem key_item;
|
|
||||||
PK11SymKey *symkey = NULL;
|
|
||||||
SECItem *param = NULL;
|
|
||||||
PK11Context *ctx = NULL;
|
|
||||||
int out_len; /* not used, required by NSS */
|
|
||||||
bool rv = FALSE;
|
|
||||||
|
|
||||||
/* use internal slot for DES encryption (requires NSS to be initialized) */
|
|
||||||
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
|
|
||||||
if(!slot)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Expand the 56-bit key to 64-bits */
|
|
||||||
extend_key_56_to_64(key_56, key);
|
|
||||||
|
|
||||||
/* Set the key parity to odd */
|
|
||||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
|
||||||
|
|
||||||
/* Import the key */
|
|
||||||
key_item.data = (unsigned char *)key;
|
|
||||||
key_item.len = sizeof(key);
|
|
||||||
symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
|
|
||||||
&key_item, NULL);
|
|
||||||
if(!symkey)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* Create the DES encryption context */
|
|
||||||
param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
|
|
||||||
if(!param)
|
|
||||||
goto fail;
|
|
||||||
ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
|
|
||||||
if(!ctx)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* Perform the encryption */
|
|
||||||
if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
|
|
||||||
(unsigned char *)in, /* inbuflen */ 8)
|
|
||||||
&& SECSuccess == PK11_Finalize(ctx))
|
|
||||||
rv = /* all OK */ TRUE;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
/* cleanup */
|
|
||||||
if(ctx)
|
|
||||||
PK11_DestroyContext(ctx, PR_TRUE);
|
|
||||||
if(symkey)
|
|
||||||
PK11_FreeSymKey(symkey);
|
|
||||||
if(param)
|
|
||||||
SECITEM_FreeItem(param, PR_TRUE);
|
|
||||||
PK11_FreeSlot(slot);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(USE_MBEDTLS)
|
|
||||||
|
|
||||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
|
||||||
const unsigned char *key_56)
|
|
||||||
{
|
|
||||||
mbedtls_des_context ctx;
|
|
||||||
char key[8];
|
|
||||||
|
|
||||||
/* Expand the 56-bit key to 64-bits */
|
|
||||||
extend_key_56_to_64(key_56, key);
|
|
||||||
|
|
||||||
/* Set the key parity to odd */
|
|
||||||
mbedtls_des_key_set_parity((unsigned char *) key);
|
|
||||||
|
|
||||||
/* Perform the encryption */
|
|
||||||
mbedtls_des_init(&ctx);
|
|
||||||
mbedtls_des_setkey_enc(&ctx, (unsigned char *) key);
|
|
||||||
return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(USE_SECTRANSP)
|
|
||||||
|
|
||||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
|
||||||
const unsigned char *key_56)
|
|
||||||
{
|
|
||||||
char key[8];
|
|
||||||
size_t out_len;
|
|
||||||
CCCryptorStatus err;
|
|
||||||
|
|
||||||
/* Expand the 56-bit key to 64-bits */
|
|
||||||
extend_key_56_to_64(key_56, key);
|
|
||||||
|
|
||||||
/* Set the key parity to odd */
|
|
||||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
|
||||||
|
|
||||||
/* Perform the encryption */
|
|
||||||
err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
|
|
||||||
kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
|
|
||||||
8 /* outbuflen */, &out_len);
|
|
||||||
|
|
||||||
return err == kCCSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(USE_OS400CRYPTO)
|
|
||||||
|
|
||||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
|
||||||
const unsigned char *key_56)
|
|
||||||
{
|
|
||||||
char key[8];
|
|
||||||
_CIPHER_Control_T ctl;
|
|
||||||
|
|
||||||
/* Setup the cipher control structure */
|
|
||||||
ctl.Func_ID = ENCRYPT_ONLY;
|
|
||||||
ctl.Data_Len = sizeof(key);
|
|
||||||
|
|
||||||
/* Expand the 56-bit key to 64-bits */
|
|
||||||
extend_key_56_to_64(key_56, ctl.Crypto_Key);
|
|
||||||
|
|
||||||
/* Set the key parity to odd */
|
|
||||||
Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
|
|
||||||
|
|
||||||
/* Perform the encryption */
|
|
||||||
_CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(USE_WIN32_CRYPTO)
|
|
||||||
|
|
||||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
|
||||||
const unsigned char *key_56)
|
|
||||||
{
|
|
||||||
HCRYPTPROV hprov;
|
|
||||||
HCRYPTKEY hkey;
|
|
||||||
struct {
|
|
||||||
BLOBHEADER hdr;
|
|
||||||
unsigned int len;
|
|
||||||
char key[8];
|
|
||||||
} blob;
|
|
||||||
DWORD len = 8;
|
|
||||||
|
|
||||||
/* Acquire the crypto provider */
|
|
||||||
if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
|
|
||||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Setup the key blob structure */
|
|
||||||
memset(&blob, 0, sizeof(blob));
|
|
||||||
blob.hdr.bType = PLAINTEXTKEYBLOB;
|
|
||||||
blob.hdr.bVersion = 2;
|
|
||||||
blob.hdr.aiKeyAlg = CALG_DES;
|
|
||||||
blob.len = sizeof(blob.key);
|
|
||||||
|
|
||||||
/* Expand the 56-bit key to 64-bits */
|
|
||||||
extend_key_56_to_64(key_56, blob.key);
|
|
||||||
|
|
||||||
/* Set the key parity to odd */
|
|
||||||
Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
|
|
||||||
|
|
||||||
/* Import the key */
|
|
||||||
if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
|
|
||||||
CryptReleaseContext(hprov, 0);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(out, in, 8);
|
|
||||||
|
|
||||||
/* Perform the encryption */
|
|
||||||
CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len);
|
|
||||||
|
|
||||||
CryptDestroyKey(hkey);
|
|
||||||
CryptReleaseContext(hprov, 0);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* defined(USE_WIN32_CRYPTO) */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
|
|
||||||
* 8 byte plaintext is encrypted with each key and the resulting 24
|
|
||||||
* bytes are stored in the results array.
|
|
||||||
*/
|
|
||||||
void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
|
||||||
const unsigned char *plaintext,
|
|
||||||
unsigned char *results)
|
|
||||||
{
|
|
||||||
#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL)
|
|
||||||
DES_key_schedule ks;
|
|
||||||
|
|
||||||
setup_des_key(keys, DESKEY(ks));
|
|
||||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
|
|
||||||
DESKEY(ks), DES_ENCRYPT);
|
|
||||||
|
|
||||||
setup_des_key(keys + 7, DESKEY(ks));
|
|
||||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8),
|
|
||||||
DESKEY(ks), DES_ENCRYPT);
|
|
||||||
|
|
||||||
setup_des_key(keys + 14, DESKEY(ks));
|
|
||||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
|
|
||||||
DESKEY(ks), DES_ENCRYPT);
|
|
||||||
#elif defined(USE_GNUTLS)
|
|
||||||
struct des_ctx des;
|
|
||||||
setup_des_key(keys, &des);
|
|
||||||
des_encrypt(&des, 8, results, plaintext);
|
|
||||||
setup_des_key(keys + 7, &des);
|
|
||||||
des_encrypt(&des, 8, results + 8, plaintext);
|
|
||||||
setup_des_key(keys + 14, &des);
|
|
||||||
des_encrypt(&des, 8, results + 16, plaintext);
|
|
||||||
#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|
|
||||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
|
||||||
encrypt_des(plaintext, results, keys);
|
|
||||||
encrypt_des(plaintext, results + 8, keys + 7);
|
|
||||||
encrypt_des(plaintext, results + 16, keys + 14);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up lanmanager hashed password
|
|
||||||
*/
|
|
||||||
CURLcode Curl_ntlm_core_mk_lm_hash(const char *password,
|
|
||||||
unsigned char *lmbuffer /* 21 bytes */)
|
|
||||||
{
|
|
||||||
unsigned char pw[14];
|
|
||||||
static const unsigned char magic[] = {
|
|
||||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
|
||||||
};
|
|
||||||
size_t len = CURLMIN(strlen(password), 14);
|
|
||||||
|
|
||||||
Curl_strntoupper((char *)pw, password, len);
|
|
||||||
memset(&pw[len], 0, 14 - len);
|
|
||||||
|
|
||||||
{
|
|
||||||
/* Create LanManager hashed password. */
|
|
||||||
|
|
||||||
#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL)
|
|
||||||
DES_key_schedule ks;
|
|
||||||
|
|
||||||
setup_des_key(pw, DESKEY(ks));
|
|
||||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
|
|
||||||
DESKEY(ks), DES_ENCRYPT);
|
|
||||||
|
|
||||||
setup_des_key(pw + 7, DESKEY(ks));
|
|
||||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
|
|
||||||
DESKEY(ks), DES_ENCRYPT);
|
|
||||||
#elif defined(USE_GNUTLS)
|
|
||||||
struct des_ctx des;
|
|
||||||
setup_des_key(pw, &des);
|
|
||||||
des_encrypt(&des, 8, lmbuffer, magic);
|
|
||||||
setup_des_key(pw + 7, &des);
|
|
||||||
des_encrypt(&des, 8, lmbuffer + 8, magic);
|
|
||||||
#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|
|
||||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
|
||||||
encrypt_des(magic, lmbuffer, pw);
|
|
||||||
encrypt_des(magic, lmbuffer + 8, pw + 7);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(lmbuffer + 16, 0, 21 - 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
|
||||||
size_t srclen)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
for(i = 0; i < srclen; i++) {
|
|
||||||
dest[2 * i] = (unsigned char)src[i];
|
|
||||||
dest[2 * i + 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(USE_WINDOWS_SSPI)
|
|
||||||
|
|
||||||
static void ascii_uppercase_to_unicode_le(unsigned char *dest,
|
|
||||||
const char *src, size_t srclen)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
for(i = 0; i < srclen; i++) {
|
|
||||||
dest[2 * i] = (unsigned char)(Curl_raw_toupper(src[i]));
|
|
||||||
dest[2 * i + 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !USE_WINDOWS_SSPI */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up nt hashed passwords
|
|
||||||
* @unittest: 1600
|
|
||||||
*/
|
|
||||||
CURLcode Curl_ntlm_core_mk_nt_hash(const char *password,
|
|
||||||
unsigned char *ntbuffer /* 21 bytes */)
|
|
||||||
{
|
|
||||||
size_t len = strlen(password);
|
|
||||||
unsigned char *pw;
|
|
||||||
if(len > SIZE_T_MAX/2) /* avoid integer overflow */
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
pw = len ? malloc(len * 2) : (unsigned char *)strdup("");
|
|
||||||
if(!pw)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
ascii_to_unicode_le(pw, password, len);
|
|
||||||
|
|
||||||
/* Create NT hashed password. */
|
|
||||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
|
||||||
memset(ntbuffer + 16, 0, 21 - 16);
|
|
||||||
|
|
||||||
free(pw);
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(USE_WINDOWS_SSPI)
|
|
||||||
|
|
||||||
/* Timestamp in tenths of a microsecond since January 1, 1601 00:00:00 UTC. */
|
|
||||||
struct ms_filetime {
|
|
||||||
unsigned int dwLowDateTime;
|
|
||||||
unsigned int dwHighDateTime;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Convert a time_t to an MS FILETIME (MS-DTYP section 2.3.3). */
|
|
||||||
static void time2filetime(struct ms_filetime *ft, time_t t)
|
|
||||||
{
|
|
||||||
#if SIZEOF_TIME_T > 4
|
|
||||||
t = (t + CURL_OFF_T_C(11644473600)) * 10000000;
|
|
||||||
ft->dwLowDateTime = (unsigned int) (t & 0xFFFFFFFF);
|
|
||||||
ft->dwHighDateTime = (unsigned int) (t >> 32);
|
|
||||||
#else
|
|
||||||
unsigned int r, s;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
ft->dwLowDateTime = t & 0xFFFFFFFF;
|
|
||||||
ft->dwHighDateTime = 0;
|
|
||||||
|
|
||||||
# ifndef HAVE_TIME_T_UNSIGNED
|
|
||||||
/* Extend sign if needed. */
|
|
||||||
if(ft->dwLowDateTime & 0x80000000)
|
|
||||||
ft->dwHighDateTime = ~0;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Bias seconds to Jan 1, 1601.
|
|
||||||
134774 days = 11644473600 seconds = 0x2B6109100 */
|
|
||||||
r = ft->dwLowDateTime;
|
|
||||||
ft->dwLowDateTime = (ft->dwLowDateTime + 0xB6109100U) & 0xFFFFFFFF;
|
|
||||||
ft->dwHighDateTime += ft->dwLowDateTime < r? 0x03: 0x02;
|
|
||||||
|
|
||||||
/* Convert to tenths of microseconds. */
|
|
||||||
ft->dwHighDateTime *= 10000000;
|
|
||||||
i = 32;
|
|
||||||
do {
|
|
||||||
i -= 8;
|
|
||||||
s = ((ft->dwLowDateTime >> i) & 0xFF) * (10000000 - 1);
|
|
||||||
r = (s << i) & 0xFFFFFFFF;
|
|
||||||
s >>= 1; /* Split shift to avoid width overflow. */
|
|
||||||
s >>= 31 - i;
|
|
||||||
ft->dwLowDateTime = (ft->dwLowDateTime + r) & 0xFFFFFFFF;
|
|
||||||
if(ft->dwLowDateTime < r)
|
|
||||||
s++;
|
|
||||||
ft->dwHighDateTime += s;
|
|
||||||
} while(i);
|
|
||||||
ft->dwHighDateTime &= 0xFFFFFFFF;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
|
|
||||||
* (uppercase UserName + Domain) as the data
|
|
||||||
*/
|
|
||||||
CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
|
||||||
const char *domain, size_t domlen,
|
|
||||||
unsigned char *ntlmhash,
|
|
||||||
unsigned char *ntlmv2hash)
|
|
||||||
{
|
|
||||||
/* Unicode representation */
|
|
||||||
size_t identity_len;
|
|
||||||
unsigned char *identity;
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
if((userlen > CURL_MAX_INPUT_LENGTH) || (domlen > CURL_MAX_INPUT_LENGTH))
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
identity_len = (userlen + domlen) * 2;
|
|
||||||
identity = malloc(identity_len + 1);
|
|
||||||
|
|
||||||
if(!identity)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
ascii_uppercase_to_unicode_le(identity, user, userlen);
|
|
||||||
ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
|
|
||||||
|
|
||||||
result = Curl_hmacit(Curl_HMAC_MD5, ntlmhash, 16, identity, identity_len,
|
|
||||||
ntlmv2hash);
|
|
||||||
free(identity);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_ntlm_core_mk_ntlmv2_resp()
|
|
||||||
*
|
|
||||||
* This creates the NTLMv2 response as set in the ntlm type-3 message.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
|
|
||||||
* challenge_client [in] - The client nonce (8 bytes)
|
|
||||||
* ntlm [in] - The ntlm data struct being used to read TargetInfo
|
|
||||||
and Server challenge received in the type-2 message
|
|
||||||
* ntresp [out] - The address where a pointer to newly allocated
|
|
||||||
* memory holding the NTLMv2 response.
|
|
||||||
* ntresp_len [out] - The length of the output message.
|
|
||||||
*
|
|
||||||
* Returns CURLE_OK on success.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
|
||||||
unsigned char *challenge_client,
|
|
||||||
struct ntlmdata *ntlm,
|
|
||||||
unsigned char **ntresp,
|
|
||||||
unsigned int *ntresp_len)
|
|
||||||
{
|
|
||||||
/* NTLMv2 response structure :
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
0 HMAC MD5 16 bytes
|
|
||||||
------BLOB--------------------------------------------------------------------
|
|
||||||
16 Signature 0x01010000
|
|
||||||
20 Reserved long (0x00000000)
|
|
||||||
24 Timestamp LE, 64-bit signed value representing the number of
|
|
||||||
tenths of a microsecond since January 1, 1601.
|
|
||||||
32 Client Nonce 8 bytes
|
|
||||||
40 Unknown 4 bytes
|
|
||||||
44 Target Info N bytes (from the type-2 message)
|
|
||||||
44+N Unknown 4 bytes
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned int len = 0;
|
|
||||||
unsigned char *ptr = NULL;
|
|
||||||
unsigned char hmac_output[HMAC_MD5_LENGTH];
|
|
||||||
struct ms_filetime tw;
|
|
||||||
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
/* Calculate the timestamp */
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
char *force_timestamp = getenv("CURL_FORCETIME");
|
|
||||||
if(force_timestamp)
|
|
||||||
time2filetime(&tw, (time_t) 0);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
time2filetime(&tw, time(NULL));
|
|
||||||
|
|
||||||
/* Calculate the response len */
|
|
||||||
len = HMAC_MD5_LENGTH + NTLMv2_BLOB_LEN;
|
|
||||||
|
|
||||||
/* Allocate the response */
|
|
||||||
ptr = calloc(1, len);
|
|
||||||
if(!ptr)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
/* Create the BLOB structure */
|
|
||||||
msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN,
|
|
||||||
"%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
|
|
||||||
"%c%c%c%c" /* Reserved = 0 */
|
|
||||||
"%c%c%c%c%c%c%c%c", /* Timestamp */
|
|
||||||
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
|
|
||||||
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
|
|
||||||
0, 0, 0, 0,
|
|
||||||
LONGQUARTET(tw.dwLowDateTime), LONGQUARTET(tw.dwHighDateTime));
|
|
||||||
|
|
||||||
memcpy(ptr + 32, challenge_client, 8);
|
|
||||||
if(ntlm->target_info_len)
|
|
||||||
memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
|
|
||||||
|
|
||||||
/* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
|
|
||||||
memcpy(ptr + 8, &ntlm->nonce[0], 8);
|
|
||||||
result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8,
|
|
||||||
NTLMv2_BLOB_LEN + 8, hmac_output);
|
|
||||||
if(result) {
|
|
||||||
free(ptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Concatenate the HMAC MD5 output with the BLOB */
|
|
||||||
memcpy(ptr, hmac_output, HMAC_MD5_LENGTH);
|
|
||||||
|
|
||||||
/* Return the response */
|
|
||||||
*ntresp = ptr;
|
|
||||||
*ntresp_len = len;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_ntlm_core_mk_lmv2_resp()
|
|
||||||
*
|
|
||||||
* This creates the LMv2 response as used in the ntlm type-3 message.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
|
|
||||||
* challenge_client [in] - The client nonce (8 bytes)
|
|
||||||
* challenge_client [in] - The server challenge (8 bytes)
|
|
||||||
* lmresp [out] - The LMv2 response (24 bytes)
|
|
||||||
*
|
|
||||||
* Returns CURLE_OK on success.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
|
||||||
unsigned char *challenge_client,
|
|
||||||
unsigned char *challenge_server,
|
|
||||||
unsigned char *lmresp)
|
|
||||||
{
|
|
||||||
unsigned char data[16];
|
|
||||||
unsigned char hmac_output[16];
|
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
|
|
||||||
memcpy(&data[0], challenge_server, 8);
|
|
||||||
memcpy(&data[8], challenge_client, 8);
|
|
||||||
|
|
||||||
result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, 16, &data[0], 16,
|
|
||||||
hmac_output);
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
/* Concatenate the HMAC MD5 output with the client nonce */
|
|
||||||
memcpy(lmresp, hmac_output, 16);
|
|
||||||
memcpy(lmresp + 16, challenge_client, 8);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !USE_WINDOWS_SSPI */
|
|
||||||
|
|
||||||
#endif /* USE_CURL_NTLM_CORE */
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue