init repo.
This commit is contained in:
1
third_party/curl/lib/.checksrc
vendored
Normal file
1
third_party/curl/lib/.checksrc
vendored
Normal file
@ -0,0 +1 @@
|
||||
enable STRERROR
|
251
third_party/curl/lib/CMakeLists.txt
vendored
Normal file
251
third_party/curl/lib/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# 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 libcurl)
|
||||
set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library")
|
||||
add_definitions(-DBUILDING_LIBCURL)
|
||||
|
||||
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)
|
||||
|
||||
# DllMain is added later for DLL builds only.
|
||||
list(REMOVE_ITEM CSOURCES dllmain.c)
|
||||
|
||||
list(APPEND HHEADERS ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
|
||||
|
||||
# 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()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_library(
|
||||
curlu # special libcurlu library just for unittests
|
||||
STATIC
|
||||
EXCLUDE_FROM_ALL
|
||||
${HHEADERS} ${CSOURCES}
|
||||
)
|
||||
target_compile_definitions(curlu PUBLIC UNITTESTS CURL_STATICLIB)
|
||||
target_link_libraries(curlu PRIVATE ${CURL_LIBS})
|
||||
endif()
|
||||
|
||||
if(ENABLE_CURLDEBUG)
|
||||
# We must compile these sources separately to avoid memdebug.h redefinitions
|
||||
# applying to them.
|
||||
set_source_files_properties(memdebug.c curl_multibyte.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
|
||||
endif()
|
||||
|
||||
transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
|
||||
include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "SunOS" 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}")
|
||||
else()
|
||||
unset(CMAKESONAME)
|
||||
endif()
|
||||
|
||||
## Library definition
|
||||
|
||||
# Add "_imp" as a suffix before the extension to avoid conflicting with
|
||||
# the statically linked "libcurl.lib" (typically with MSVC)
|
||||
if(WIN32 AND
|
||||
NOT IMPORT_LIB_SUFFIX AND
|
||||
CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL CMAKE_IMPORT_LIBRARY_SUFFIX)
|
||||
set(IMPORT_LIB_SUFFIX "_imp")
|
||||
endif()
|
||||
|
||||
# Whether to do a single compilation pass for libcurl sources and reuse these
|
||||
# objects to generate both static and shared target.
|
||||
if(NOT DEFINED SHARE_LIB_OBJECT)
|
||||
# Enable it by default on platforms where PIC is the default for both shared
|
||||
# and static and there is a way to tell the linker which libcurl symbols it
|
||||
# should export (vs. marking these symbols exportable at compile-time).
|
||||
if(WIN32)
|
||||
set(SHARE_LIB_OBJECT ON)
|
||||
else()
|
||||
# On other platforms, make it an option disabled by default
|
||||
set(SHARE_LIB_OBJECT OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(SHARE_LIB_OBJECT)
|
||||
set(LIB_OBJECT "libcurl_object")
|
||||
add_library(${LIB_OBJECT} OBJECT ${HHEADERS} ${CSOURCES})
|
||||
if(WIN32)
|
||||
# Define CURL_STATICLIB always, to disable __declspec(dllexport) for
|
||||
# exported libcurl symbols. We handle exports via libcurl.def instead.
|
||||
# Except with symbol hiding disabled or debug mode enabled, when we export
|
||||
# _all_ symbols from libcurl DLL, without using libcurl.def.
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND
|
||||
PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB")
|
||||
endif()
|
||||
target_link_libraries(${LIB_OBJECT} PRIVATE ${CURL_LIBS})
|
||||
set_target_properties(${LIB_OBJECT} PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
set_target_properties(${LIB_OBJECT} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_OBJECT} INTERFACE
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
|
||||
|
||||
set(LIB_SOURCE $<TARGET_OBJECTS:${LIB_OBJECT}>)
|
||||
else()
|
||||
set(LIB_SOURCE ${HHEADERS} ${CSOURCES})
|
||||
endif()
|
||||
|
||||
# we want it to be called libcurl on all platforms
|
||||
if(BUILD_STATIC_LIBS)
|
||||
list(APPEND libcurl_export ${LIB_STATIC})
|
||||
add_library(${LIB_STATIC} STATIC ${LIB_SOURCE})
|
||||
add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
|
||||
if(WIN32)
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND
|
||||
PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB")
|
||||
endif()
|
||||
target_link_libraries(${LIB_STATIC} PRIVATE ${CURL_LIBS})
|
||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES
|
||||
PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}"
|
||||
SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
||||
endif()
|
||||
if(CMAKEVERSION AND CMAKESONAME)
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES
|
||||
VERSION ${CMAKEVERSION} SOVERSION ${CMAKESONAME})
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_STATIC} INTERFACE
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
list(APPEND libcurl_export ${LIB_SHARED})
|
||||
add_library(${LIB_SHARED} SHARED ${LIB_SOURCE})
|
||||
add_library(${PROJECT_NAME}::${LIB_SHARED} ALIAS ${LIB_SHARED})
|
||||
if(WIN32 OR CYGWIN)
|
||||
if(CYGWIN)
|
||||
# For cygwin always compile dllmain.c as a separate unit since it
|
||||
# includes windows.h, which shouldn't be included in other units.
|
||||
set_source_files_properties(dllmain.c PROPERTIES
|
||||
SKIP_UNITY_BUILD_INCLUSION ON)
|
||||
endif()
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES dllmain.c)
|
||||
endif()
|
||||
if(WIN32)
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES libcurl.rc)
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "${CURL_SOURCE_DIR}/libcurl.def")
|
||||
endif()
|
||||
endif()
|
||||
target_link_libraries(${LIB_SHARED} PRIVATE ${CURL_LIBS})
|
||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES
|
||||
PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}"
|
||||
IMPORT_PREFIX "" IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
||||
endif()
|
||||
if(CMAKEVERSION AND CMAKESONAME)
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES
|
||||
VERSION ${CMAKEVERSION} SOVERSION ${CMAKESONAME})
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_SHARED} INTERFACE
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
|
||||
endif()
|
||||
|
||||
add_library(${LIB_NAME} ALIAS ${LIB_SELECTED})
|
||||
add_library(${PROJECT_NAME}::${LIB_NAME} ALIAS ${LIB_SELECTED})
|
||||
|
||||
if(CURL_ENABLE_EXPORT_TARGET)
|
||||
if(BUILD_STATIC_LIBS)
|
||||
install(TARGETS ${LIB_STATIC}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${LIB_SHARED}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
export(TARGETS ${libcurl_export}
|
||||
FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
|
||||
NAMESPACE ${PROJECT_NAME}::
|
||||
)
|
||||
endif()
|
148
third_party/curl/lib/Makefile.am
vendored
Normal file
148
third_party/curl/lib/Makefile.am
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# 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
|
||||
#
|
||||
###########################################################################
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
CMAKE_DIST = CMakeLists.txt curl_config.h.cmake
|
||||
|
||||
EXTRA_DIST = Makefile.mk config-win32.h config-win32ce.h config-plan9.h \
|
||||
config-riscos.h config-mac.h curl_config.h.in config-dos.h libcurl.rc \
|
||||
config-amigaos.h config-win32ce.h config-os400.h setup-os400.h \
|
||||
$(CMAKE_DIST) setup-win32.h .checksrc Makefile.soname
|
||||
|
||||
lib_LTLIBRARIES = libcurl.la
|
||||
|
||||
if BUILD_UNITTESTS
|
||||
noinst_LTLIBRARIES = libcurlu.la
|
||||
else
|
||||
noinst_LTLIBRARIES =
|
||||
endif
|
||||
|
||||
# This might hold -Werror
|
||||
CFLAGS += @CURL_CFLAG_EXTRAS@
|
||||
|
||||
# Specify our include paths here, and do it relative to $(top_srcdir) and
|
||||
# $(top_builddir), to ensure that these paths which belong to the library
|
||||
# being currently built and tested are searched before the library which
|
||||
# might possibly already be installed in the system.
|
||||
#
|
||||
# $(top_srcdir)/include is for libcurl's external include files
|
||||
# $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file
|
||||
# $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "private" files
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/lib \
|
||||
-I$(top_srcdir)/lib
|
||||
|
||||
# Prevent LIBS from being used for all link targets
|
||||
LIBS = $(BLANK_AT_MAKETIME)
|
||||
|
||||
include Makefile.soname
|
||||
|
||||
AM_CPPFLAGS += -DBUILDING_LIBCURL
|
||||
AM_LDFLAGS =
|
||||
AM_CFLAGS =
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS)
|
||||
libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS)
|
||||
|
||||
libcurl_la_CPPFLAGS_EXTRA =
|
||||
libcurl_la_LDFLAGS_EXTRA =
|
||||
libcurl_la_CFLAGS_EXTRA =
|
||||
|
||||
if CURL_LT_SHLIB_USE_VERSION_INFO
|
||||
libcurl_la_LDFLAGS_EXTRA += $(VERSIONINFO)
|
||||
endif
|
||||
|
||||
if CURL_LT_SHLIB_USE_NO_UNDEFINED
|
||||
libcurl_la_LDFLAGS_EXTRA += -no-undefined
|
||||
endif
|
||||
|
||||
if CURL_LT_SHLIB_USE_MIMPURE_TEXT
|
||||
libcurl_la_LDFLAGS_EXTRA += -mimpure-text
|
||||
endif
|
||||
|
||||
if CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS
|
||||
libcurl_la_LDFLAGS_EXTRA += -Wl,--version-script=libcurl.vers
|
||||
else
|
||||
# if symbol-hiding is enabled, hide them!
|
||||
if DOING_CURL_SYMBOL_HIDING
|
||||
libcurl_la_LDFLAGS_EXTRA += -export-symbols-regex '^curl_.*'
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_CPPFLAG_CURL_STATICLIB
|
||||
libcurl_la_CPPFLAGS_EXTRA += -DCURL_STATICLIB
|
||||
else
|
||||
if HAVE_WINDRES
|
||||
libcurl_la_SOURCES += $(LIB_RCFILES)
|
||||
$(LIB_RCFILES): $(top_srcdir)/include/curl/curlver.h
|
||||
endif
|
||||
endif
|
||||
|
||||
if DOING_CURL_SYMBOL_HIDING
|
||||
libcurl_la_CPPFLAGS_EXTRA += -DCURL_HIDDEN_SYMBOLS
|
||||
libcurl_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING)
|
||||
endif
|
||||
|
||||
libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA)
|
||||
libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(CURL_LDFLAGS_LIB) $(LIBCURL_LIBS)
|
||||
libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA)
|
||||
|
||||
libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS
|
||||
libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_LIBS)
|
||||
libcurlu_la_CFLAGS = $(AM_CFLAGS)
|
||||
|
||||
CHECKSRC = $(CS_$(V))
|
||||
CS_0 = @echo " RUN " $@;
|
||||
CS_1 =
|
||||
CS_ = $(CS_0)
|
||||
|
||||
checksrc:
|
||||
$(CHECKSRC)(@PERL@ $(top_srcdir)/scripts/checksrc.pl -D$(srcdir) \
|
||||
-W$(srcdir)/curl_config.h $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] \
|
||||
$(srcdir)/vtls/*.[ch] $(srcdir)/vquic/*.[ch] $(srcdir)/vssh/*.[ch])
|
||||
|
||||
if CURLDEBUG
|
||||
# for debug builds, we scan the sources on all regular make invokes
|
||||
all-local: checksrc
|
||||
endif
|
||||
|
||||
# disable the tests that are mostly causing false positives
|
||||
TIDYFLAGS=-checks=-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-optin.performance.Padding,-clang-analyzer-valist.Uninitialized,-clang-analyzer-core.NonNullParamChecker,-clang-analyzer-core.NullDereference -quiet
|
||||
|
||||
TIDY:=clang-tidy
|
||||
|
||||
tidy:
|
||||
$(TIDY) $(CSOURCES) $(TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H
|
||||
|
||||
optiontable:
|
||||
perl optiontable.pl < $(top_srcdir)/include/curl/curl.h > easyoptions.c
|
||||
|
||||
if HAVE_WINDRES
|
||||
.rc.lo:
|
||||
$(LIBTOOL) --tag=RC --mode=compile $(RC) -I$(top_srcdir)/include $(RCFLAGS) -i $< -o $@
|
||||
endif
|
5523
third_party/curl/lib/Makefile.in
vendored
Normal file
5523
third_party/curl/lib/Makefile.in
vendored
Normal file
File diff suppressed because it is too large
Load Diff
381
third_party/curl/lib/Makefile.inc
vendored
Normal file
381
third_party/curl/lib/Makefile.inc
vendored
Normal file
@ -0,0 +1,381 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# 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/cipher_suite.c \
|
||||
vtls/gtls.c \
|
||||
vtls/hostcheck.c \
|
||||
vtls/keylog.c \
|
||||
vtls/mbedtls.c \
|
||||
vtls/mbedtls_threadlock.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/cipher_suite.h \
|
||||
vtls/gtls.h \
|
||||
vtls/hostcheck.h \
|
||||
vtls/keylog.h \
|
||||
vtls/mbedtls.h \
|
||||
vtls/mbedtls_threadlock.h \
|
||||
vtls/openssl.h \
|
||||
vtls/rustls.h \
|
||||
vtls/schannel.h \
|
||||
vtls/schannel_int.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_osslq.c \
|
||||
vquic/curl_quiche.c \
|
||||
vquic/vquic.c \
|
||||
vquic/vquic-tls.c
|
||||
|
||||
LIB_VQUIC_HFILES = \
|
||||
vquic/curl_msh3.h \
|
||||
vquic/curl_ngtcp2.h \
|
||||
vquic/curl_osslq.h \
|
||||
vquic/curl_quiche.h \
|
||||
vquic/vquic.h \
|
||||
vquic/vquic_int.h \
|
||||
vquic/vquic-tls.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 \
|
||||
bufq.c \
|
||||
bufref.c \
|
||||
c-hyper.c \
|
||||
cf-h1-proxy.c \
|
||||
cf-h2-proxy.c \
|
||||
cf-haproxy.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_memrchr.c \
|
||||
curl_multibyte.c \
|
||||
curl_ntlm_core.c \
|
||||
curl_path.c \
|
||||
curl_range.c \
|
||||
curl_rtmp.c \
|
||||
curl_sasl.c \
|
||||
curl_sha512_256.c \
|
||||
curl_sspi.c \
|
||||
curl_threads.c \
|
||||
curl_trc.c \
|
||||
cw-out.c \
|
||||
dict.c \
|
||||
dllmain.c \
|
||||
doh.c \
|
||||
dynbuf.c \
|
||||
dynhds.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 \
|
||||
hash.c \
|
||||
headers.c \
|
||||
hmac.c \
|
||||
hostasyn.c \
|
||||
hostip.c \
|
||||
hostip4.c \
|
||||
hostip6.c \
|
||||
hostsyn.c \
|
||||
hsts.c \
|
||||
http.c \
|
||||
http1.c \
|
||||
http2.c \
|
||||
http_aws_sigv4.c \
|
||||
http_chunks.c \
|
||||
http_digest.c \
|
||||
http_negotiate.c \
|
||||
http_ntlm.c \
|
||||
http_proxy.c \
|
||||
idn.c \
|
||||
if2ip.c \
|
||||
imap.c \
|
||||
inet_ntop.c \
|
||||
inet_pton.c \
|
||||
krb5.c \
|
||||
ldap.c \
|
||||
llist.c \
|
||||
macos.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 \
|
||||
request.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 \
|
||||
bufq.h \
|
||||
bufref.h \
|
||||
c-hyper.h \
|
||||
cf-h1-proxy.h \
|
||||
cf-h2-proxy.h \
|
||||
cf-haproxy.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_md4.h \
|
||||
curl_md5.h \
|
||||
curl_memory.h \
|
||||
curl_memrchr.h \
|
||||
curl_multibyte.h \
|
||||
curl_ntlm_core.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_sha512_256.h \
|
||||
curl_sspi.h \
|
||||
curl_threads.h \
|
||||
curl_trc.h \
|
||||
curlx.h \
|
||||
cw-out.h \
|
||||
dict.h \
|
||||
doh.h \
|
||||
dynbuf.h \
|
||||
dynhds.h \
|
||||
easy_lock.h \
|
||||
easyif.h \
|
||||
easyoptions.h \
|
||||
escape.h \
|
||||
file.h \
|
||||
fileinfo.h \
|
||||
fopen.h \
|
||||
formdata.h \
|
||||
ftp.h \
|
||||
ftplistparser.h \
|
||||
functypes.h \
|
||||
getinfo.h \
|
||||
gopher.h \
|
||||
hash.h \
|
||||
headers.h \
|
||||
hostip.h \
|
||||
hsts.h \
|
||||
http.h \
|
||||
http1.h \
|
||||
http2.h \
|
||||
http_aws_sigv4.h \
|
||||
http_chunks.h \
|
||||
http_digest.h \
|
||||
http_negotiate.h \
|
||||
http_ntlm.h \
|
||||
http_proxy.h \
|
||||
idn.h \
|
||||
if2ip.h \
|
||||
imap.h \
|
||||
inet_ntop.h \
|
||||
inet_pton.h \
|
||||
llist.h \
|
||||
macos.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 \
|
||||
request.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)
|
334
third_party/curl/lib/Makefile.mk
vendored
Normal file
334
third_party/curl/lib/Makefile.mk
vendored
Normal file
@ -0,0 +1,334 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# 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
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# Makefile to build curl parts with GCC-like toolchains and optional features.
|
||||
#
|
||||
# Usage: make -f Makefile.mk CFG=-feat1[-feat2][-feat3][...]
|
||||
# Example: make -f Makefile.mk CFG=-zlib-ssl-libssh2-ipv6
|
||||
#
|
||||
# Look for ' ?=' to find all accepted customization variables.
|
||||
|
||||
# This script is reused by 'src' and 'docs/examples' Makefile.mk scripts.
|
||||
|
||||
ifndef PROOT
|
||||
PROOT := ..
|
||||
LOCAL := 1
|
||||
endif
|
||||
|
||||
### Common
|
||||
|
||||
CFLAGS ?=
|
||||
CPPFLAGS ?=
|
||||
LDFLAGS ?=
|
||||
LIBS ?=
|
||||
|
||||
CROSSPREFIX ?=
|
||||
|
||||
ifeq ($(CC),cc)
|
||||
CC := gcc
|
||||
endif
|
||||
CC := $(CROSSPREFIX)$(CC)
|
||||
AR := $(CROSSPREFIX)$(AR)
|
||||
|
||||
TRIPLET ?= $(shell $(CC) -dumpmachine)
|
||||
|
||||
BIN_EXT :=
|
||||
|
||||
ifneq ($(findstring msdos,$(TRIPLET)),)
|
||||
# Cross-tools: https://github.com/andrewwutw/build-djgpp
|
||||
MSDOS := 1
|
||||
BIN_EXT := .exe
|
||||
else ifneq ($(findstring amigaos,$(TRIPLET)),)
|
||||
# Cross-tools: https://github.com/bebbo/amiga-gcc
|
||||
AMIGA := 1
|
||||
endif
|
||||
|
||||
CPPFLAGS += -I. -I$(PROOT)/include
|
||||
|
||||
### Deprecated settings. For compatibility.
|
||||
|
||||
ifdef WATT_ROOT
|
||||
WATT_PATH := $(realpath $(WATT_ROOT))
|
||||
endif
|
||||
|
||||
### Optional features
|
||||
|
||||
ifneq ($(findstring -debug,$(CFG)),)
|
||||
CFLAGS += -g
|
||||
CPPFLAGS += -DDEBUGBUILD
|
||||
else
|
||||
CPPFLAGS += -DNDEBUG
|
||||
endif
|
||||
ifneq ($(findstring -trackmem,$(CFG)),)
|
||||
CPPFLAGS += -DCURLDEBUG
|
||||
endif
|
||||
ifneq ($(findstring -map,$(CFG)),)
|
||||
MAP := 1
|
||||
endif
|
||||
|
||||
# CPPFLAGS below are only necessary when building libcurl via 'lib' (see
|
||||
# comments below about exceptions). Always include them anyway to match
|
||||
# behavior of other build systems.
|
||||
|
||||
ifneq ($(findstring -sync,$(CFG)),)
|
||||
CPPFLAGS += -DUSE_SYNC_DNS
|
||||
else ifneq ($(findstring -ares,$(CFG)),)
|
||||
LIBCARES_PATH ?= $(PROOT)/../c-ares
|
||||
CPPFLAGS += -DUSE_ARES
|
||||
CPPFLAGS += -I"$(LIBCARES_PATH)/include"
|
||||
LDFLAGS += -L"$(LIBCARES_PATH)/lib"
|
||||
LIBS += -lcares
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -rtmp,$(CFG)),)
|
||||
LIBRTMP_PATH ?= $(PROOT)/../librtmp
|
||||
CPPFLAGS += -DUSE_LIBRTMP
|
||||
CPPFLAGS += -I"$(LIBRTMP_PATH)"
|
||||
LDFLAGS += -L"$(LIBRTMP_PATH)/librtmp"
|
||||
LIBS += -lrtmp
|
||||
ZLIB := 1
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -ssh2,$(CFG)),)
|
||||
LIBSSH2_PATH ?= $(PROOT)/../libssh2
|
||||
CPPFLAGS += -DUSE_LIBSSH2
|
||||
CPPFLAGS += -I"$(LIBSSH2_PATH)/include"
|
||||
LDFLAGS += -L"$(LIBSSH2_PATH)/lib"
|
||||
LIBS += -lssh2
|
||||
else ifneq ($(findstring -libssh,$(CFG)),)
|
||||
LIBSSH_PATH ?= $(PROOT)/../libssh
|
||||
CPPFLAGS += -DUSE_LIBSSH
|
||||
CPPFLAGS += -I"$(LIBSSH_PATH)/include"
|
||||
LDFLAGS += -L"$(LIBSSH_PATH)/lib"
|
||||
LIBS += -lssh
|
||||
else ifneq ($(findstring -wolfssh,$(CFG)),)
|
||||
WOLFSSH_PATH ?= $(PROOT)/../wolfssh
|
||||
CPPFLAGS += -DUSE_WOLFSSH
|
||||
CPPFLAGS += -I"$(WOLFSSH_PATH)/include"
|
||||
LDFLAGS += -L"$(WOLFSSH_PATH)/lib"
|
||||
LIBS += -lwolfssh
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -ssl,$(CFG)),)
|
||||
OPENSSL_PATH ?= $(PROOT)/../openssl
|
||||
CPPFLAGS += -DUSE_OPENSSL
|
||||
CPPFLAGS += -DCURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG
|
||||
OPENSSL_INCLUDE ?= $(OPENSSL_PATH)/include
|
||||
OPENSSL_LIBPATH ?= $(OPENSSL_PATH)/lib
|
||||
CPPFLAGS += -I"$(OPENSSL_INCLUDE)"
|
||||
LDFLAGS += -L"$(OPENSSL_LIBPATH)"
|
||||
OPENSSL_LIBS ?= -lssl -lcrypto
|
||||
LIBS += $(OPENSSL_LIBS)
|
||||
|
||||
ifneq ($(findstring -srp,$(CFG)),)
|
||||
ifneq ($(wildcard $(OPENSSL_INCLUDE)/openssl/srp.h),)
|
||||
# OpenSSL 1.0.1 and later.
|
||||
CPPFLAGS += -DHAVE_OPENSSL_SRP -DUSE_TLS_SRP
|
||||
endif
|
||||
endif
|
||||
SSLLIBS += 1
|
||||
endif
|
||||
ifneq ($(findstring -wolfssl,$(CFG)),)
|
||||
WOLFSSL_PATH ?= $(PROOT)/../wolfssl
|
||||
CPPFLAGS += -DUSE_WOLFSSL
|
||||
CPPFLAGS += -DSIZEOF_LONG_LONG=8
|
||||
CPPFLAGS += -I"$(WOLFSSL_PATH)/include"
|
||||
LDFLAGS += -L"$(WOLFSSL_PATH)/lib"
|
||||
LIBS += -lwolfssl
|
||||
SSLLIBS += 1
|
||||
endif
|
||||
ifneq ($(findstring -mbedtls,$(CFG)),)
|
||||
MBEDTLS_PATH ?= $(PROOT)/../mbedtls
|
||||
CPPFLAGS += -DUSE_MBEDTLS
|
||||
CPPFLAGS += -I"$(MBEDTLS_PATH)/include"
|
||||
LDFLAGS += -L"$(MBEDTLS_PATH)/lib"
|
||||
LIBS += -lmbedtls -lmbedx509 -lmbedcrypto
|
||||
SSLLIBS += 1
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -nghttp2,$(CFG)),)
|
||||
NGHTTP2_PATH ?= $(PROOT)/../nghttp2
|
||||
CPPFLAGS += -DUSE_NGHTTP2
|
||||
CPPFLAGS += -I"$(NGHTTP2_PATH)/include"
|
||||
LDFLAGS += -L"$(NGHTTP2_PATH)/lib"
|
||||
LIBS += -lnghttp2
|
||||
endif
|
||||
|
||||
ifeq ($(findstring -nghttp3,$(CFG))$(findstring -ngtcp2,$(CFG)),-nghttp3-ngtcp2)
|
||||
NGHTTP3_PATH ?= $(PROOT)/../nghttp3
|
||||
CPPFLAGS += -DUSE_NGHTTP3
|
||||
CPPFLAGS += -I"$(NGHTTP3_PATH)/include"
|
||||
LDFLAGS += -L"$(NGHTTP3_PATH)/lib"
|
||||
LIBS += -lnghttp3
|
||||
|
||||
NGTCP2_PATH ?= $(PROOT)/../ngtcp2
|
||||
CPPFLAGS += -DUSE_NGTCP2
|
||||
CPPFLAGS += -I"$(NGTCP2_PATH)/include"
|
||||
LDFLAGS += -L"$(NGTCP2_PATH)/lib"
|
||||
|
||||
NGTCP2_LIBS ?=
|
||||
ifeq ($(NGTCP2_LIBS),)
|
||||
ifneq ($(findstring -ssl,$(CFG)),)
|
||||
ifneq ($(wildcard $(OPENSSL_INCLUDE)/openssl/aead.h),)
|
||||
NGTCP2_LIBS := -lngtcp2_crypto_boringssl
|
||||
else # including libressl
|
||||
NGTCP2_LIBS := -lngtcp2_crypto_quictls
|
||||
endif
|
||||
else ifneq ($(findstring -wolfssl,$(CFG)),)
|
||||
NGTCP2_LIBS := -lngtcp2_crypto_wolfssl
|
||||
endif
|
||||
endif
|
||||
|
||||
LIBS += -lngtcp2 $(NGTCP2_LIBS)
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -zlib,$(CFG))$(ZLIB),)
|
||||
ZLIB_PATH ?= $(PROOT)/../zlib
|
||||
# These CPPFLAGS are also required when compiling the curl tool via 'src'.
|
||||
CPPFLAGS += -DHAVE_LIBZ
|
||||
CPPFLAGS += -I"$(ZLIB_PATH)/include"
|
||||
LDFLAGS += -L"$(ZLIB_PATH)/lib"
|
||||
ZLIB_LIBS ?= -lz
|
||||
LIBS += $(ZLIB_LIBS)
|
||||
ZLIB := 1
|
||||
endif
|
||||
ifneq ($(findstring -zstd,$(CFG)),)
|
||||
ZSTD_PATH ?= $(PROOT)/../zstd
|
||||
CPPFLAGS += -DHAVE_ZSTD
|
||||
CPPFLAGS += -I"$(ZSTD_PATH)/include"
|
||||
LDFLAGS += -L"$(ZSTD_PATH)/lib"
|
||||
ZSTD_LIBS ?= -lzstd
|
||||
LIBS += $(ZSTD_LIBS)
|
||||
endif
|
||||
ifneq ($(findstring -brotli,$(CFG)),)
|
||||
BROTLI_PATH ?= $(PROOT)/../brotli
|
||||
CPPFLAGS += -DHAVE_BROTLI
|
||||
CPPFLAGS += -I"$(BROTLI_PATH)/include"
|
||||
LDFLAGS += -L"$(BROTLI_PATH)/lib"
|
||||
BROTLI_LIBS ?= -lbrotlidec -lbrotlicommon
|
||||
LIBS += $(BROTLI_LIBS)
|
||||
endif
|
||||
ifneq ($(findstring -gsasl,$(CFG)),)
|
||||
LIBGSASL_PATH ?= $(PROOT)/../gsasl
|
||||
CPPFLAGS += -DUSE_GSASL
|
||||
CPPFLAGS += -I"$(LIBGSASL_PATH)/include"
|
||||
LDFLAGS += -L"$(LIBGSASL_PATH)/lib"
|
||||
LIBS += -lgsasl
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -idn2,$(CFG)),)
|
||||
LIBIDN2_PATH ?= $(PROOT)/../libidn2
|
||||
CPPFLAGS += -DUSE_LIBIDN2
|
||||
CPPFLAGS += -I"$(LIBIDN2_PATH)/include"
|
||||
LDFLAGS += -L"$(LIBIDN2_PATH)/lib"
|
||||
LIBS += -lidn2
|
||||
|
||||
ifneq ($(findstring -psl,$(CFG)),)
|
||||
LIBPSL_PATH ?= $(PROOT)/../libpsl
|
||||
CPPFLAGS += -DUSE_LIBPSL
|
||||
CPPFLAGS += -I"$(LIBPSL_PATH)/include"
|
||||
LDFLAGS += -L"$(LIBPSL_PATH)/lib"
|
||||
LIBS += -lpsl
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -ipv6,$(CFG)),)
|
||||
CPPFLAGS += -DUSE_IPV6
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -watt,$(CFG))$(MSDOS),)
|
||||
WATT_PATH ?= $(PROOT)/../watt
|
||||
CPPFLAGS += -I"$(WATT_PATH)/inc"
|
||||
LDFLAGS += -L"$(WATT_PATH)/lib"
|
||||
LIBS += -lwatt
|
||||
endif
|
||||
|
||||
ifneq ($(findstring 11,$(subst $(subst ,, ),,$(SSLLIBS))),)
|
||||
CPPFLAGS += -DCURL_WITH_MULTI_SSL
|
||||
endif
|
||||
|
||||
### Common rules
|
||||
|
||||
OBJ_DIR := $(TRIPLET)
|
||||
|
||||
ifneq ($(findstring /sh,$(SHELL)),)
|
||||
DEL = rm -f $1
|
||||
COPY = -cp -afv $1 $2
|
||||
MKDIR = mkdir -p $1
|
||||
RMDIR = rm -fr $1
|
||||
WHICH = $(SHELL) -c "command -v $1"
|
||||
else
|
||||
DEL = -del 2>NUL /q /f $(subst /,\,$1)
|
||||
COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
|
||||
MKDIR = -md 2>NUL $(subst /,\,$1)
|
||||
RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
|
||||
WHICH = where $1
|
||||
endif
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
$(OBJ_DIR):
|
||||
-$(call MKDIR, $(OBJ_DIR))
|
||||
|
||||
$(OBJ_DIR)/%.o: %.c
|
||||
$(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
@$(call DEL, $(TOCLEAN))
|
||||
@$(RMDIR) $(OBJ_DIR)
|
||||
|
||||
distclean vclean: clean
|
||||
@$(call DEL, $(TARGETS) $(TOVCLEAN))
|
||||
|
||||
### Local
|
||||
|
||||
ifdef LOCAL
|
||||
|
||||
CPPFLAGS += -DBUILDING_LIBCURL
|
||||
|
||||
### Sources and targets
|
||||
|
||||
# Provides CSOURCES, HHEADERS
|
||||
include Makefile.inc
|
||||
|
||||
vpath %.c vauth vquic vssh vtls
|
||||
|
||||
libcurl_a_LIBRARY := libcurl.a
|
||||
|
||||
TARGETS := $(libcurl_a_LIBRARY)
|
||||
|
||||
libcurl_a_OBJECTS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(notdir $(strip $(CSOURCES))))
|
||||
libcurl_a_DEPENDENCIES := $(strip $(CSOURCES) $(HHEADERS))
|
||||
|
||||
TOCLEAN :=
|
||||
TOVCLEAN :=
|
||||
|
||||
### Rules
|
||||
|
||||
$(libcurl_a_LIBRARY): $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES)
|
||||
@$(call DEL, $@)
|
||||
$(AR) rcs $@ $(libcurl_a_OBJECTS)
|
||||
|
||||
all: $(OBJ_DIR) $(TARGETS)
|
||||
endif
|
42
third_party/curl/lib/Makefile.soname
vendored
Normal file
42
third_party/curl/lib/Makefile.soname
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# 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
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
VERSIONCHANGE=12
|
||||
VERSIONADD=0
|
||||
VERSIONDEL=8
|
||||
|
||||
# libtool version:
|
||||
VERSIONINFO=-version-info $(VERSIONCHANGE):$(VERSIONADD):$(VERSIONDEL)
|
||||
# This flag accepts an argument of the form current[:revision[:age]]. So,
|
||||
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
|
||||
# 1.
|
||||
#
|
||||
# Here's the simplified rule guide on how to change -version-info:
|
||||
# (current version is C:R:A)
|
||||
#
|
||||
# 1. if there are only source changes, use C:R+1:A
|
||||
# 2. if interfaces were added use C+1:0:A+1
|
||||
# 3. if interfaces were removed, then use C+1:0:0
|
||||
#
|
||||
# For the full guide on libcurl ABI rules, see docs/libcurl/ABI
|
708
third_party/curl/lib/altsvc.c
vendored
Normal file
708
third_party/curl/lib/altsvc.c
vendored
Normal file
@ -0,0 +1,708 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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"
|
||||
#include "strdup.h"
|
||||
#include "inet_pton.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(1, sizeof(struct altsvc));
|
||||
size_t hlen;
|
||||
size_t dlen;
|
||||
if(!as)
|
||||
return NULL;
|
||||
hlen = strlen(srchost);
|
||||
dlen = strlen(dsthost);
|
||||
DEBUGASSERT(hlen);
|
||||
DEBUGASSERT(dlen);
|
||||
if(!hlen || !dlen) {
|
||||
/* bad input */
|
||||
free(as);
|
||||
return NULL;
|
||||
}
|
||||
if((hlen > 2) && srchost[0] == '[') {
|
||||
/* IPv6 address, strip off brackets */
|
||||
srchost++;
|
||||
hlen -= 2;
|
||||
}
|
||||
else if(srchost[hlen - 1] == '.')
|
||||
/* strip off trailing dot */
|
||||
hlen--;
|
||||
if((dlen > 2) && dsthost[0] == '[') {
|
||||
/* IPv6 address, strip off brackets */
|
||||
dsthost++;
|
||||
dlen -= 2;
|
||||
}
|
||||
|
||||
as->src.host = Curl_memdup0(srchost, hlen);
|
||||
if(!as->src.host)
|
||||
goto error;
|
||||
|
||||
as->dst.host = Curl_memdup0(dsthost, dlen);
|
||||
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_append(&asi->list, 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;
|
||||
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) {
|
||||
struct dynbuf buf;
|
||||
Curl_dyn_init(&buf, MAX_ALTSVC_LINE);
|
||||
while(Curl_get_line(&buf, fp)) {
|
||||
char *lineptr = Curl_dyn_ptr(&buf);
|
||||
while(*lineptr && ISBLANK(*lineptr))
|
||||
lineptr++;
|
||||
if(*lineptr == '#')
|
||||
/* skip commented lines */
|
||||
continue;
|
||||
|
||||
altsvc_add(asi, lineptr);
|
||||
}
|
||||
Curl_dyn_free(&buf); /* free the line buffer */
|
||||
fclose(fp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write this single altsvc entry to a single output line
|
||||
*/
|
||||
|
||||
static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
||||
{
|
||||
struct tm stamp;
|
||||
const char *dst6_pre = "";
|
||||
const char *dst6_post = "";
|
||||
const char *src6_pre = "";
|
||||
const char *src6_post = "";
|
||||
CURLcode result = Curl_gmtime(as->expires, &stamp);
|
||||
if(result)
|
||||
return result;
|
||||
#ifdef USE_IPV6
|
||||
else {
|
||||
char ipv6_unused[16];
|
||||
if(1 == Curl_inet_pton(AF_INET6, as->dst.host, ipv6_unused)) {
|
||||
dst6_pre = "[";
|
||||
dst6_post = "]";
|
||||
}
|
||||
if(1 == Curl_inet_pton(AF_INET6, as->src.host, ipv6_unused)) {
|
||||
src6_pre = "[";
|
||||
src6_post = "]";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fprintf(fp,
|
||||
"%s %s%s%s %u "
|
||||
"%s %s%s%s %u "
|
||||
"\"%d%02d%02d "
|
||||
"%02d:%02d:%02d\" "
|
||||
"%u %d\n",
|
||||
Curl_alpnid2str(as->src.alpnid),
|
||||
src6_pre, as->src.host, src6_post,
|
||||
as->src.port,
|
||||
|
||||
Curl_alpnid2str(as->dst.alpnid),
|
||||
dst6_pre, as->dst.host, dst6_post,
|
||||
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(1, sizeof(struct altsvcinfo));
|
||||
if(!asi)
|
||||
return NULL;
|
||||
Curl_llist_init(&asi->list, NULL);
|
||||
|
||||
/* set default behavior */
|
||||
asi->flags = CURLALTSVC_H1
|
||||
#ifdef USE_HTTP2
|
||||
| CURLALTSVC_H2
|
||||
#endif
|
||||
#ifdef USE_HTTP3
|
||||
| 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);
|
||||
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 altsvc_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);
|
||||
}
|
||||
#undef time
|
||||
#define time(x) altsvc_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;
|
||||
if(*p == '[') {
|
||||
/* pass all valid IPv6 letters - does not handle zone id */
|
||||
len = strspn(++p, "0123456789abcdefABCDEF:.");
|
||||
if(p[len] != ']')
|
||||
/* invalid host syntax, bail out */
|
||||
break;
|
||||
/* we store the IPv6 numerical address *with* brackets */
|
||||
len += 2;
|
||||
p = &p[len-1];
|
||||
}
|
||||
else {
|
||||
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_append(&asi->list, 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 */
|
81
third_party/curl/lib/altsvc.h
vendored
Normal file
81
third_party/curl/lib/altsvc.h
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
#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 */
|
247
third_party/curl/lib/amigaos.c
vendored
Normal file
247
third_party/curl/lib/amigaos.c
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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
|
||||
#include <signal.h>
|
||||
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__ */
|
41
third_party/curl/lib/amigaos.h
vendored
Normal file
41
third_party/curl/lib/amigaos.h
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
#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 */
|
117
third_party/curl/lib/arpa_telnet.h
vendored
Normal file
117
third_party/curl/lib/arpa_telnet.h
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
#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"
|
||||
};
|
||||
#define CURL_TELOPT(x) telnetoptions[x]
|
||||
#else
|
||||
#define CURL_TELOPT(x) ""
|
||||
#endif
|
||||
|
||||
#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON
|
||||
|
||||
#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM)
|
||||
|
||||
#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) )
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM]
|
||||
#else
|
||||
#define CURL_TELCMD(x) ""
|
||||
#endif
|
||||
|
||||
#endif /* CURL_DISABLE_TELNET */
|
||||
|
||||
#endif /* HEADER_CURL_ARPA_TELNET_H */
|
958
third_party/curl/lib/asyn-ares.c
vendored
Normal file
958
third_party/curl/lib/asyn-ares.c
vendored
Normal file
@ -0,0 +1,958 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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. For old c-ares without getaddrinfo.
|
||||
|
||||
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
|
||||
|
||||
#define CARES_TIMEOUT_PER_ATTEMPT 2000
|
||||
|
||||
static int ares_ver = 0;
|
||||
|
||||
/*
|
||||
* 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
|
||||
ares_version(&ares_ver);
|
||||
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;
|
||||
|
||||
/*
|
||||
if c ares < 1.20.0: curl set timeout to CARES_TIMEOUT_PER_ATTEMPT (2s)
|
||||
|
||||
if c-ares >= 1.20.0 it already has the timeout to 2s, curl does not need
|
||||
to set the timeout value;
|
||||
|
||||
if c-ares >= 1.24.0, user can set the timeout via /etc/resolv.conf to
|
||||
overwrite c-ares' timeout.
|
||||
*/
|
||||
DEBUGASSERT(ares_ver);
|
||||
if(ares_ver < 0x011400) {
|
||||
options.timeout = CARES_TIMEOUT_PER_ATTEMPT;
|
||||
optmask |= ARES_OPT_TIMEOUTMS;
|
||||
}
|
||||
|
||||
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 USE_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 USE_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(1, sizeof(struct thread_data) + namelen);
|
||||
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 */
|
||||
if(data->conn->ip_version == CURL_IPRESOLVE_V6)
|
||||
pf = PF_INET6;
|
||||
else
|
||||
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 its 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:
|
||||
DEBUGF(infof(data, "bad servers set"));
|
||||
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) {
|
||||
DEBUGF(infof(data, "bad DNS IPv4 address"));
|
||||
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(USE_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) {
|
||||
DEBUGF(infof(data, "bad DNS IPv6 address"));
|
||||
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 */
|
998
third_party/curl/lib/asyn-thread.c
vendored
Normal file
998
third_party/curl/lib/asyn-thread.c
vendored
Normal file
@ -0,0 +1,998 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 "system_win32.h"
|
||||
#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);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Thread sync data used by GetAddrInfoExW for win8+ */
|
||||
struct thread_sync_data_w8
|
||||
{
|
||||
OVERLAPPED overlapped;
|
||||
ADDRINFOEXW_ *res;
|
||||
HANDLE cancel_ev;
|
||||
ADDRINFOEXW_ hints;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Data for synchronization between resolver thread and its parent */
|
||||
struct thread_sync_data {
|
||||
#ifdef _WIN32
|
||||
struct thread_sync_data_w8 w8;
|
||||
#endif
|
||||
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 {
|
||||
#ifdef _WIN32
|
||||
HANDLE complete_ev;
|
||||
#endif
|
||||
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) {
|
||||
wakeup_close(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 or pipe */
|
||||
if(wakeup_create(&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) {
|
||||
wakeup_close(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 _WIN32
|
||||
static VOID WINAPI
|
||||
query_complete(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlapped)
|
||||
{
|
||||
size_t ss_size;
|
||||
const ADDRINFOEXW_ *ai;
|
||||
struct Curl_addrinfo *ca;
|
||||
struct Curl_addrinfo *cafirst = NULL;
|
||||
struct Curl_addrinfo *calast = NULL;
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-align"
|
||||
#endif
|
||||
struct thread_sync_data *tsd =
|
||||
CONTAINING_RECORD(overlapped, struct thread_sync_data, w8.overlapped);
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
struct thread_data *td = tsd->td;
|
||||
const ADDRINFOEXW_ *res = tsd->w8.res;
|
||||
int error = (int)err;
|
||||
(void)bytes;
|
||||
|
||||
if(error == ERROR_SUCCESS) {
|
||||
/* traverse the addrinfo list */
|
||||
|
||||
for(ai = res; ai != NULL; ai = ai->ai_next) {
|
||||
size_t namelen = ai->ai_canonname ? wcslen(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 USE_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) {
|
||||
size_t i;
|
||||
ca->ai_canonname = (void *)((char *)ca->ai_addr + ss_size);
|
||||
for(i = 0; i < namelen; ++i) /* convert wide string to ascii */
|
||||
ca->ai_canonname[i] = (char)ai->ai_canonname[i];
|
||||
ca->ai_canonname[namelen] = '\0';
|
||||
}
|
||||
|
||||
/* 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, 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
|
||||
}
|
||||
tsd->res = cafirst;
|
||||
}
|
||||
|
||||
if(tsd->w8.res) {
|
||||
Curl_FreeAddrInfoExW(tsd->w8.res);
|
||||
tsd->w8.res = NULL;
|
||||
}
|
||||
|
||||
if(error) {
|
||||
tsd->sock_error = SOCKERRNO?SOCKERRNO:error;
|
||||
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
|
||||
char buf[1];
|
||||
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);
|
||||
if(td->complete_ev)
|
||||
SetEvent(td->complete_ev); /* Notify caller that the query completed */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
|
||||
/*
|
||||
* getaddrinfo_thread() resolves a name and then exits.
|
||||
*
|
||||
* For builds without ARES, but with USE_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(wakeup_write(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) {
|
||||
#ifdef _WIN32
|
||||
if(td->complete_ev) {
|
||||
CloseHandle(td->complete_ev);
|
||||
td->complete_ev = NULL;
|
||||
}
|
||||
#endif
|
||||
if(td->thread_hnd != curl_thread_t_null) {
|
||||
Curl_thread_destroy(td->thread_hnd);
|
||||
td->thread_hnd = curl_thread_t_null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef _WIN32
|
||||
if(td->complete_ev) {
|
||||
Curl_GetAddrInfoExCancel(&td->tsd.w8.cancel_ev);
|
||||
WaitForSingleObject(td->complete_ev, INFINITE);
|
||||
CloseHandle(td->complete_ev);
|
||||
td->complete_ev = NULL;
|
||||
}
|
||||
#endif
|
||||
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);
|
||||
wakeup_close(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;
|
||||
#ifdef _WIN32
|
||||
td->complete_ev = NULL;
|
||||
#endif
|
||||
|
||||
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 _WIN32
|
||||
if(Curl_isWindows8OrGreater && Curl_FreeAddrInfoExW &&
|
||||
Curl_GetAddrInfoExCancel && Curl_GetAddrInfoExW) {
|
||||
#define MAX_NAME_LEN 256 /* max domain name is 253 chars */
|
||||
#define MAX_PORT_LEN 8
|
||||
WCHAR namebuf[MAX_NAME_LEN];
|
||||
WCHAR portbuf[MAX_PORT_LEN];
|
||||
/* calculate required length */
|
||||
int w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, hostname,
|
||||
-1, NULL, 0);
|
||||
if((w_len > 0) && (w_len < MAX_NAME_LEN)) {
|
||||
/* do utf8 conversion */
|
||||
w_len = MultiByteToWideChar(CP_UTF8, 0, hostname, -1, namebuf, w_len);
|
||||
if((w_len > 0) && (w_len < MAX_NAME_LEN)) {
|
||||
swprintf(portbuf, MAX_PORT_LEN, L"%d", port);
|
||||
td->tsd.w8.hints.ai_family = hints->ai_family;
|
||||
td->tsd.w8.hints.ai_socktype = hints->ai_socktype;
|
||||
td->complete_ev = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if(!td->complete_ev) {
|
||||
/* failed to start, mark it as done here for proper cleanup. */
|
||||
td->tsd.done = 1;
|
||||
goto err_exit;
|
||||
}
|
||||
err = Curl_GetAddrInfoExW(namebuf, portbuf, NS_DNS,
|
||||
NULL, &td->tsd.w8.hints, &td->tsd.w8.res,
|
||||
NULL, &td->tsd.w8.overlapped,
|
||||
&query_complete, &td->tsd.w8.cancel_ev);
|
||||
if(err != WSA_IO_PENDING)
|
||||
query_complete(err, 0, &td->tsd.w8.overlapped);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#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 == curl_thread_t_null) {
|
||||
/* 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);
|
||||
#ifdef _WIN32
|
||||
DEBUGASSERT(td->complete_ev || td->thread_hnd != curl_thread_t_null);
|
||||
#else
|
||||
DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
|
||||
#endif
|
||||
|
||||
/* wait for the thread to resolve the name */
|
||||
#ifdef _WIN32
|
||||
if(td->complete_ev) {
|
||||
WaitForSingleObject(td->complete_ev, INFINITE);
|
||||
CloseHandle(td->complete_ev);
|
||||
td->complete_ev = NULL;
|
||||
if(entry)
|
||||
result = getaddrinfo_complete(data);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
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. */
|
||||
#ifdef _WIN32
|
||||
if(td && td->complete_ev) {
|
||||
Curl_GetAddrInfoExCancel(&td->tsd.w8.cancel_ev);
|
||||
(void)thread_wait_resolv(data, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
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 */
|
||||
if(data->conn->ip_version == CURL_IPRESOLVE_V6)
|
||||
pf = PF_INET6;
|
||||
else
|
||||
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 */
|
184
third_party/curl/lib/asyn.h
vendored
Normal file
184
third_party/curl/lib/asyn.h
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
#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 */
|
293
third_party/curl/lib/base64.c
vendored
Normal file
293
third_party/curl/lib/base64.c
vendored
Normal file
@ -0,0 +1,293 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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_DIGEST_AUTH) || \
|
||||
!defined(CURL_DISABLE_DOH) || defined(USE_SSL) || defined(BUILDING_CURL)
|
||||
#include "curl/curl.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_base64.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#ifdef BUILDING_LIBCURL
|
||||
#include "curl_memory.h"
|
||||
#endif
|
||||
#include "memdebug.h"
|
||||
|
||||
/* ---- Base64 Encoding/Decoding Table --- */
|
||||
/* Padding character string starts at offset 64. */
|
||||
static const char base64encdec[]=
|
||||
"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 *)base64encdec;
|
||||
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 = (size_t)(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(base64encdec, 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 */
|
677
third_party/curl/lib/bufq.c
vendored
Normal file
677
third_party/curl/lib/bufq.c
vendored
Normal file
@ -0,0 +1,677 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 "bufq.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static bool chunk_is_empty(const struct buf_chunk *chunk)
|
||||
{
|
||||
return chunk->r_offset >= chunk->w_offset;
|
||||
}
|
||||
|
||||
static bool chunk_is_full(const struct buf_chunk *chunk)
|
||||
{
|
||||
return chunk->w_offset >= chunk->dlen;
|
||||
}
|
||||
|
||||
static size_t chunk_len(const struct buf_chunk *chunk)
|
||||
{
|
||||
return chunk->w_offset - chunk->r_offset;
|
||||
}
|
||||
|
||||
static size_t chunk_space(const struct buf_chunk *chunk)
|
||||
{
|
||||
return chunk->dlen - chunk->w_offset;
|
||||
}
|
||||
|
||||
static void chunk_reset(struct buf_chunk *chunk)
|
||||
{
|
||||
chunk->next = NULL;
|
||||
chunk->r_offset = chunk->w_offset = 0;
|
||||
}
|
||||
|
||||
static size_t chunk_append(struct buf_chunk *chunk,
|
||||
const unsigned char *buf, size_t len)
|
||||
{
|
||||
unsigned char *p = &chunk->x.data[chunk->w_offset];
|
||||
size_t n = chunk->dlen - chunk->w_offset;
|
||||
DEBUGASSERT(chunk->dlen >= chunk->w_offset);
|
||||
if(n) {
|
||||
n = CURLMIN(n, len);
|
||||
memcpy(p, buf, n);
|
||||
chunk->w_offset += n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static size_t chunk_read(struct buf_chunk *chunk,
|
||||
unsigned char *buf, size_t len)
|
||||
{
|
||||
unsigned char *p = &chunk->x.data[chunk->r_offset];
|
||||
size_t n = chunk->w_offset - chunk->r_offset;
|
||||
DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
|
||||
if(!n) {
|
||||
return 0;
|
||||
}
|
||||
else if(n <= len) {
|
||||
memcpy(buf, p, n);
|
||||
chunk->r_offset = chunk->w_offset = 0;
|
||||
return n;
|
||||
}
|
||||
else {
|
||||
memcpy(buf, p, len);
|
||||
chunk->r_offset += len;
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t chunk_slurpn(struct buf_chunk *chunk, size_t max_len,
|
||||
Curl_bufq_reader *reader,
|
||||
void *reader_ctx, CURLcode *err)
|
||||
{
|
||||
unsigned char *p = &chunk->x.data[chunk->w_offset];
|
||||
size_t n = chunk->dlen - chunk->w_offset; /* free amount */
|
||||
ssize_t nread;
|
||||
|
||||
DEBUGASSERT(chunk->dlen >= chunk->w_offset);
|
||||
if(!n) {
|
||||
*err = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
if(max_len && n > max_len)
|
||||
n = max_len;
|
||||
nread = reader(reader_ctx, p, n, err);
|
||||
if(nread > 0) {
|
||||
DEBUGASSERT((size_t)nread <= n);
|
||||
chunk->w_offset += nread;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
static void chunk_peek(const struct buf_chunk *chunk,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
{
|
||||
DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
|
||||
*pbuf = &chunk->x.data[chunk->r_offset];
|
||||
*plen = chunk->w_offset - chunk->r_offset;
|
||||
}
|
||||
|
||||
static void chunk_peek_at(const struct buf_chunk *chunk, size_t offset,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
{
|
||||
offset += chunk->r_offset;
|
||||
DEBUGASSERT(chunk->w_offset >= offset);
|
||||
*pbuf = &chunk->x.data[offset];
|
||||
*plen = chunk->w_offset - offset;
|
||||
}
|
||||
|
||||
static size_t chunk_skip(struct buf_chunk *chunk, size_t amount)
|
||||
{
|
||||
size_t n = chunk->w_offset - chunk->r_offset;
|
||||
DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
|
||||
if(n) {
|
||||
n = CURLMIN(n, amount);
|
||||
chunk->r_offset += n;
|
||||
if(chunk->r_offset == chunk->w_offset)
|
||||
chunk->r_offset = chunk->w_offset = 0;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static void chunk_list_free(struct buf_chunk **anchor)
|
||||
{
|
||||
struct buf_chunk *chunk;
|
||||
while(*anchor) {
|
||||
chunk = *anchor;
|
||||
*anchor = chunk->next;
|
||||
free(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Curl_bufcp_init(struct bufc_pool *pool,
|
||||
size_t chunk_size, size_t spare_max)
|
||||
{
|
||||
DEBUGASSERT(chunk_size > 0);
|
||||
DEBUGASSERT(spare_max > 0);
|
||||
memset(pool, 0, sizeof(*pool));
|
||||
pool->chunk_size = chunk_size;
|
||||
pool->spare_max = spare_max;
|
||||
}
|
||||
|
||||
static CURLcode bufcp_take(struct bufc_pool *pool,
|
||||
struct buf_chunk **pchunk)
|
||||
{
|
||||
struct buf_chunk *chunk = NULL;
|
||||
|
||||
if(pool->spare) {
|
||||
chunk = pool->spare;
|
||||
pool->spare = chunk->next;
|
||||
--pool->spare_count;
|
||||
chunk_reset(chunk);
|
||||
*pchunk = chunk;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
chunk = calloc(1, sizeof(*chunk) + pool->chunk_size);
|
||||
if(!chunk) {
|
||||
*pchunk = NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
chunk->dlen = pool->chunk_size;
|
||||
*pchunk = chunk;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void bufcp_put(struct bufc_pool *pool,
|
||||
struct buf_chunk *chunk)
|
||||
{
|
||||
if(pool->spare_count >= pool->spare_max) {
|
||||
free(chunk);
|
||||
}
|
||||
else {
|
||||
chunk_reset(chunk);
|
||||
chunk->next = pool->spare;
|
||||
pool->spare = chunk;
|
||||
++pool->spare_count;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_bufcp_free(struct bufc_pool *pool)
|
||||
{
|
||||
chunk_list_free(&pool->spare);
|
||||
pool->spare_count = 0;
|
||||
}
|
||||
|
||||
static void bufq_init(struct bufq *q, struct bufc_pool *pool,
|
||||
size_t chunk_size, size_t max_chunks, int opts)
|
||||
{
|
||||
DEBUGASSERT(chunk_size > 0);
|
||||
DEBUGASSERT(max_chunks > 0);
|
||||
memset(q, 0, sizeof(*q));
|
||||
q->chunk_size = chunk_size;
|
||||
q->max_chunks = max_chunks;
|
||||
q->pool = pool;
|
||||
q->opts = opts;
|
||||
}
|
||||
|
||||
void Curl_bufq_init2(struct bufq *q, size_t chunk_size, size_t max_chunks,
|
||||
int opts)
|
||||
{
|
||||
bufq_init(q, NULL, chunk_size, max_chunks, opts);
|
||||
}
|
||||
|
||||
void Curl_bufq_init(struct bufq *q, size_t chunk_size, size_t max_chunks)
|
||||
{
|
||||
bufq_init(q, NULL, chunk_size, max_chunks, BUFQ_OPT_NONE);
|
||||
}
|
||||
|
||||
void Curl_bufq_initp(struct bufq *q, struct bufc_pool *pool,
|
||||
size_t max_chunks, int opts)
|
||||
{
|
||||
bufq_init(q, pool, pool->chunk_size, max_chunks, opts);
|
||||
}
|
||||
|
||||
void Curl_bufq_free(struct bufq *q)
|
||||
{
|
||||
chunk_list_free(&q->head);
|
||||
chunk_list_free(&q->spare);
|
||||
q->tail = NULL;
|
||||
q->chunk_count = 0;
|
||||
}
|
||||
|
||||
void Curl_bufq_reset(struct bufq *q)
|
||||
{
|
||||
struct buf_chunk *chunk;
|
||||
while(q->head) {
|
||||
chunk = q->head;
|
||||
q->head = chunk->next;
|
||||
chunk->next = q->spare;
|
||||
q->spare = chunk;
|
||||
}
|
||||
q->tail = NULL;
|
||||
}
|
||||
|
||||
size_t Curl_bufq_len(const struct bufq *q)
|
||||
{
|
||||
const struct buf_chunk *chunk = q->head;
|
||||
size_t len = 0;
|
||||
while(chunk) {
|
||||
len += chunk_len(chunk);
|
||||
chunk = chunk->next;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t Curl_bufq_space(const struct bufq *q)
|
||||
{
|
||||
size_t space = 0;
|
||||
if(q->tail)
|
||||
space += chunk_space(q->tail);
|
||||
if(q->spare) {
|
||||
struct buf_chunk *chunk = q->spare;
|
||||
while(chunk) {
|
||||
space += chunk->dlen;
|
||||
chunk = chunk->next;
|
||||
}
|
||||
}
|
||||
if(q->chunk_count < q->max_chunks) {
|
||||
space += (q->max_chunks - q->chunk_count) * q->chunk_size;
|
||||
}
|
||||
return space;
|
||||
}
|
||||
|
||||
bool Curl_bufq_is_empty(const struct bufq *q)
|
||||
{
|
||||
return !q->head || chunk_is_empty(q->head);
|
||||
}
|
||||
|
||||
bool Curl_bufq_is_full(const struct bufq *q)
|
||||
{
|
||||
if(!q->tail || q->spare)
|
||||
return FALSE;
|
||||
if(q->chunk_count < q->max_chunks)
|
||||
return FALSE;
|
||||
if(q->chunk_count > q->max_chunks)
|
||||
return TRUE;
|
||||
/* we have no spares and cannot make more, is the tail full? */
|
||||
return chunk_is_full(q->tail);
|
||||
}
|
||||
|
||||
static struct buf_chunk *get_spare(struct bufq *q)
|
||||
{
|
||||
struct buf_chunk *chunk = NULL;
|
||||
|
||||
if(q->spare) {
|
||||
chunk = q->spare;
|
||||
q->spare = chunk->next;
|
||||
chunk_reset(chunk);
|
||||
return chunk;
|
||||
}
|
||||
|
||||
if(q->chunk_count >= q->max_chunks && (!(q->opts & BUFQ_OPT_SOFT_LIMIT)))
|
||||
return NULL;
|
||||
|
||||
if(q->pool) {
|
||||
if(bufcp_take(q->pool, &chunk))
|
||||
return NULL;
|
||||
++q->chunk_count;
|
||||
return chunk;
|
||||
}
|
||||
else {
|
||||
chunk = calloc(1, sizeof(*chunk) + q->chunk_size);
|
||||
if(!chunk)
|
||||
return NULL;
|
||||
chunk->dlen = q->chunk_size;
|
||||
++q->chunk_count;
|
||||
return chunk;
|
||||
}
|
||||
}
|
||||
|
||||
static void prune_head(struct bufq *q)
|
||||
{
|
||||
struct buf_chunk *chunk;
|
||||
|
||||
while(q->head && chunk_is_empty(q->head)) {
|
||||
chunk = q->head;
|
||||
q->head = chunk->next;
|
||||
if(q->tail == chunk)
|
||||
q->tail = q->head;
|
||||
if(q->pool) {
|
||||
bufcp_put(q->pool, chunk);
|
||||
--q->chunk_count;
|
||||
}
|
||||
else if((q->chunk_count > q->max_chunks) ||
|
||||
(q->opts & BUFQ_OPT_NO_SPARES)) {
|
||||
/* SOFT_LIMIT allowed us more than max. free spares until
|
||||
* we are at max again. Or free them if we are configured
|
||||
* to not use spares. */
|
||||
free(chunk);
|
||||
--q->chunk_count;
|
||||
}
|
||||
else {
|
||||
chunk->next = q->spare;
|
||||
q->spare = chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct buf_chunk *get_non_full_tail(struct bufq *q)
|
||||
{
|
||||
struct buf_chunk *chunk;
|
||||
|
||||
if(q->tail && !chunk_is_full(q->tail))
|
||||
return q->tail;
|
||||
chunk = get_spare(q);
|
||||
if(chunk) {
|
||||
/* new tail, and possibly new head */
|
||||
if(q->tail) {
|
||||
q->tail->next = chunk;
|
||||
q->tail = chunk;
|
||||
}
|
||||
else {
|
||||
DEBUGASSERT(!q->head);
|
||||
q->head = q->tail = chunk;
|
||||
}
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
ssize_t Curl_bufq_write(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
CURLcode *err)
|
||||
{
|
||||
struct buf_chunk *tail;
|
||||
ssize_t nwritten = 0;
|
||||
size_t n;
|
||||
|
||||
DEBUGASSERT(q->max_chunks > 0);
|
||||
while(len) {
|
||||
tail = get_non_full_tail(q);
|
||||
if(!tail) {
|
||||
if((q->chunk_count < q->max_chunks) || (q->opts & BUFQ_OPT_SOFT_LIMIT)) {
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
n = chunk_append(tail, buf, len);
|
||||
if(!n)
|
||||
break;
|
||||
nwritten += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
}
|
||||
if(nwritten == 0 && len) {
|
||||
*err = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
*err = CURLE_OK;
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
CURLcode Curl_bufq_cwrite(struct bufq *q,
|
||||
const char *buf, size_t len,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
ssize_t n;
|
||||
CURLcode result;
|
||||
n = Curl_bufq_write(q, (const unsigned char *)buf, len, &result);
|
||||
*pnwritten = (n < 0)? 0 : (size_t)n;
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
|
||||
CURLcode *err)
|
||||
{
|
||||
ssize_t nread = 0;
|
||||
size_t n;
|
||||
|
||||
*err = CURLE_OK;
|
||||
while(len && q->head) {
|
||||
n = chunk_read(q->head, buf, len);
|
||||
if(n) {
|
||||
nread += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
}
|
||||
prune_head(q);
|
||||
}
|
||||
if(nread == 0) {
|
||||
*err = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
|
||||
size_t *pnread)
|
||||
{
|
||||
ssize_t n;
|
||||
CURLcode result;
|
||||
n = Curl_bufq_read(q, (unsigned char *)buf, len, &result);
|
||||
*pnread = (n < 0)? 0 : (size_t)n;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Curl_bufq_peek(struct bufq *q,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
{
|
||||
if(q->head && chunk_is_empty(q->head)) {
|
||||
prune_head(q);
|
||||
}
|
||||
if(q->head && !chunk_is_empty(q->head)) {
|
||||
chunk_peek(q->head, pbuf, plen);
|
||||
return TRUE;
|
||||
}
|
||||
*pbuf = NULL;
|
||||
*plen = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
{
|
||||
struct buf_chunk *c = q->head;
|
||||
size_t clen;
|
||||
|
||||
while(c) {
|
||||
clen = chunk_len(c);
|
||||
if(!clen)
|
||||
break;
|
||||
if(offset >= clen) {
|
||||
offset -= clen;
|
||||
c = c->next;
|
||||
continue;
|
||||
}
|
||||
chunk_peek_at(c, offset, pbuf, plen);
|
||||
return TRUE;
|
||||
}
|
||||
*pbuf = NULL;
|
||||
*plen = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void Curl_bufq_skip(struct bufq *q, size_t amount)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
while(amount && q->head) {
|
||||
n = chunk_skip(q->head, amount);
|
||||
amount -= n;
|
||||
prune_head(q);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
|
||||
void *writer_ctx, CURLcode *err)
|
||||
{
|
||||
const unsigned char *buf;
|
||||
size_t blen;
|
||||
ssize_t nwritten = 0;
|
||||
|
||||
while(Curl_bufq_peek(q, &buf, &blen)) {
|
||||
ssize_t chunk_written;
|
||||
|
||||
chunk_written = writer(writer_ctx, buf, blen, err);
|
||||
if(chunk_written < 0) {
|
||||
if(!nwritten || *err != CURLE_AGAIN) {
|
||||
/* blocked on first write or real error, fail */
|
||||
nwritten = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(!chunk_written) {
|
||||
if(!nwritten) {
|
||||
/* treat as blocked */
|
||||
*err = CURLE_AGAIN;
|
||||
nwritten = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Curl_bufq_skip(q, (size_t)chunk_written);
|
||||
nwritten += chunk_written;
|
||||
}
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
ssize_t Curl_bufq_write_pass(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
Curl_bufq_writer *writer, void *writer_ctx,
|
||||
CURLcode *err)
|
||||
{
|
||||
ssize_t nwritten = 0, n;
|
||||
|
||||
*err = CURLE_OK;
|
||||
while(len) {
|
||||
if(Curl_bufq_is_full(q)) {
|
||||
/* try to make room in case we are full */
|
||||
n = Curl_bufq_pass(q, writer, writer_ctx, err);
|
||||
if(n < 0) {
|
||||
if(*err != CURLE_AGAIN) {
|
||||
/* real error, fail */
|
||||
return -1;
|
||||
}
|
||||
/* would block, bufq is full, give up */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add whatever is remaining now to bufq */
|
||||
n = Curl_bufq_write(q, buf, len, err);
|
||||
if(n < 0) {
|
||||
if(*err != CURLE_AGAIN) {
|
||||
/* real error, fail */
|
||||
return -1;
|
||||
}
|
||||
/* no room in bufq */
|
||||
break;
|
||||
}
|
||||
/* edge case of writer returning 0 (and len is >0)
|
||||
* break or we might enter an infinite loop here */
|
||||
if(n == 0)
|
||||
break;
|
||||
|
||||
/* Maybe only part of `data` has been added, continue to loop */
|
||||
buf += (size_t)n;
|
||||
len -= (size_t)n;
|
||||
nwritten += (size_t)n;
|
||||
}
|
||||
|
||||
if(!nwritten && len) {
|
||||
*err = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
*err = CURLE_OK;
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
ssize_t Curl_bufq_sipn(struct bufq *q, size_t max_len,
|
||||
Curl_bufq_reader *reader, void *reader_ctx,
|
||||
CURLcode *err)
|
||||
{
|
||||
struct buf_chunk *tail = NULL;
|
||||
ssize_t nread;
|
||||
|
||||
*err = CURLE_AGAIN;
|
||||
tail = get_non_full_tail(q);
|
||||
if(!tail) {
|
||||
if(q->chunk_count < q->max_chunks) {
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
/* full, blocked */
|
||||
*err = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nread = chunk_slurpn(tail, max_len, reader, reader_ctx, err);
|
||||
if(nread < 0) {
|
||||
return -1;
|
||||
}
|
||||
else if(nread == 0) {
|
||||
/* eof */
|
||||
*err = CURLE_OK;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read up to `max_len` bytes and append it to the end of the buffer queue.
|
||||
* if `max_len` is 0, no limit is imposed and the call behaves exactly
|
||||
* the same as `Curl_bufq_slurp()`.
|
||||
* Returns the total amount of buf read (may be 0) or -1 on other
|
||||
* reader errors.
|
||||
* Note that even in case of a -1 chunks may have been read and
|
||||
* the buffer queue will have different length than before.
|
||||
*/
|
||||
static ssize_t bufq_slurpn(struct bufq *q, size_t max_len,
|
||||
Curl_bufq_reader *reader, void *reader_ctx,
|
||||
CURLcode *err)
|
||||
{
|
||||
ssize_t nread = 0, n;
|
||||
|
||||
*err = CURLE_AGAIN;
|
||||
while(1) {
|
||||
|
||||
n = Curl_bufq_sipn(q, max_len, reader, reader_ctx, err);
|
||||
if(n < 0) {
|
||||
if(!nread || *err != CURLE_AGAIN) {
|
||||
/* blocked on first read or real error, fail */
|
||||
nread = -1;
|
||||
}
|
||||
else
|
||||
*err = CURLE_OK;
|
||||
break;
|
||||
}
|
||||
else if(n == 0) {
|
||||
/* eof */
|
||||
*err = CURLE_OK;
|
||||
break;
|
||||
}
|
||||
nread += (size_t)n;
|
||||
if(max_len) {
|
||||
DEBUGASSERT((size_t)n <= max_len);
|
||||
max_len -= (size_t)n;
|
||||
if(!max_len)
|
||||
break;
|
||||
}
|
||||
/* give up slurping when we get less bytes than we asked for */
|
||||
if(q->tail && !chunk_is_full(q->tail))
|
||||
break;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader,
|
||||
void *reader_ctx, CURLcode *err)
|
||||
{
|
||||
return bufq_slurpn(q, 0, reader, reader_ctx, err);
|
||||
}
|
272
third_party/curl/lib/bufq.h
vendored
Normal file
272
third_party/curl/lib/bufq.h
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
#ifndef HEADER_CURL_BUFQ_H
|
||||
#define HEADER_CURL_BUFQ_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>
|
||||
|
||||
/**
|
||||
* A chunk of bytes for reading and writing.
|
||||
* The size is fixed a creation with read and write offset
|
||||
* for where unread content is.
|
||||
*/
|
||||
struct buf_chunk {
|
||||
struct buf_chunk *next; /* to keep it in a list */
|
||||
size_t dlen; /* the amount of allocated x.data[] */
|
||||
size_t r_offset; /* first unread bytes */
|
||||
size_t w_offset; /* one after last written byte */
|
||||
union {
|
||||
unsigned char data[1]; /* the buffer for `dlen` bytes */
|
||||
void *dummy; /* alignment */
|
||||
} x;
|
||||
};
|
||||
|
||||
/**
|
||||
* A pool for providing/keeping a number of chunks of the same size
|
||||
*
|
||||
* The same pool can be shared by many `bufq` instances. However, a pool
|
||||
* is not thread safe. All bufqs using it are supposed to operate in the
|
||||
* same thread.
|
||||
*/
|
||||
struct bufc_pool {
|
||||
struct buf_chunk *spare; /* list of available spare chunks */
|
||||
size_t chunk_size; /* the size of chunks in this pool */
|
||||
size_t spare_count; /* current number of spare chunks in list */
|
||||
size_t spare_max; /* max number of spares to keep */
|
||||
};
|
||||
|
||||
void Curl_bufcp_init(struct bufc_pool *pool,
|
||||
size_t chunk_size, size_t spare_max);
|
||||
|
||||
void Curl_bufcp_free(struct bufc_pool *pool);
|
||||
|
||||
/**
|
||||
* A queue of byte chunks for reading and writing.
|
||||
* Reading is done from `head`, writing is done to `tail`.
|
||||
*
|
||||
* `bufq`s can be empty or full or neither. Its `len` is the number
|
||||
* of bytes that can be read. For an empty bufq, `len` will be 0.
|
||||
*
|
||||
* By default, a bufq can hold up to `max_chunks * chunk_size` number
|
||||
* of bytes. When `max_chunks` are used (in the `head` list) and the
|
||||
* `tail` chunk is full, the bufq will report that it is full.
|
||||
*
|
||||
* On a full bufq, `len` may be less than the maximum number of bytes,
|
||||
* e.g. when the head chunk is partially read. `len` may also become
|
||||
* larger than the max when option `BUFQ_OPT_SOFT_LIMIT` is used.
|
||||
*
|
||||
* By default, writing to a full bufq will return (-1, CURLE_AGAIN). Same
|
||||
* as reading from an empty bufq.
|
||||
* With `BUFQ_OPT_SOFT_LIMIT` set, a bufq will allow writing becond this
|
||||
* limit and use more than `max_chunks`. However it will report that it
|
||||
* is full nevertheless. This is provided for situation where writes
|
||||
* preferably never fail (except for memory exhaustion).
|
||||
*
|
||||
* By default and without a pool, a bufq will keep chunks that read
|
||||
* empty in its `spare` list. Option `BUFQ_OPT_NO_SPARES` will
|
||||
* disable that and free chunks once they become empty.
|
||||
*
|
||||
* When providing a pool to a bufq, all chunk creation and spare handling
|
||||
* will be delegated to that pool.
|
||||
*/
|
||||
struct bufq {
|
||||
struct buf_chunk *head; /* chunk with bytes to read from */
|
||||
struct buf_chunk *tail; /* chunk to write to */
|
||||
struct buf_chunk *spare; /* list of free chunks, unless `pool` */
|
||||
struct bufc_pool *pool; /* optional pool for free chunks */
|
||||
size_t chunk_count; /* current number of chunks in `head+spare` */
|
||||
size_t max_chunks; /* max `head` chunks to use */
|
||||
size_t chunk_size; /* size of chunks to manage */
|
||||
int opts; /* options for handling queue, see below */
|
||||
};
|
||||
|
||||
/**
|
||||
* Default behaviour: chunk limit is "hard", meaning attempts to write
|
||||
* more bytes than can be hold in `max_chunks` is refused and will return
|
||||
* -1, CURLE_AGAIN. */
|
||||
#define BUFQ_OPT_NONE (0)
|
||||
/**
|
||||
* Make `max_chunks` a "soft" limit. A bufq will report that it is "full"
|
||||
* when `max_chunks` are used, but allows writing beyond this limit.
|
||||
*/
|
||||
#define BUFQ_OPT_SOFT_LIMIT (1 << 0)
|
||||
/**
|
||||
* Do not keep spare chunks.
|
||||
*/
|
||||
#define BUFQ_OPT_NO_SPARES (1 << 1)
|
||||
|
||||
/**
|
||||
* Initialize a buffer queue that can hold up to `max_chunks` buffers
|
||||
* each of size `chunk_size`. The bufq will not allow writing of
|
||||
* more bytes than can be held in `max_chunks`.
|
||||
*/
|
||||
void Curl_bufq_init(struct bufq *q, size_t chunk_size, size_t max_chunks);
|
||||
|
||||
/**
|
||||
* Initialize a buffer queue that can hold up to `max_chunks` buffers
|
||||
* each of size `chunk_size` with the given options. See `BUFQ_OPT_*`.
|
||||
*/
|
||||
void Curl_bufq_init2(struct bufq *q, size_t chunk_size,
|
||||
size_t max_chunks, int opts);
|
||||
|
||||
void Curl_bufq_initp(struct bufq *q, struct bufc_pool *pool,
|
||||
size_t max_chunks, int opts);
|
||||
|
||||
/**
|
||||
* Reset the buffer queue to be empty. Will keep any allocated buffer
|
||||
* chunks around.
|
||||
*/
|
||||
void Curl_bufq_reset(struct bufq *q);
|
||||
|
||||
/**
|
||||
* Free all resources held by the buffer queue.
|
||||
*/
|
||||
void Curl_bufq_free(struct bufq *q);
|
||||
|
||||
/**
|
||||
* Return the total amount of data in the queue.
|
||||
*/
|
||||
size_t Curl_bufq_len(const struct bufq *q);
|
||||
|
||||
/**
|
||||
* Return the total amount of free space in the queue.
|
||||
* The returned length is the number of bytes that can
|
||||
* be expected to be written successfully to the bufq,
|
||||
* providing no memory allocations fail.
|
||||
*/
|
||||
size_t Curl_bufq_space(const struct bufq *q);
|
||||
|
||||
/**
|
||||
* Returns TRUE iff there is no data in the buffer queue.
|
||||
*/
|
||||
bool Curl_bufq_is_empty(const struct bufq *q);
|
||||
|
||||
/**
|
||||
* Returns TRUE iff there is no space left in the buffer queue.
|
||||
*/
|
||||
bool Curl_bufq_is_full(const struct bufq *q);
|
||||
|
||||
/**
|
||||
* Write buf to the end of the buffer queue. The buf is copied
|
||||
* and the amount of copied bytes is returned.
|
||||
* A return code of -1 indicates an error, setting `err` to the
|
||||
* cause. An err of CURLE_AGAIN is returned if the buffer queue is full.
|
||||
*/
|
||||
ssize_t Curl_bufq_write(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
CURLcode *err);
|
||||
|
||||
CURLcode Curl_bufq_cwrite(struct bufq *q,
|
||||
const char *buf, size_t len,
|
||||
size_t *pnwritten);
|
||||
|
||||
/**
|
||||
* Read buf from the start of the buffer queue. The buf is copied
|
||||
* and the amount of copied bytes is returned.
|
||||
* A return code of -1 indicates an error, setting `err` to the
|
||||
* cause. An err of CURLE_AGAIN is returned if the buffer queue is empty.
|
||||
*/
|
||||
ssize_t Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
|
||||
CURLcode *err);
|
||||
|
||||
CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
|
||||
size_t *pnread);
|
||||
|
||||
/**
|
||||
* Peek at the head chunk in the buffer queue. Returns a pointer to
|
||||
* the chunk buf (at the current offset) and its length. Does not
|
||||
* modify the buffer queue.
|
||||
* Returns TRUE iff bytes are available. Sets `pbuf` to NULL and `plen`
|
||||
* to 0 when no bytes are available.
|
||||
* Repeated calls return the same information until the buffer queue
|
||||
* is modified, see `Curl_bufq_skip()``
|
||||
*/
|
||||
bool Curl_bufq_peek(struct bufq *q,
|
||||
const unsigned char **pbuf, size_t *plen);
|
||||
|
||||
bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
|
||||
const unsigned char **pbuf, size_t *plen);
|
||||
|
||||
/**
|
||||
* Tell the buffer queue to discard `amount` buf bytes at the head
|
||||
* of the queue. Skipping more buf than is currently buffered will
|
||||
* just empty the queue.
|
||||
*/
|
||||
void Curl_bufq_skip(struct bufq *q, size_t amount);
|
||||
|
||||
typedef ssize_t Curl_bufq_writer(void *writer_ctx,
|
||||
const unsigned char *buf, size_t len,
|
||||
CURLcode *err);
|
||||
/**
|
||||
* Passes the chunks in the buffer queue to the writer and returns
|
||||
* the amount of buf written. A writer may return -1 and CURLE_AGAIN
|
||||
* to indicate blocking at which point the queue will stop and return
|
||||
* the amount of buf passed so far.
|
||||
* -1 is returned on any other errors reported by the writer.
|
||||
* Note that in case of a -1 chunks may have been written and
|
||||
* the buffer queue will have different length than before.
|
||||
*/
|
||||
ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
|
||||
void *writer_ctx, CURLcode *err);
|
||||
|
||||
typedef ssize_t Curl_bufq_reader(void *reader_ctx,
|
||||
unsigned char *buf, size_t len,
|
||||
CURLcode *err);
|
||||
|
||||
/**
|
||||
* Read date and append it to the end of the buffer queue until the
|
||||
* reader returns blocking or the queue is full. A reader returns
|
||||
* -1 and CURLE_AGAIN to indicate blocking.
|
||||
* Returns the total amount of buf read (may be 0) or -1 on other
|
||||
* reader errors.
|
||||
* Note that in case of a -1 chunks may have been read and
|
||||
* the buffer queue will have different length than before.
|
||||
*/
|
||||
ssize_t Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader,
|
||||
void *reader_ctx, CURLcode *err);
|
||||
|
||||
/**
|
||||
* Read *once* up to `max_len` bytes and append it to the buffer.
|
||||
* if `max_len` is 0, no limit is imposed besides the chunk space.
|
||||
* Returns the total amount of buf read (may be 0) or -1 on other
|
||||
* reader errors.
|
||||
*/
|
||||
ssize_t Curl_bufq_sipn(struct bufq *q, size_t max_len,
|
||||
Curl_bufq_reader *reader, void *reader_ctx,
|
||||
CURLcode *err);
|
||||
|
||||
/**
|
||||
* Write buf to the end of the buffer queue.
|
||||
* Will write bufq content or passed `buf` directly using the `writer`
|
||||
* callback when it sees fit. 'buf' might get passed directly
|
||||
* on or is placed into the buffer, depending on `len` and current
|
||||
* amount buffered, chunk size, etc.
|
||||
*/
|
||||
ssize_t Curl_bufq_write_pass(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
Curl_bufq_writer *writer, void *writer_ctx,
|
||||
CURLcode *err);
|
||||
|
||||
#endif /* HEADER_CURL_BUFQ_H */
|
127
third_party/curl/lib/bufref.c
vendored
Normal file
127
third_party/curl/lib/bufref.c
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 "strdup.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 = Curl_memdup0(ptr, len);
|
||||
if(!cpy)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
Curl_bufref_set(br, cpy, len, curl_free);
|
||||
return CURLE_OK;
|
||||
}
|
48
third_party/curl/lib/bufref.h
vendored
Normal file
48
third_party/curl/lib/bufref.h
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
#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
|
1228
third_party/curl/lib/c-hyper.c
vendored
Normal file
1228
third_party/curl/lib/c-hyper.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
63
third_party/curl/lib/c-hyper.h
vendored
Normal file
63
third_party/curl/lib/c-hyper.h
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
#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>
|
||||
|
||||
struct hyp_io_ctx {
|
||||
struct Curl_easy *data;
|
||||
int sockindex;
|
||||
};
|
||||
|
||||
/* per-transfer data for the Hyper backend */
|
||||
struct hyptransfer {
|
||||
hyper_waker *write_waker;
|
||||
hyper_waker *read_waker;
|
||||
const hyper_executor *exec;
|
||||
hyper_waker *send_body_waker;
|
||||
struct hyp_io_ctx io_ctx;
|
||||
};
|
||||
|
||||
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,
|
||||
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 */
|
1104
third_party/curl/lib/cf-h1-proxy.c
vendored
Normal file
1104
third_party/curl/lib/cf-h1-proxy.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
39
third_party/curl/lib/cf-h1-proxy.h
vendored
Normal file
39
third_party/curl/lib/cf-h1-proxy.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef HEADER_CURL_H1_PROXY_H
|
||||
#define HEADER_CURL_H1_PROXY_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_PROXY) && !defined(CURL_DISABLE_HTTP)
|
||||
|
||||
CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data);
|
||||
|
||||
extern struct Curl_cftype Curl_cft_h1_proxy;
|
||||
|
||||
|
||||
#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */
|
||||
|
||||
#endif /* HEADER_CURL_H1_PROXY_H */
|
1576
third_party/curl/lib/cf-h2-proxy.c
vendored
Normal file
1576
third_party/curl/lib/cf-h2-proxy.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
39
third_party/curl/lib/cf-h2-proxy.h
vendored
Normal file
39
third_party/curl/lib/cf-h2-proxy.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef HEADER_CURL_H2_PROXY_H
|
||||
#define HEADER_CURL_H2_PROXY_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(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data);
|
||||
|
||||
extern struct Curl_cftype Curl_cft_h2_proxy;
|
||||
|
||||
|
||||
#endif /* defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY) */
|
||||
|
||||
#endif /* HEADER_CURL_H2_PROXY_H */
|
250
third_party/curl/lib/cf-haproxy.c
vendored
Normal file
250
third_party/curl/lib/cf-haproxy.c
vendored
Normal file
@ -0,0 +1,250 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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_PROXY)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "cfilters.h"
|
||||
#include "cf-haproxy.h"
|
||||
#include "curl_trc.h"
|
||||
#include "multiif.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
HAPROXY_INIT, /* init/default/no tunnel state */
|
||||
HAPROXY_SEND, /* data_out being sent */
|
||||
HAPROXY_DONE /* all work done */
|
||||
} haproxy_state;
|
||||
|
||||
struct cf_haproxy_ctx {
|
||||
int state;
|
||||
struct dynbuf data_out;
|
||||
};
|
||||
|
||||
static void cf_haproxy_ctx_reset(struct cf_haproxy_ctx *ctx)
|
||||
{
|
||||
DEBUGASSERT(ctx);
|
||||
ctx->state = HAPROXY_INIT;
|
||||
Curl_dyn_reset(&ctx->data_out);
|
||||
}
|
||||
|
||||
static void cf_haproxy_ctx_free(struct cf_haproxy_ctx *ctx)
|
||||
{
|
||||
if(ctx) {
|
||||
Curl_dyn_free(&ctx->data_out);
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_haproxy_ctx *ctx = cf->ctx;
|
||||
CURLcode result;
|
||||
const char *tcp_version;
|
||||
const char *client_ip;
|
||||
|
||||
DEBUGASSERT(ctx);
|
||||
DEBUGASSERT(ctx->state == HAPROXY_INIT);
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
if(cf->conn->unix_domain_socket)
|
||||
/* the buffer is large enough to hold this! */
|
||||
result = Curl_dyn_addn(&ctx->data_out, STRCONST("PROXY UNKNOWN\r\n"));
|
||||
else {
|
||||
#endif /* USE_UNIX_SOCKETS */
|
||||
/* Emit the correct prefix for IPv6 */
|
||||
tcp_version = cf->conn->bits.ipv6 ? "TCP6" : "TCP4";
|
||||
if(data->set.str[STRING_HAPROXY_CLIENT_IP])
|
||||
client_ip = data->set.str[STRING_HAPROXY_CLIENT_IP];
|
||||
else
|
||||
client_ip = data->info.primary.local_ip;
|
||||
|
||||
result = Curl_dyn_addf(&ctx->data_out, "PROXY %s %s %s %i %i\r\n",
|
||||
tcp_version,
|
||||
client_ip,
|
||||
data->info.primary.remote_ip,
|
||||
data->info.primary.local_port,
|
||||
data->info.primary.remote_port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
}
|
||||
#endif /* USE_UNIX_SOCKETS */
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode cf_haproxy_connect(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
bool blocking, bool *done)
|
||||
{
|
||||
struct cf_haproxy_ctx *ctx = cf->ctx;
|
||||
CURLcode result;
|
||||
size_t len;
|
||||
|
||||
DEBUGASSERT(ctx);
|
||||
if(cf->connected) {
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
result = cf->next->cft->do_connect(cf->next, data, blocking, done);
|
||||
if(result || !*done)
|
||||
return result;
|
||||
|
||||
switch(ctx->state) {
|
||||
case HAPROXY_INIT:
|
||||
result = cf_haproxy_date_out_set(cf, data);
|
||||
if(result)
|
||||
goto out;
|
||||
ctx->state = HAPROXY_SEND;
|
||||
FALLTHROUGH();
|
||||
case HAPROXY_SEND:
|
||||
len = Curl_dyn_len(&ctx->data_out);
|
||||
if(len > 0) {
|
||||
size_t written;
|
||||
result = Curl_conn_send(data, cf->sockindex,
|
||||
Curl_dyn_ptr(&ctx->data_out),
|
||||
len, &written);
|
||||
if(result == CURLE_AGAIN) {
|
||||
result = CURLE_OK;
|
||||
written = 0;
|
||||
}
|
||||
else if(result)
|
||||
goto out;
|
||||
Curl_dyn_tail(&ctx->data_out, len - written);
|
||||
if(Curl_dyn_len(&ctx->data_out) > 0) {
|
||||
result = CURLE_OK;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ctx->state = HAPROXY_DONE;
|
||||
FALLTHROUGH();
|
||||
default:
|
||||
Curl_dyn_free(&ctx->data_out);
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
*done = (!result) && (ctx->state == HAPROXY_DONE);
|
||||
cf->connected = *done;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cf_haproxy_destroy(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
(void)data;
|
||||
CURL_TRC_CF(data, cf, "destroy");
|
||||
cf_haproxy_ctx_free(cf->ctx);
|
||||
}
|
||||
|
||||
static void cf_haproxy_close(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
CURL_TRC_CF(data, cf, "close");
|
||||
cf->connected = FALSE;
|
||||
cf_haproxy_ctx_reset(cf->ctx);
|
||||
if(cf->next)
|
||||
cf->next->cft->do_close(cf->next, data);
|
||||
}
|
||||
|
||||
static void cf_haproxy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
if(cf->next->connected && !cf->connected) {
|
||||
/* If we are not connected, but the filter "below" is
|
||||
* and not waiting on something, we are sending. */
|
||||
Curl_pollset_set_out_only(data, ps, Curl_conn_cf_get_socket(cf, data));
|
||||
}
|
||||
}
|
||||
|
||||
struct Curl_cftype Curl_cft_haproxy = {
|
||||
"HAPROXY",
|
||||
CF_TYPE_PROXY,
|
||||
0,
|
||||
cf_haproxy_destroy,
|
||||
cf_haproxy_connect,
|
||||
cf_haproxy_close,
|
||||
Curl_cf_def_get_host,
|
||||
cf_haproxy_adjust_pollset,
|
||||
Curl_cf_def_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,
|
||||
Curl_cf_def_query,
|
||||
};
|
||||
|
||||
static CURLcode cf_haproxy_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_cfilter *cf = NULL;
|
||||
struct cf_haproxy_ctx *ctx;
|
||||
CURLcode result;
|
||||
|
||||
(void)data;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
ctx->state = HAPROXY_INIT;
|
||||
Curl_dyn_init(&ctx->data_out, DYN_HAXPROXY);
|
||||
|
||||
result = Curl_cf_create(&cf, &Curl_cft_haproxy, ctx);
|
||||
if(result)
|
||||
goto out;
|
||||
ctx = NULL;
|
||||
|
||||
out:
|
||||
cf_haproxy_ctx_free(ctx);
|
||||
*pcf = result? NULL : cf;
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_cf_haproxy_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
CURLcode result;
|
||||
|
||||
result = cf_haproxy_create(&cf, data);
|
||||
if(result)
|
||||
goto out;
|
||||
Curl_conn_cf_insert_after(cf_at, cf);
|
||||
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_PROXY */
|
39
third_party/curl/lib/cf-haproxy.h
vendored
Normal file
39
third_party/curl/lib/cf-haproxy.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef HEADER_CURL_CF_HAPROXY_H
|
||||
#define HEADER_CURL_CF_HAPROXY_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"
|
||||
|
||||
#if !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
CURLcode Curl_cf_haproxy_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data);
|
||||
|
||||
extern struct Curl_cftype Curl_cft_haproxy;
|
||||
|
||||
#endif /* !CURL_DISABLE_PROXY */
|
||||
|
||||
#endif /* HEADER_CURL_CF_HAPROXY_H */
|
531
third_party/curl/lib/cf-https-connect.c
vendored
Normal file
531
third_party/curl/lib/cf-https-connect.c
vendored
Normal file
@ -0,0 +1,531 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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_trc.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;
|
||||
unsigned int soft_eyeballs_timeout_ms;
|
||||
unsigned 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);
|
||||
|
||||
CURL_TRC_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;
|
||||
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) {
|
||||
CURL_TRC_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) {
|
||||
CURL_TRC_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);
|
||||
CURL_TRC_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)) {
|
||||
CURL_TRC_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 */
|
||||
CURL_TRC_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:
|
||||
CURL_TRC_CF(data, cf, "connect -> %d, done=%d", result, *done);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cf_hc_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
if(!cf->connected) {
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
struct cf_hc_baller *ballers[2];
|
||||
size_t i;
|
||||
|
||||
ballers[0] = &ctx->h3_baller;
|
||||
ballers[1] = &ctx->h21_baller;
|
||||
for(i = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
|
||||
struct cf_hc_baller *b = ballers[i];
|
||||
if(!cf_hc_baller_is_active(b))
|
||||
continue;
|
||||
Curl_conn_cf_adjust_pollset(b->cf, data, ps);
|
||||
}
|
||||
CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
CURL_TRC_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 cf_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 = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
|
||||
return CURLE_OK;
|
||||
}
|
||||
case CF_QUERY_TIMER_APPCONNECT: {
|
||||
struct curltime *when = pres2;
|
||||
*when = cf_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)
|
||||
{
|
||||
CURL_TRC_CF(data, cf, "close");
|
||||
cf_hc_reset(cf, data);
|
||||
cf->connected = FALSE;
|
||||
|
||||
if(cf->next) {
|
||||
cf->next->cft->do_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;
|
||||
CURL_TRC_CF(data, cf, "destroy");
|
||||
cf_hc_reset(cf, data);
|
||||
Curl_safefree(ctx);
|
||||
}
|
||||
|
||||
struct Curl_cftype Curl_cft_http_connect = {
|
||||
"HTTPS-CONNECT",
|
||||
0,
|
||||
CURL_LOG_LVL_NONE,
|
||||
cf_hc_destroy,
|
||||
cf_hc_connect,
|
||||
cf_hc_close,
|
||||
Curl_cf_def_get_host,
|
||||
cf_hc_adjust_pollset,
|
||||
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(1, sizeof(*ctx));
|
||||
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;
|
||||
}
|
||||
|
||||
static CURLcode 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_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 = cf_http_connect_add(data, conn, sockindex, remotehost,
|
||||
try_h3, try_h21);
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */
|
58
third_party/curl/lib/cf-https-connect.h
vendored
Normal file
58
third_party/curl/lib/cf-https-connect.h
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
#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 */
|
1963
third_party/curl/lib/cf-socket.c
vendored
Normal file
1963
third_party/curl/lib/cf-socket.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
171
third_party/curl/lib/cf-socket.h
vendored
Normal file
171
third_party/curl/lib/cf-socket.h
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
#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;
|
||||
struct ip_quadruple;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
#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);
|
||||
|
||||
/**
|
||||
* 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 pip pointer to get IP quadruple 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,
|
||||
struct ip_quadruple *pip);
|
||||
|
||||
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 */
|
861
third_party/curl/lib/cfilters.c
vendored
Normal file
861
third_party/curl/lib/cfilters.c
vendored
Normal file
@ -0,0 +1,861 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 "select.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
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
/* used by unit2600.c */
|
||||
void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
{
|
||||
cf->connected = FALSE;
|
||||
if(cf->next)
|
||||
cf->next->cft->do_close(cf->next, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void conn_report_connect_stats(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
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->primary.remote_port;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
/* NOP */
|
||||
(void)cf;
|
||||
(void)data;
|
||||
(void)ps;
|
||||
}
|
||||
|
||||
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->do_close(cf, data);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t Curl_cf_recv(struct Curl_easy *data, int num, char *buf,
|
||||
size_t len, CURLcode *code)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
*code = CURLE_OK;
|
||||
cf = data->conn->cfilter[num];
|
||||
while(cf && !cf->connected) {
|
||||
cf = cf->next;
|
||||
}
|
||||
if(cf) {
|
||||
ssize_t nread = cf->cft->do_recv(cf, data, buf, len, code);
|
||||
DEBUGASSERT(nread >= 0 || *code);
|
||||
DEBUGASSERT(nread < 0 || !*code);
|
||||
return nread;
|
||||
}
|
||||
failf(data, "recv: no filter connected");
|
||||
*code = CURLE_FAILED_INIT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t Curl_cf_send(struct Curl_easy *data, int num,
|
||||
const void *mem, size_t len, CURLcode *code)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
*code = CURLE_OK;
|
||||
cf = data->conn->cfilter[num];
|
||||
while(cf && !cf->connected) {
|
||||
cf = cf->next;
|
||||
}
|
||||
if(cf) {
|
||||
ssize_t nwritten = cf->cft->do_send(cf, data, mem, len, code);
|
||||
DEBUGASSERT(nwritten >= 0 || *code);
|
||||
DEBUGASSERT(nwritten < 0 || !*code || !len);
|
||||
return nwritten;
|
||||
}
|
||||
failf(data, "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(1, sizeof(*cf));
|
||||
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;
|
||||
CURL_TRC_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;
|
||||
}
|
||||
|
||||
bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf,
|
||||
struct Curl_cfilter *discard,
|
||||
struct Curl_easy *data,
|
||||
bool destroy_always)
|
||||
{
|
||||
struct Curl_cfilter **pprev = &cf->next;
|
||||
bool found = FALSE;
|
||||
|
||||
/* remove from sub-chain and destroy */
|
||||
DEBUGASSERT(cf);
|
||||
while(*pprev) {
|
||||
if(*pprev == cf) {
|
||||
*pprev = discard->next;
|
||||
discard->next = NULL;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
pprev = &((*pprev)->next);
|
||||
}
|
||||
if(found || destroy_always) {
|
||||
discard->next = NULL;
|
||||
discard->cft->destroy(discard, data);
|
||||
free(discard);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
bool blocking, bool *done)
|
||||
{
|
||||
if(cf)
|
||||
return cf->cft->do_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->do_close(cf, data);
|
||||
}
|
||||
|
||||
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->do_connect(cf, data, blocking, done);
|
||||
if(!result && *done) {
|
||||
Curl_conn_ev_update_info(data, data->conn);
|
||||
conn_report_connect_stats(data, data->conn);
|
||||
data->conn->keepalive = Curl_now();
|
||||
}
|
||||
else if(result) {
|
||||
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_cf_is_ssl(struct Curl_cfilter *cf)
|
||||
{
|
||||
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_ssl(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
return conn? Curl_conn_cf_is_ssl(conn->cfilter[sockindex]) : 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;
|
||||
}
|
||||
|
||||
void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
/* Get the lowest not-connected filter, if there are any */
|
||||
while(cf && !cf->connected && cf->next && !cf->next->connected)
|
||||
cf = cf->next;
|
||||
/* From there on, give all filters a chance to adjust the pollset.
|
||||
* Lower filters are called later, so they may override */
|
||||
while(cf) {
|
||||
cf->cft->adjust_pollset(cf, data, ps);
|
||||
cf = cf->next;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_conn_adjust_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
for(i = 0; i < 2; ++i) {
|
||||
Curl_conn_cf_adjust_pollset(data->conn->cfilter[i], data, ps);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex)
|
||||
{
|
||||
if(data->conn) {
|
||||
struct Curl_cfilter *cf = data->conn->cfilter[sockindex];
|
||||
if(cf)
|
||||
(void)Curl_conn_cf_cntrl(cf, data, TRUE,
|
||||
CF_CTRL_FORGET_SOCKET, 0, NULL);
|
||||
fake_sclose(data->conn->sock[sockindex]);
|
||||
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 done 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update connection statistics
|
||||
*/
|
||||
static void 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;
|
||||
}
|
||||
|
||||
int Curl_conn_get_stream_error(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_STREAM_ERROR,
|
||||
&n, NULL) : CURLE_UNKNOWN_OPTION;
|
||||
return (result || n < 0)? 0 : n;
|
||||
}
|
||||
|
||||
int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd)
|
||||
{
|
||||
if(data && data->conn &&
|
||||
sockfd != CURL_SOCKET_BAD && sockfd == data->conn->sock[SECONDARYSOCKET])
|
||||
return SECONDARYSOCKET;
|
||||
return FIRSTSOCKET;
|
||||
}
|
||||
|
||||
CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex,
|
||||
char *buf, size_t blen, ssize_t *n)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
ssize_t nread;
|
||||
|
||||
DEBUGASSERT(data->conn);
|
||||
nread = data->conn->recv[sockindex](data, sockindex, buf, blen, &result);
|
||||
DEBUGASSERT(nread >= 0 || result);
|
||||
DEBUGASSERT(nread < 0 || !result);
|
||||
*n = (nread >= 0)? (size_t)nread : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t blen,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
ssize_t nwritten;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn;
|
||||
|
||||
DEBUGASSERT(sockindex >= 0 && sockindex < 2);
|
||||
DEBUGASSERT(pnwritten);
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
conn = data->conn;
|
||||
#ifdef CURLDEBUG
|
||||
{
|
||||
/* Allow debug builds to override this logic to force short sends
|
||||
*/
|
||||
char *p = getenv("CURL_SMALLSENDS");
|
||||
if(p) {
|
||||
size_t altsize = (size_t)strtoul(p, NULL, 10);
|
||||
if(altsize)
|
||||
blen = CURLMIN(blen, altsize);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
nwritten = conn->send[sockindex](data, sockindex, buf, blen, &result);
|
||||
DEBUGASSERT((nwritten >= 0) || result);
|
||||
*pnwritten = (nwritten < 0)? 0 : (size_t)nwritten;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_pollset_reset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
size_t i;
|
||||
(void)data;
|
||||
memset(ps, 0, sizeof(*ps));
|
||||
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
|
||||
ps->sockets[i] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void Curl_pollset_change(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
int add_flags, int remove_flags)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
(void)data;
|
||||
DEBUGASSERT(VALID_SOCK(sock));
|
||||
if(!VALID_SOCK(sock))
|
||||
return;
|
||||
|
||||
DEBUGASSERT(add_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
|
||||
DEBUGASSERT(remove_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
|
||||
DEBUGASSERT((add_flags&remove_flags) == 0); /* no overlap */
|
||||
for(i = 0; i < ps->num; ++i) {
|
||||
if(ps->sockets[i] == sock) {
|
||||
ps->actions[i] &= (unsigned char)(~remove_flags);
|
||||
ps->actions[i] |= (unsigned char)add_flags;
|
||||
/* all gone? remove socket */
|
||||
if(!ps->actions[i]) {
|
||||
if((i + 1) < ps->num) {
|
||||
memmove(&ps->sockets[i], &ps->sockets[i + 1],
|
||||
(ps->num - (i + 1)) * sizeof(ps->sockets[0]));
|
||||
memmove(&ps->actions[i], &ps->actions[i + 1],
|
||||
(ps->num - (i + 1)) * sizeof(ps->actions[0]));
|
||||
}
|
||||
--ps->num;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* not present */
|
||||
if(add_flags) {
|
||||
/* Having more SOCKETS per easy handle than what is defined
|
||||
* is a programming error. This indicates that we need
|
||||
* to raise this limit, making easy_pollset larger.
|
||||
* Since we use this in tight loops, we do not want to make
|
||||
* the pollset dynamic unnecessarily.
|
||||
* The current maximum in practise is HTTP/3 eyeballing where
|
||||
* we have up to 4 sockets involved in connection setup.
|
||||
*/
|
||||
DEBUGASSERT(i < MAX_SOCKSPEREASYHANDLE);
|
||||
if(i < MAX_SOCKSPEREASYHANDLE) {
|
||||
ps->sockets[i] = sock;
|
||||
ps->actions[i] = (unsigned char)add_flags;
|
||||
ps->num = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pollset_set(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool do_in, bool do_out)
|
||||
{
|
||||
Curl_pollset_change(data, ps, sock,
|
||||
(do_in?CURL_POLL_IN:0)|(do_out?CURL_POLL_OUT:0),
|
||||
(!do_in?CURL_POLL_IN:0)|(!do_out?CURL_POLL_OUT:0));
|
||||
}
|
||||
|
||||
static void ps_add(struct Curl_easy *data, struct easy_pollset *ps,
|
||||
int bitmap, curl_socket_t *socks)
|
||||
{
|
||||
if(bitmap) {
|
||||
int i;
|
||||
for(i = 0; i < MAX_SOCKSPEREASYHANDLE; ++i) {
|
||||
if(!(bitmap & GETSOCK_MASK_RW(i)) || !VALID_SOCK((socks[i]))) {
|
||||
break;
|
||||
}
|
||||
if(bitmap & GETSOCK_READSOCK(i)) {
|
||||
if(bitmap & GETSOCK_WRITESOCK(i))
|
||||
Curl_pollset_add_inout(data, ps, socks[i]);
|
||||
else
|
||||
/* is READ, since we checked MASK_RW above */
|
||||
Curl_pollset_add_in(data, ps, socks[i]);
|
||||
}
|
||||
else
|
||||
Curl_pollset_add_out(data, ps, socks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pollset_add_socks(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
int (*get_socks_cb)(struct Curl_easy *data,
|
||||
curl_socket_t *socks))
|
||||
{
|
||||
curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
|
||||
int bitmap;
|
||||
|
||||
bitmap = get_socks_cb(data, socks);
|
||||
ps_add(data, ps, bitmap, socks);
|
||||
}
|
||||
|
||||
void Curl_pollset_check(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool *pwant_read, bool *pwant_write)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
(void)data;
|
||||
DEBUGASSERT(VALID_SOCK(sock));
|
||||
for(i = 0; i < ps->num; ++i) {
|
||||
if(ps->sockets[i] == sock) {
|
||||
*pwant_read = !!(ps->actions[i] & CURL_POLL_IN);
|
||||
*pwant_write = !!(ps->actions[i] & CURL_POLL_OUT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*pwant_read = *pwant_write = FALSE;
|
||||
}
|
644
third_party/curl/lib/cfilters.h
vendored
Normal file
644
third_party/curl/lib/cfilters.h
vendored
Normal file
@ -0,0 +1,644 @@
|
||||
#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);
|
||||
|
||||
struct easy_pollset;
|
||||
|
||||
/* Passing in an easy_pollset for monitoring of sockets, let
|
||||
* filters add or remove sockets actions (CURL_POLL_OUT, CURL_POLL_IN).
|
||||
* This may add a socket or, in case no actions remain, remove
|
||||
* a socket from the set.
|
||||
*
|
||||
* Filter implementations need to call filters "below" *after* they have
|
||||
* made their adjustments. This allows lower filters to override "upper"
|
||||
* actions. If a "lower" filter is unable to write, it needs to be able
|
||||
* to disallow POLL_OUT.
|
||||
*
|
||||
* A filter without own restrictions/preferences should not modify
|
||||
* the pollset. Filters, whose filter "below" is not connected, should
|
||||
* also do no adjustments.
|
||||
*
|
||||
* Examples: a TLS handshake, while ongoing, might remove POLL_IN
|
||||
* when it needs to write, or vice versa. A HTTP/2 filter might remove
|
||||
* POLL_OUT when a stream window is exhausted and a WINDOW_UPDATE needs
|
||||
* to be received first and add instead POLL_IN.
|
||||
*
|
||||
* @param cf the filter to ask
|
||||
* @param data the easy handle the pollset is about
|
||||
* @param ps the pollset (inout) for the easy handle
|
||||
*/
|
||||
typedef void Curl_cft_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
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 */
|
||||
#define CF_CTRL_FORGET_SOCKET (256+1) /* 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 */
|
||||
#define CF_QUERY_STREAM_ERROR 6 /* error code - */
|
||||
|
||||
/**
|
||||
* 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
|
||||
* CF_TYPE_PROXY provides proxying
|
||||
*/
|
||||
#define CF_TYPE_IP_CONNECT (1 << 0)
|
||||
#define CF_TYPE_SSL (1 << 1)
|
||||
#define CF_TYPE_MULTIPLEX (1 << 2)
|
||||
#define CF_TYPE_PROXY (1 << 3)
|
||||
|
||||
/* 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 *do_connect; /* establish connection */
|
||||
Curl_cft_close *do_close; /* close conn */
|
||||
Curl_cft_get_host *get_host; /* host filter talks to */
|
||||
Curl_cft_adjust_pollset *adjust_pollset; /* adjust transfer poll set */
|
||||
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_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const char **phost, const char **pdisplay_host,
|
||||
int *pport);
|
||||
void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
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 `discard` iff
|
||||
* it still is in the filter chain below `cf`. If `discard`
|
||||
* is no longer found beneath `cf` return FALSE.
|
||||
* if `destroy_always` is TRUE, will call `discard`s destroy
|
||||
* function and free it even if not found in the subchain.
|
||||
*/
|
||||
bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf,
|
||||
struct Curl_cfilter *discard,
|
||||
struct Curl_easy *data,
|
||||
bool destroy_always);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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);
|
||||
|
||||
/**
|
||||
* Determine if the connection filter chain is using SSL to the remote host
|
||||
* (or will be once connected).
|
||||
*/
|
||||
bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Tell filters to forget about the socket at sockindex.
|
||||
*/
|
||||
void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex);
|
||||
|
||||
/**
|
||||
* Adjust the pollset for the filter chain startgin at `cf`.
|
||||
*/
|
||||
void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/**
|
||||
* Adjust pollset from filters installed at transfer's connection.
|
||||
*/
|
||||
void Curl_conn_adjust_pollset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/**
|
||||
* Receive data through the filter chain at `sockindex` for connection
|
||||
* `data->conn`. Copy at most `len` bytes into `buf`. Return the
|
||||
* actual number of bytes copied or a negative value on error.
|
||||
* The error code is placed into `*code`.
|
||||
*/
|
||||
ssize_t Curl_cf_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_cf_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 done 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);
|
||||
|
||||
/**
|
||||
* 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_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data);
|
||||
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);
|
||||
|
||||
/**
|
||||
* Get the underlying error code for a transfer stream or 0 if not known.
|
||||
*/
|
||||
int Curl_conn_get_stream_error(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex);
|
||||
|
||||
/**
|
||||
* Get the index of the given socket in the connection's sockets.
|
||||
* Useful in calling `Curl_conn_send()/Curl_conn_recv()` with the
|
||||
* correct socket index.
|
||||
*/
|
||||
int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd);
|
||||
|
||||
/*
|
||||
* Receive data on the connection, using FIRSTSOCKET/SECONDARYSOCKET.
|
||||
* Will return CURLE_AGAIN iff blocked on receiving.
|
||||
*/
|
||||
CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex,
|
||||
char *buf, size_t buffersize,
|
||||
ssize_t *pnread);
|
||||
|
||||
/*
|
||||
* Send data on the connection, using FIRSTSOCKET/SECONDARYSOCKET.
|
||||
* Will return CURLE_AGAIN iff blocked on sending.
|
||||
*/
|
||||
CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t blen,
|
||||
size_t *pnwritten);
|
||||
|
||||
|
||||
void Curl_pollset_reset(struct Curl_easy *data,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
/* Change the poll flags (CURL_POLL_IN/CURL_POLL_OUT) to the poll set for
|
||||
* socket `sock`. If the socket is not already part of the poll set, it
|
||||
* will be added.
|
||||
* If the socket is present and all poll flags are cleared, it will be removed.
|
||||
*/
|
||||
void Curl_pollset_change(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
int add_flags, int remove_flags);
|
||||
|
||||
void Curl_pollset_set(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool do_in, bool do_out);
|
||||
|
||||
#define Curl_pollset_add_in(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), CURL_POLL_IN, 0)
|
||||
#define Curl_pollset_add_out(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), CURL_POLL_OUT, 0)
|
||||
#define Curl_pollset_add_inout(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), \
|
||||
CURL_POLL_IN|CURL_POLL_OUT, 0)
|
||||
#define Curl_pollset_set_in_only(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), \
|
||||
CURL_POLL_IN, CURL_POLL_OUT)
|
||||
#define Curl_pollset_set_out_only(data, ps, sock) \
|
||||
Curl_pollset_change((data), (ps), (sock), \
|
||||
CURL_POLL_OUT, CURL_POLL_IN)
|
||||
|
||||
void Curl_pollset_add_socks(struct Curl_easy *data,
|
||||
struct easy_pollset *ps,
|
||||
int (*get_socks_cb)(struct Curl_easy *data,
|
||||
curl_socket_t *socks));
|
||||
|
||||
/**
|
||||
* Check if the pollset, as is, wants to read and/or write regarding
|
||||
* the given socket.
|
||||
*/
|
||||
void Curl_pollset_check(struct Curl_easy *data,
|
||||
struct easy_pollset *ps, curl_socket_t sock,
|
||||
bool *pwant_read, bool *pwant_write);
|
||||
|
||||
/**
|
||||
* 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 */
|
129
third_party/curl/lib/config-amigaos.h
vendored
Normal file
129
third_party/curl/lib/config-amigaos.h
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
#ifndef HEADER_CURL_CONFIG_AMIGAOS_H
|
||||
#define HEADER_CURL_CONFIG_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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* ================================================================ */
|
||||
/* Hand crafted config file for AmigaOS */
|
||||
/* ================================================================ */
|
||||
|
||||
#ifdef __AMIGA__ /* Any AmigaOS flavour */
|
||||
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_CLOSESOCKET_CAMEL 1
|
||||
#define HAVE_IOCTLSOCKET_CAMEL 1
|
||||
#define HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1
|
||||
#define HAVE_LONGLONG 1
|
||||
#define HAVE_NETDB_H 1
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_NET_IF_H 1
|
||||
#define HAVE_PWD_H 1
|
||||
#define HAVE_SELECT 1
|
||||
#define HAVE_SIGNAL 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define HAVE_STRDUP 1
|
||||
#define HAVE_STRICMP 1
|
||||
#define HAVE_STRINGS_H 1
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_SOCKIO_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_UTIME 1
|
||||
#define HAVE_UTIME_H 1
|
||||
#define HAVE_WRITABLE_ARGV 1
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
#define NEED_MALLOC_H 1
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_SIZE_T 4
|
||||
|
||||
#ifndef SIZEOF_CURL_OFF_T
|
||||
#define SIZEOF_CURL_OFF_T 8
|
||||
#endif
|
||||
|
||||
#define USE_MANUAL 1
|
||||
#define CURL_DISABLE_LDAP 1
|
||||
|
||||
#ifndef OS
|
||||
#define OS "AmigaOS"
|
||||
#endif
|
||||
|
||||
#define PACKAGE "curl"
|
||||
#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.se/mail/"
|
||||
#define PACKAGE_NAME "curl"
|
||||
#define PACKAGE_STRING "curl -"
|
||||
#define PACKAGE_TARNAME "curl"
|
||||
#define PACKAGE_VERSION "-"
|
||||
|
||||
#if defined(USE_AMISSL)
|
||||
#define CURL_CA_PATH "AmiSSL:Certs"
|
||||
#elif defined(__MORPHOS__)
|
||||
#define CURL_CA_BUNDLE "MOSSYS:Data/SSL/curl-ca-bundle.crt"
|
||||
#else
|
||||
#define CURL_CA_BUNDLE "s:curl-ca-bundle.crt"
|
||||
#endif
|
||||
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
#define in_addr_t int
|
||||
|
||||
#ifndef F_OK
|
||||
# define F_OK 0
|
||||
#endif
|
||||
|
||||
#ifndef O_RDONLY
|
||||
# define O_RDONLY 0x0000
|
||||
#endif
|
||||
|
||||
#ifndef LONG_MAX
|
||||
# define LONG_MAX 0x7fffffffL
|
||||
#endif
|
||||
|
||||
#ifndef LONG_MIN
|
||||
# define LONG_MIN (-0x7fffffffL-1)
|
||||
#endif
|
||||
|
||||
#define HAVE_RECV 1
|
||||
#define RECV_TYPE_ARG1 long
|
||||
#define RECV_TYPE_ARG2 char *
|
||||
#define RECV_TYPE_ARG3 long
|
||||
#define RECV_TYPE_ARG4 long
|
||||
#define RECV_TYPE_RETV long
|
||||
|
||||
#define HAVE_SEND 1
|
||||
#define SEND_TYPE_ARG1 int
|
||||
#define SEND_QUAL_ARG2 const
|
||||
#define SEND_TYPE_ARG2 char *
|
||||
#define SEND_TYPE_ARG3 int
|
||||
#define SEND_TYPE_ARG4 int
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
#endif /* __AMIGA__ */
|
||||
#endif /* HEADER_CURL_CONFIG_AMIGAOS_H */
|
138
third_party/curl/lib/config-dos.h
vendored
Normal file
138
third_party/curl/lib/config-dos.h
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
#ifndef HEADER_CURL_CONFIG_DOS_H
|
||||
#define HEADER_CURL_CONFIG_DOS_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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/* ================================================================ */
|
||||
/* lib/config-dos.h - Hand crafted config file for DOS */
|
||||
/* ================================================================ */
|
||||
|
||||
#ifndef OS
|
||||
#if defined(DJGPP)
|
||||
#define OS "MSDOS/djgpp"
|
||||
#elif defined(__HIGHC__)
|
||||
#define OS "MSDOS/HighC"
|
||||
#else
|
||||
#define OS "MSDOS/?"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define PACKAGE "curl"
|
||||
|
||||
#define USE_MANUAL 1
|
||||
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_FREEADDRINFO 1
|
||||
#define HAVE_GETADDRINFO 1
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#define HAVE_IO_H 1
|
||||
#define HAVE_IOCTL_FIONBIO 1
|
||||
#define HAVE_IOCTLSOCKET 1
|
||||
#define HAVE_IOCTLSOCKET_FIONBIO 1
|
||||
#define HAVE_LOCALE_H 1
|
||||
#define HAVE_LONGLONG 1
|
||||
#define HAVE_NETDB_H 1
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_NETINET_TCP_H 1
|
||||
#define HAVE_NET_IF_H 1
|
||||
#define HAVE_RECV 1
|
||||
#define HAVE_SELECT 1
|
||||
#define HAVE_SEND 1
|
||||
#define HAVE_SETLOCALE 1
|
||||
#define HAVE_SETMODE 1
|
||||
#define HAVE_SIGNAL 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_STRDUP 1
|
||||
#define HAVE_STRICMP 1
|
||||
#define HAVE_STRTOLL 1
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
#define NEED_MALLOC_H 1
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_LONG 4
|
||||
#define SIZEOF_SIZE_T 4
|
||||
#define SIZEOF_CURL_OFF_T 8
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Qualifiers for send() and recv() */
|
||||
|
||||
#define SEND_TYPE_ARG1 int
|
||||
#define SEND_QUAL_ARG2 const
|
||||
#define SEND_TYPE_ARG2 void *
|
||||
#define SEND_TYPE_ARG3 int
|
||||
#define SEND_TYPE_ARG4 int
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
#define RECV_TYPE_ARG1 int
|
||||
#define RECV_TYPE_ARG2 void *
|
||||
#define RECV_TYPE_ARG3 int
|
||||
#define RECV_TYPE_ARG4 int
|
||||
#define RECV_TYPE_RETV int
|
||||
|
||||
#define BSD
|
||||
|
||||
/* CURLDEBUG definition enables memory tracking */
|
||||
/* #define CURLDEBUG */
|
||||
|
||||
/* to disable LDAP */
|
||||
#define CURL_DISABLE_LDAP 1
|
||||
|
||||
#define in_addr_t u_long
|
||||
|
||||
#if defined(__HIGHC__) || \
|
||||
(defined(__GNUC__) && (__GNUC__ < 4))
|
||||
#define ssize_t int
|
||||
#endif
|
||||
|
||||
/* Target HAVE_x section */
|
||||
|
||||
#if defined(DJGPP)
|
||||
#define HAVE_BASENAME 1
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define HAVE_SIGACTION 1
|
||||
#define HAVE_SIGSETJMP 1
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
#elif defined(__HIGHC__)
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#define strerror(e) strerror_s_((e))
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS /* Watt-32 */
|
||||
#define HAVE_CLOSE_S 1
|
||||
#endif
|
||||
|
||||
#undef word
|
||||
#undef byte
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_DOS_H */
|
103
third_party/curl/lib/config-mac.h
vendored
Normal file
103
third_party/curl/lib/config-mac.h
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
#ifndef HEADER_CURL_CONFIG_MAC_H
|
||||
#define HEADER_CURL_CONFIG_MAC_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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* =================================================================== */
|
||||
/* Hand crafted config file for Mac OS 9 */
|
||||
/* =================================================================== */
|
||||
/* On Mac OS X you must run configure to generate curl_config.h file */
|
||||
/* =================================================================== */
|
||||
|
||||
#ifndef OS
|
||||
#define OS "mac"
|
||||
#endif
|
||||
|
||||
#include <ConditionalMacros.h>
|
||||
#if TYPE_LONGLONG
|
||||
#define HAVE_LONGLONG 1
|
||||
#endif
|
||||
|
||||
/* Define if you want the built-in manual */
|
||||
#define USE_MANUAL 1
|
||||
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_NETDB_H 1
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_NET_IF_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_UTIME_H 1
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#define HAVE_SYS_UTIME_H 1
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
#define HAVE_ALARM 1
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#define HAVE_UTIME 1
|
||||
#define HAVE_SELECT 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
#define HAVE_SIGACTION 1
|
||||
|
||||
#ifdef MACOS_SSL_SUPPORT
|
||||
# define USE_OPENSSL 1
|
||||
#endif
|
||||
|
||||
#define CURL_DISABLE_LDAP 1
|
||||
|
||||
#define HAVE_IOCTL_FIONBIO 1
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_LONG 4
|
||||
#define SIZEOF_SIZE_T 4
|
||||
#ifdef HAVE_LONGLONG
|
||||
#define SIZEOF_CURL_OFF_T 8
|
||||
#else
|
||||
#define SIZEOF_CURL_OFF_T 4
|
||||
#endif
|
||||
|
||||
#define HAVE_RECV 1
|
||||
#define RECV_TYPE_ARG1 int
|
||||
#define RECV_TYPE_ARG2 void *
|
||||
#define RECV_TYPE_ARG3 size_t
|
||||
#define RECV_TYPE_ARG4 int
|
||||
#define RECV_TYPE_RETV ssize_t
|
||||
|
||||
#define HAVE_SEND 1
|
||||
#define SEND_TYPE_ARG1 int
|
||||
#define SEND_QUAL_ARG2 const
|
||||
#define SEND_TYPE_ARG2 void *
|
||||
#define SEND_TYPE_ARG3 size_t
|
||||
#define SEND_TYPE_ARG4 int
|
||||
#define SEND_TYPE_RETV ssize_t
|
||||
|
||||
#define HAVE_EXTRA_STRICMP_H 1
|
||||
#define HAVE_EXTRA_STRDUP_H 1
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_MAC_H */
|
334
third_party/curl/lib/config-os400.h
vendored
Normal file
334
third_party/curl/lib/config-os400.h
vendored
Normal file
@ -0,0 +1,334 @@
|
||||
#ifndef HEADER_CURL_CONFIG_OS400_H
|
||||
#define HEADER_CURL_CONFIG_OS400_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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* ================================================================ */
|
||||
/* Hand crafted config file for OS/400 */
|
||||
/* ================================================================ */
|
||||
|
||||
#pragma enum(int)
|
||||
|
||||
#undef PACKAGE
|
||||
|
||||
/* Version number of this archive. */
|
||||
#undef VERSION
|
||||
|
||||
/* Define cpu-machine-OS */
|
||||
#ifndef OS
|
||||
#define OS "OS/400"
|
||||
#endif
|
||||
|
||||
/* OS400 supports a 3-argument ASCII version of gethostbyaddr_r(), but its
|
||||
* prototype is incompatible with the "standard" one (1st argument is not
|
||||
* const). However, getaddrinfo() is supported (ASCII version defined as
|
||||
* a local wrapper in setup-os400.h) in a threadsafe way: we can then
|
||||
* configure getaddrinfo() as such and get rid of gethostbyname_r() without
|
||||
* loss of threadsafeness. */
|
||||
#undef HAVE_GETHOSTBYNAME_R
|
||||
#undef HAVE_GETHOSTBYNAME_R_3
|
||||
#undef HAVE_GETHOSTBYNAME_R_5
|
||||
#undef HAVE_GETHOSTBYNAME_R_6
|
||||
#define HAVE_GETADDRINFO
|
||||
#define HAVE_GETADDRINFO_THREADSAFE
|
||||
|
||||
/* Define if you need the _REENTRANT define for some functions */
|
||||
#undef NEED_REENTRANT
|
||||
|
||||
/* Define if you want to enable IPv6 support */
|
||||
#define USE_IPV6
|
||||
|
||||
/* Define if struct sockaddr_in6 has the sin6_scope_id member */
|
||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
|
||||
/* Define this to 'int' if ssize_t is not an available typedefed type */
|
||||
#undef ssize_t
|
||||
|
||||
/* Define this as a suitable file to read random data from */
|
||||
#undef RANDOM_FILE
|
||||
|
||||
/* Define to 1 if you have the alarm function. */
|
||||
#define HAVE_ALARM 1
|
||||
|
||||
/* Define if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H
|
||||
|
||||
/* Define if you have the `closesocket' function. */
|
||||
#undef HAVE_CLOSESOCKET
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H
|
||||
|
||||
/* Define if you have the `geteuid' function. */
|
||||
#define HAVE_GETEUID
|
||||
|
||||
/* Define if you have the `gethostname' function. */
|
||||
#define HAVE_GETHOSTNAME
|
||||
|
||||
/* Define if you have the `getpass_r' function. */
|
||||
#undef HAVE_GETPASS_R
|
||||
|
||||
/* Define to 1 if you have the getpeername function. */
|
||||
#define HAVE_GETPEERNAME 1
|
||||
|
||||
/* Define if you have the `getpwuid' function. */
|
||||
#define HAVE_GETPWUID
|
||||
|
||||
/* Define to 1 if you have the getsockname function. */
|
||||
#define HAVE_GETSOCKNAME 1
|
||||
|
||||
/* Define if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define if you have the `timeval' struct. */
|
||||
#define HAVE_STRUCT_TIMEVAL
|
||||
|
||||
/* Define if you have the <io.h> header file. */
|
||||
#undef HAVE_IO_H
|
||||
|
||||
/* Define if you have the `socket' library (-lsocket). */
|
||||
#undef HAVE_LIBSOCKET
|
||||
|
||||
/* Define if you have GSS API. */
|
||||
#define HAVE_GSSAPI
|
||||
|
||||
/* Define if you have the GNU gssapi libraries */
|
||||
#undef HAVE_GSSGNU
|
||||
|
||||
/* Define if you need the malloc.h header file even with stdlib.h */
|
||||
/* #define NEED_MALLOC_H 1 */
|
||||
|
||||
/* Define if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H
|
||||
|
||||
/* Define if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H
|
||||
|
||||
/* Define if you have the <net/if.h> header file. */
|
||||
#define HAVE_NET_IF_H
|
||||
|
||||
/* Define if you have the <pwd.h> header file. */
|
||||
#define HAVE_PWD_H
|
||||
|
||||
/* Define if you have the `select' function. */
|
||||
#define HAVE_SELECT
|
||||
|
||||
/* Define if you have the `sigaction' function. */
|
||||
#define HAVE_SIGACTION
|
||||
|
||||
/* Define if you have the `signal' function. */
|
||||
#undef HAVE_SIGNAL
|
||||
|
||||
/* Define if you have the `socket' function. */
|
||||
#define HAVE_SOCKET
|
||||
|
||||
|
||||
/* The following define is needed on OS400 to enable strcmpi(), stricmp() and
|
||||
strdup(). */
|
||||
#define __cplusplus__strings__
|
||||
|
||||
/* Define if you have the `strcasecmp' function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define if you have the `strcmpi' function. */
|
||||
#define HAVE_STRCMPI
|
||||
|
||||
/* Define if you have the `stricmp' function. */
|
||||
#define HAVE_STRICMP
|
||||
|
||||
/* Define if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP
|
||||
|
||||
/* Define if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H
|
||||
|
||||
/* Define if you have the <stropts.h> header file. */
|
||||
#undef HAVE_STROPTS_H
|
||||
|
||||
/* Define if you have the `strtok_r' function. */
|
||||
#define HAVE_STRTOK_R
|
||||
|
||||
/* Define if you have the `strtoll' function. */
|
||||
#undef HAVE_STRTOLL /* Allows ASCII compile on V5R1. */
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define if you have the <sys/sockio.h> header file. */
|
||||
#undef HAVE_SYS_SOCKIO_H
|
||||
|
||||
/* Define if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H
|
||||
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define if you have the <sys/un.h> header file. */
|
||||
#define HAVE_SYS_UN_H
|
||||
|
||||
/* Define if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define if you have the <termios.h> header file. */
|
||||
#undef HAVE_TERMIOS_H
|
||||
|
||||
/* Define if you have the <termio.h> header file. */
|
||||
#undef HAVE_TERMIO_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* Define if the compiler supports the 'long long' data type. */
|
||||
#define HAVE_LONGLONG
|
||||
|
||||
/* The size of a `long long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG 4
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#define SIZEOF_SIZE_T 4
|
||||
|
||||
/* The size of `curl_off_t', as computed by sizeof. */
|
||||
#define SIZEOF_CURL_OFF_T 8
|
||||
|
||||
/* Define this if you have struct sockaddr_storage */
|
||||
#define HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS
|
||||
|
||||
/* Define to enable HTTP3 support (experimental, requires NGTCP2, QUICHE or
|
||||
MSH3) */
|
||||
#undef USE_HTTP3
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#define _LARGE_FILES
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* type to use in place of in_addr_t if not defined */
|
||||
#define in_addr_t unsigned long
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define if you have a working ioctl FIONBIO function. */
|
||||
#define HAVE_IOCTL_FIONBIO
|
||||
|
||||
/* Define if you have a working ioctl SIOCGIFADDR function. */
|
||||
#define HAVE_IOCTL_SIOCGIFADDR
|
||||
|
||||
/* To disable LDAP */
|
||||
#undef CURL_DISABLE_LDAP
|
||||
|
||||
/* Definition to make a library symbol externally visible. */
|
||||
#define CURL_EXTERN_SYMBOL
|
||||
|
||||
/* Define if you have the ldap_url_parse procedure. */
|
||||
/* #define HAVE_LDAP_URL_PARSE */ /* Disabled because of an IBM bug. */
|
||||
|
||||
/* Define if you have the recv function. */
|
||||
#define HAVE_RECV
|
||||
|
||||
/* Define to the type of arg 1 for recv. */
|
||||
#define RECV_TYPE_ARG1 int
|
||||
|
||||
/* Define to the type of arg 2 for recv. */
|
||||
#define RECV_TYPE_ARG2 char *
|
||||
|
||||
/* Define to the type of arg 3 for recv. */
|
||||
#define RECV_TYPE_ARG3 int
|
||||
|
||||
/* Define to the type of arg 4 for recv. */
|
||||
#define RECV_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for recv. */
|
||||
#define RECV_TYPE_RETV int
|
||||
|
||||
/* Define if you have the send function. */
|
||||
#define HAVE_SEND
|
||||
|
||||
/* Define to the type of arg 1 for send. */
|
||||
#define SEND_TYPE_ARG1 int
|
||||
|
||||
/* Define to the type qualifier of arg 2 for send. */
|
||||
#define SEND_QUAL_ARG2
|
||||
|
||||
/* Define to the type of arg 2 for send. */
|
||||
#define SEND_TYPE_ARG2 char *
|
||||
|
||||
/* Define to the type of arg 3 for send. */
|
||||
#define SEND_TYPE_ARG3 int
|
||||
|
||||
/* Define to the type of arg 4 for send. */
|
||||
#define SEND_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for send. */
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
/* Define to use the OS/400 crypto library. */
|
||||
#define USE_OS400CRYPTO
|
||||
|
||||
/* Define to use Unix sockets. */
|
||||
#define USE_UNIX_SOCKETS
|
||||
|
||||
/* Use the system keyring as the default CA bundle. */
|
||||
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* ADDITIONAL DEFINITIONS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* The following must be defined BEFORE system header files inclusion. */
|
||||
|
||||
#define __ptr128 /* No teraspace. */
|
||||
#define qadrt_use_fputc_inline /* Generate fputc() wrapper inline. */
|
||||
#define qadrt_use_fread_inline /* Generate fread() wrapper inline. */
|
||||
#define qadrt_use_fwrite_inline /* Generate fwrite() wrapper inline. */
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_OS400_H */
|
147
third_party/curl/lib/config-plan9.h
vendored
Normal file
147
third_party/curl/lib/config-plan9.h
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
#ifndef HEADER_CURL_CONFIG_PLAN9_H
|
||||
#define HEADER_CURL_CONFIG_PLAN9_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 BUILDING_LIBCURL 1
|
||||
#define CURL_CA_BUNDLE "/sys/lib/tls/ca.pem"
|
||||
#define CURL_CA_PATH "/sys/lib/tls"
|
||||
#define CURL_STATICLIB 1
|
||||
#define USE_IPV6 1
|
||||
#define CURL_DISABLE_LDAP 1
|
||||
|
||||
#define NEED_REENTRANT 1
|
||||
#ifndef OS
|
||||
#define OS "plan9"
|
||||
#endif
|
||||
#define PACKAGE "curl"
|
||||
#define PACKAGE_NAME "curl"
|
||||
#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.se/mail/"
|
||||
#define PACKAGE_STRING "curl -"
|
||||
#define PACKAGE_TARNAME "curl"
|
||||
#define PACKAGE_VERSION "-"
|
||||
#define RANDOM_FILE "/dev/random"
|
||||
#define VERSION "0.0.0" /* TODO */
|
||||
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
#ifdef _BITS64
|
||||
#error not implement
|
||||
#else
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_LONG 4
|
||||
#define SIZEOF_OFF_T 8
|
||||
#define SIZEOF_CURL_OFF_T 4 /* curl_off_t = timediff_t = int */
|
||||
#define SIZEOF_SIZE_T 4
|
||||
#define SIZEOF_TIME_T 4
|
||||
#endif
|
||||
|
||||
#define HAVE_RECV 1
|
||||
#define RECV_TYPE_ARG1 int
|
||||
#define RECV_TYPE_ARG2 void *
|
||||
#define RECV_TYPE_ARG3 int
|
||||
#define RECV_TYPE_ARG4 int
|
||||
#define RECV_TYPE_RETV int
|
||||
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
#define HAVE_SEND 1
|
||||
#define SEND_TYPE_ARG1 int
|
||||
#define SEND_TYPE_ARG2 void *
|
||||
#define SEND_QUAL_ARG2
|
||||
#define SEND_TYPE_ARG3 int
|
||||
#define SEND_TYPE_ARG4 int
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
#define HAVE_ALARM 1
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_BASENAME 1
|
||||
#define HAVE_BOOL_T 1
|
||||
#define HAVE_FCNTL 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_FREEADDRINFO 1
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#define HAVE_GETADDRINFO 1
|
||||
#define HAVE_GETEUID 1
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
#define HAVE_GETPPID 1
|
||||
#define HAVE_GETPWUID 1
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#define HAVE_GMTIME_R 1
|
||||
#define HAVE_INET_NTOP 1
|
||||
#define HAVE_INET_PTON 1
|
||||
#define HAVE_LIBGEN_H 1
|
||||
#define HAVE_LIBZ 1
|
||||
#define HAVE_LOCALE_H 1
|
||||
#define HAVE_LONGLONG 1
|
||||
#define HAVE_NETDB_H 1
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_NETINET_TCP_H 1
|
||||
#define HAVE_PWD_H 1
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
||||
#define USE_OPENSSL 1
|
||||
|
||||
#define HAVE_PIPE 1
|
||||
#define HAVE_POLL_FINE 1
|
||||
#define HAVE_POLL_H 1
|
||||
#define HAVE_PTHREAD_H 1
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
#define HAVE_SIGACTION 1
|
||||
#define HAVE_SIGNAL 1
|
||||
#define HAVE_SIGSETJMP 1
|
||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_SSL_GET_SHUTDOWN 1
|
||||
#define HAVE_STDBOOL_H 1
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define HAVE_STRDUP 1
|
||||
#define HAVE_STRTOK_R 1
|
||||
#define HAVE_STRTOLL 1
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_SYS_UN_H 1
|
||||
#define HAVE_TERMIOS_H 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_UTIME 1
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
#define HAVE_POSIX_STRERROR_R 1
|
||||
#define HAVE_STRERROR_R 1
|
||||
#define USE_MANUAL 1
|
||||
|
||||
#define __attribute__(x)
|
||||
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_PLAN9_H */
|
277
third_party/curl/lib/config-riscos.h
vendored
Normal file
277
third_party/curl/lib/config-riscos.h
vendored
Normal file
@ -0,0 +1,277 @@
|
||||
#ifndef HEADER_CURL_CONFIG_RISCOS_H
|
||||
#define HEADER_CURL_CONFIG_RISCOS_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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* ================================================================ */
|
||||
/* Hand crafted config file for RISC OS */
|
||||
/* ================================================================ */
|
||||
|
||||
/* Name of this package! */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Version number of this archive. */
|
||||
#undef VERSION
|
||||
|
||||
/* Define cpu-machine-OS */
|
||||
#ifndef OS
|
||||
#define OS "ARM-RISC OS"
|
||||
#endif
|
||||
|
||||
/* Define if you want the built-in manual */
|
||||
#define USE_MANUAL
|
||||
|
||||
/* Define if you have the gethostbyname_r() function with 3 arguments */
|
||||
#undef HAVE_GETHOSTBYNAME_R_3
|
||||
|
||||
/* Define if you have the gethostbyname_r() function with 5 arguments */
|
||||
#undef HAVE_GETHOSTBYNAME_R_5
|
||||
|
||||
/* Define if you have the gethostbyname_r() function with 6 arguments */
|
||||
#undef HAVE_GETHOSTBYNAME_R_6
|
||||
|
||||
/* Define if you need the _REENTRANT define for some functions */
|
||||
#undef NEED_REENTRANT
|
||||
|
||||
/* Define if you want to enable IPv6 support */
|
||||
#undef USE_IPV6
|
||||
|
||||
/* Define if struct sockaddr_in6 has the sin6_scope_id member */
|
||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
|
||||
/* Define this to 'int' if ssize_t is not an available typedefed type */
|
||||
#undef ssize_t
|
||||
|
||||
/* Define this as a suitable file to read random data from */
|
||||
#undef RANDOM_FILE
|
||||
|
||||
/* Define if you have the alarm function. */
|
||||
#define HAVE_ALARM
|
||||
|
||||
/* Define if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H
|
||||
|
||||
/* Define if you have the `closesocket' function. */
|
||||
#undef HAVE_CLOSESOCKET
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H
|
||||
|
||||
/* Define if you have the `ftruncate' function. */
|
||||
#define HAVE_FTRUNCATE
|
||||
|
||||
/* Define if getaddrinfo exists and works */
|
||||
#define HAVE_GETADDRINFO
|
||||
|
||||
/* Define if you have the `geteuid' function. */
|
||||
#undef HAVE_GETEUID
|
||||
|
||||
/* Define if you have the `gethostbyname_r' function. */
|
||||
#undef HAVE_GETHOSTBYNAME_R
|
||||
|
||||
/* Define if you have the `gethostname' function. */
|
||||
#define HAVE_GETHOSTNAME
|
||||
|
||||
/* Define if you have the `getpass_r' function. */
|
||||
#undef HAVE_GETPASS_R
|
||||
|
||||
/* Define if you have the `getpwuid' function. */
|
||||
#undef HAVE_GETPWUID
|
||||
|
||||
/* Define if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define if you have the `timeval' struct. */
|
||||
#define HAVE_STRUCT_TIMEVAL
|
||||
|
||||
/* Define if you have the <io.h> header file. */
|
||||
#undef HAVE_IO_H
|
||||
|
||||
/* Define if you have the `socket' library (-lsocket). */
|
||||
#undef HAVE_LIBSOCKET
|
||||
|
||||
/* Define if you need the malloc.h header file even with stdlib.h */
|
||||
/* #define NEED_MALLOC_H 1 */
|
||||
|
||||
/* Define if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H
|
||||
|
||||
/* Define if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H
|
||||
|
||||
/* Define if you have the <net/if.h> header file. */
|
||||
#define HAVE_NET_IF_H
|
||||
|
||||
/* Define if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define if you have the `select' function. */
|
||||
#define HAVE_SELECT
|
||||
|
||||
/* Define if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define if you have the `signal' function. */
|
||||
#define HAVE_SIGNAL
|
||||
|
||||
/* Define if you have the `socket' function. */
|
||||
#define HAVE_SOCKET
|
||||
|
||||
/* Define if you have the `strcasecmp' function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define if you have the `strcmpi' function. */
|
||||
#undef HAVE_STRCMPI
|
||||
|
||||
/* Define if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP
|
||||
|
||||
/* Define if you have the `stricmp' function. */
|
||||
#define HAVE_STRICMP
|
||||
|
||||
/* Define if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define if you have the `strtok_r' function. */
|
||||
#undef HAVE_STRTOK_R
|
||||
|
||||
/* Define if you have the `strtoll' function. */
|
||||
#undef HAVE_STRTOLL
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define if you have the <sys/sockio.h> header file. */
|
||||
#undef HAVE_SYS_SOCKIO_H
|
||||
|
||||
/* Define if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H
|
||||
|
||||
/* Define if you have the <termio.h> header file. */
|
||||
#undef HAVE_TERMIO_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG_LONG
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#define SIZEOF_SIZE_T 4
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef ssize_t
|
||||
|
||||
/* Define if you have a working ioctl FIONBIO function. */
|
||||
#define HAVE_IOCTL_FIONBIO
|
||||
|
||||
/* to disable LDAP */
|
||||
#define CURL_DISABLE_LDAP
|
||||
|
||||
/* Define if you have the recv function. */
|
||||
#define HAVE_RECV 1
|
||||
|
||||
/* Define to the type of arg 1 for recv. */
|
||||
#define RECV_TYPE_ARG1 int
|
||||
|
||||
/* Define to the type of arg 2 for recv. */
|
||||
#define RECV_TYPE_ARG2 void *
|
||||
|
||||
/* Define to the type of arg 3 for recv. */
|
||||
#define RECV_TYPE_ARG3 size_t
|
||||
|
||||
/* Define to the type of arg 4 for recv. */
|
||||
#define RECV_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for recv. */
|
||||
#define RECV_TYPE_RETV ssize_t
|
||||
|
||||
/* Define if you have the send function. */
|
||||
#define HAVE_SEND 1
|
||||
|
||||
/* Define to the type of arg 1 for send. */
|
||||
#define SEND_TYPE_ARG1 int
|
||||
|
||||
/* Define to the type qualifier of arg 2 for send. */
|
||||
#define SEND_QUAL_ARG2 const
|
||||
|
||||
/* Define to the type of arg 2 for send. */
|
||||
#define SEND_TYPE_ARG2 void *
|
||||
|
||||
/* Define to the type of arg 3 for send. */
|
||||
#define SEND_TYPE_ARG3 size_t
|
||||
|
||||
/* Define to the type of arg 4 for send. */
|
||||
#define SEND_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for send. */
|
||||
#define SEND_TYPE_RETV ssize_t
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_RISCOS_H */
|
512
third_party/curl/lib/config-win32.h
vendored
Normal file
512
third_party/curl/lib/config-win32.h
vendored
Normal file
@ -0,0 +1,512 @@
|
||||
#ifndef HEADER_CURL_CONFIG_WIN32_H
|
||||
#define HEADER_CURL_CONFIG_WIN32_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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* ================================================================ */
|
||||
/* Hand crafted config file for Windows */
|
||||
/* ================================================================ */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* HEADER FILES */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the <arpa/inet.h> header file. */
|
||||
/* #define HAVE_ARPA_INET_H 1 */
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define if you have the <io.h> header file. */
|
||||
#define HAVE_IO_H 1
|
||||
|
||||
/* Define if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define if you need <malloc.h> header even with <stdlib.h> header file. */
|
||||
#define NEED_MALLOC_H 1
|
||||
|
||||
/* Define if you have the <netdb.h> header file. */
|
||||
/* #define HAVE_NETDB_H 1 */
|
||||
|
||||
/* Define if you have the <netinet/in.h> header file. */
|
||||
/* #define HAVE_NETINET_IN_H 1 */
|
||||
|
||||
/* Define to 1 if you have the <stdbool.h> header file. */
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || defined(__MINGW32__)
|
||||
#define HAVE_STDBOOL_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <sys/select.h> header file. */
|
||||
/* #define HAVE_SYS_SELECT_H 1 */
|
||||
|
||||
/* Define if you have the <sys/socket.h> header file. */
|
||||
/* #define HAVE_SYS_SOCKET_H 1 */
|
||||
|
||||
/* Define if you have the <sys/sockio.h> header file. */
|
||||
/* #define HAVE_SYS_SOCKIO_H 1 */
|
||||
|
||||
/* Define if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define if you have the <sys/utime.h> header file. */
|
||||
#define HAVE_SYS_UTIME_H 1
|
||||
|
||||
/* Define if you have the <termio.h> header file. */
|
||||
/* #define HAVE_TERMIO_H 1 */
|
||||
|
||||
/* Define if you have the <termios.h> header file. */
|
||||
/* #define HAVE_TERMIOS_H 1 */
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <libgen.h> header file. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_LIBGEN_H 1
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* OTHER HEADER INFO */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if bool is an available type. */
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || defined(__MINGW32__)
|
||||
#define HAVE_BOOL_T 1
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* FUNCTIONS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the closesocket function. */
|
||||
#define HAVE_CLOSESOCKET 1
|
||||
|
||||
/* Define if you have the ftruncate function. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the `getpeername' function. */
|
||||
#define HAVE_GETPEERNAME 1
|
||||
|
||||
/* Define to 1 if you have the getsockname function. */
|
||||
#define HAVE_GETSOCKNAME 1
|
||||
|
||||
/* Define if you have the gethostname function. */
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
|
||||
/* Define if you have the gettimeofday function. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
#define HAVE_IOCTLSOCKET 1
|
||||
|
||||
/* Define if you have a working ioctlsocket FIONBIO function. */
|
||||
#define HAVE_IOCTLSOCKET_FIONBIO 1
|
||||
|
||||
/* Define if you have the select function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define if you have the setlocale function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
/* Define if you have the setmode function. */
|
||||
#define HAVE_SETMODE 1
|
||||
|
||||
/* Define if you have the socket function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_STRCASECMP 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the strdup function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define if you have the stricmp function. */
|
||||
#define HAVE_STRICMP 1
|
||||
|
||||
/* Define if you have the strtoll function. */
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || defined(__MINGW32__)
|
||||
#define HAVE_STRTOLL 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the utime function. */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define if you have the recv function. */
|
||||
#define HAVE_RECV 1
|
||||
|
||||
/* Define to the type of arg 1 for recv. */
|
||||
#define RECV_TYPE_ARG1 SOCKET
|
||||
|
||||
/* Define to the type of arg 2 for recv. */
|
||||
#define RECV_TYPE_ARG2 char *
|
||||
|
||||
/* Define to the type of arg 3 for recv. */
|
||||
#define RECV_TYPE_ARG3 int
|
||||
|
||||
/* Define to the type of arg 4 for recv. */
|
||||
#define RECV_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for recv. */
|
||||
#define RECV_TYPE_RETV int
|
||||
|
||||
/* Define if you have the send function. */
|
||||
#define HAVE_SEND 1
|
||||
|
||||
/* Define to the type of arg 1 for send. */
|
||||
#define SEND_TYPE_ARG1 SOCKET
|
||||
|
||||
/* Define to the type qualifier of arg 2 for send. */
|
||||
#define SEND_QUAL_ARG2 const
|
||||
|
||||
/* Define to the type of arg 2 for send. */
|
||||
#define SEND_TYPE_ARG2 char *
|
||||
|
||||
/* Define to the type of arg 3 for send. */
|
||||
#define SEND_TYPE_ARG3 int
|
||||
|
||||
/* Define to the type of arg 4 for send. */
|
||||
#define SEND_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for send. */
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
/* Define to 1 if you have the snprintf function. */
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || defined(__MINGW32__)
|
||||
#define HAVE_SNPRINTF 1
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 /* Vista */
|
||||
/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
|
||||
#define HAVE_INET_NTOP 1
|
||||
/* Define to 1 if you have a IPv6 capable working inet_pton function. */
|
||||
#define HAVE_INET_PTON 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the `basename' function. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_BASENAME 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the strtok_r function. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_STRTOK_R 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the signal function. */
|
||||
#define HAVE_SIGNAL 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* TYPEDEF REPLACEMENTS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if in_addr_t is not an available 'typedefed' type. */
|
||||
#define in_addr_t unsigned long
|
||||
|
||||
/* Define if ssize_t is not an available 'typedefed' type. */
|
||||
#ifndef _SSIZE_T_DEFINED
|
||||
# if defined(__MINGW32__)
|
||||
# elif defined(_WIN64)
|
||||
# define _SSIZE_T_DEFINED
|
||||
# define ssize_t __int64
|
||||
# else
|
||||
# define _SSIZE_T_DEFINED
|
||||
# define ssize_t int
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* TYPE SIZES */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define to the size of `int', as computed by sizeof. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* Define to the size of `long long', as computed by sizeof. */
|
||||
/* #define SIZEOF_LONG_LONG 8 */
|
||||
|
||||
/* Define to the size of `long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG 4
|
||||
|
||||
/* Define to the size of `size_t', as computed by sizeof. */
|
||||
#if defined(_WIN64)
|
||||
# define SIZEOF_SIZE_T 8
|
||||
#else
|
||||
# define SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
/* Define to the size of `curl_off_t', as computed by sizeof. */
|
||||
#define SIZEOF_CURL_OFF_T 8
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* COMPILER SPECIFIC */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define to nothing if compiler does not support 'const' qualifier. */
|
||||
/* #define const */
|
||||
|
||||
/* Define to nothing if compiler does not support 'volatile' qualifier. */
|
||||
/* #define volatile */
|
||||
|
||||
/* Windows should not have HAVE_GMTIME_R defined */
|
||||
/* #undef HAVE_GMTIME_R */
|
||||
|
||||
/* Define if the compiler supports the 'long long' data type. */
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1310)) || defined(__MINGW32__)
|
||||
#define HAVE_LONGLONG 1
|
||||
#endif
|
||||
|
||||
/* Define to avoid VS2005 complaining about portable C functions. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
||||
/* mingw-w64 and visual studio >= 2005 (MSVCR80)
|
||||
all default to 64-bit time_t unless _USE_32BIT_TIME_T is defined */
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) || defined(__MINGW32__)
|
||||
# ifndef _USE_32BIT_TIME_T
|
||||
# define SIZEOF_TIME_T 8
|
||||
# else
|
||||
# define SIZEOF_TIME_T 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define some minimum and default build targets for Visual Studio */
|
||||
#if defined(_MSC_VER)
|
||||
/* Officially, Microsoft's Windows SDK versions 6.X does not support Windows
|
||||
2000 as a supported build target. VS2008 default installations provides
|
||||
an embedded Windows SDK v6.0A along with the claim that Windows 2000 is a
|
||||
valid build target for VS2008. Popular belief is that binaries built with
|
||||
VS2008 using Windows SDK versions v6.X and Windows 2000 as a build target
|
||||
are functional. */
|
||||
# define VS2008_MIN_TARGET 0x0500
|
||||
|
||||
/* The minimum build target for VS2012 is Vista unless Update 1 is installed
|
||||
and the v110_xp toolset is chosen. */
|
||||
# if defined(_USING_V110_SDK71_)
|
||||
# define VS2012_MIN_TARGET 0x0501
|
||||
# else
|
||||
# define VS2012_MIN_TARGET 0x0600
|
||||
# endif
|
||||
|
||||
/* VS2008 default build target is Windows Vista. We override default target
|
||||
to be Windows XP. */
|
||||
# define VS2008_DEF_TARGET 0x0501
|
||||
|
||||
/* VS2012 default build target is Windows Vista unless Update 1 is installed
|
||||
and the v110_xp toolset is chosen. */
|
||||
# if defined(_USING_V110_SDK71_)
|
||||
# define VS2012_DEF_TARGET 0x0501
|
||||
# else
|
||||
# define VS2012_DEF_TARGET 0x0600
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* VS2008 default target settings and minimum build target check. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (_MSC_VER <= 1600)
|
||||
# ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT VS2008_DEF_TARGET
|
||||
# endif
|
||||
# ifndef WINVER
|
||||
# define WINVER VS2008_DEF_TARGET
|
||||
# endif
|
||||
# if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET)
|
||||
# error VS2008 does not support Windows build targets prior to Windows 2000
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* VS2012 default target settings and minimum build target check. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1700)
|
||||
# ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT VS2012_DEF_TARGET
|
||||
# endif
|
||||
# ifndef WINVER
|
||||
# define WINVER VS2012_DEF_TARGET
|
||||
# endif
|
||||
# if (_WIN32_WINNT < VS2012_MIN_TARGET) || (WINVER < VS2012_MIN_TARGET)
|
||||
# if defined(_USING_V110_SDK71_)
|
||||
# error VS2012 does not support Windows build targets prior to Windows XP
|
||||
# else
|
||||
# error VS2012 does not support Windows build targets prior to Windows \
|
||||
Vista
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Windows XP is required for freeaddrinfo, getaddrinfo */
|
||||
#define HAVE_FREEADDRINFO 1
|
||||
#define HAVE_GETADDRINFO 1
|
||||
#define HAVE_GETADDRINFO_THREADSAFE 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* STRUCT RELATED */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have struct sockaddr_storage. */
|
||||
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
|
||||
/* Define if you have struct timeval. */
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
/* Define if struct sockaddr_in6 has the sin6_scope_id member. */
|
||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* LARGE FILE SUPPORT */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_WIN32_WCE)
|
||||
# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
|
||||
# define USE_WIN32_LARGE_FILES
|
||||
# else
|
||||
# define USE_WIN32_SMALL_FILES
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__) && !defined(USE_WIN32_LARGE_FILES)
|
||||
# define USE_WIN32_LARGE_FILES
|
||||
#endif
|
||||
|
||||
#if !defined(USE_WIN32_LARGE_FILES) && !defined(USE_WIN32_SMALL_FILES)
|
||||
# define USE_WIN32_SMALL_FILES
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#if defined(USE_WIN32_LARGE_FILES) && defined(__MINGW32__)
|
||||
# ifndef _FILE_OFFSET_BITS
|
||||
# define _FILE_OFFSET_BITS 64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_WIN32_LARGE_FILES
|
||||
#define HAVE__FSEEKI64
|
||||
#endif
|
||||
|
||||
/* Define to the size of `off_t', as computed by sizeof. */
|
||||
#if defined(__MINGW32__) && \
|
||||
defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
|
||||
# define SIZEOF_OFF_T 8
|
||||
#else
|
||||
# define SIZEOF_OFF_T 4
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* DNS RESOLVER SPECIALTY */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Undefine both USE_ARES and USE_THREADS_WIN32 for synchronous DNS.
|
||||
*/
|
||||
|
||||
/* Define to enable c-ares asynchronous DNS lookups. */
|
||||
/* #define USE_ARES 1 */
|
||||
|
||||
/* Default define to enable threaded asynchronous DNS lookups. */
|
||||
#if !defined(USE_SYNC_DNS) && !defined(USE_ARES) && \
|
||||
!defined(USE_THREADS_WIN32)
|
||||
# define USE_THREADS_WIN32 1
|
||||
#endif
|
||||
|
||||
#if defined(USE_ARES) && defined(USE_THREADS_WIN32)
|
||||
# error "Only one DNS lookup specialty may be defined at most"
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* LDAP SUPPORT */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#if defined(CURL_HAS_NOVELL_LDAPSDK)
|
||||
#undef USE_WIN32_LDAP
|
||||
#define HAVE_LDAP_SSL_H 1
|
||||
#define HAVE_LDAP_URL_PARSE 1
|
||||
#elif defined(CURL_HAS_OPENLDAP_LDAPSDK)
|
||||
#undef USE_WIN32_LDAP
|
||||
#define HAVE_LDAP_URL_PARSE 1
|
||||
#else
|
||||
#undef HAVE_LDAP_URL_PARSE
|
||||
#define HAVE_LDAP_SSL 1
|
||||
#define USE_WIN32_LDAP 1
|
||||
#endif
|
||||
|
||||
/* Define to use the Windows crypto library. */
|
||||
#if !defined(CURL_WINDOWS_APP)
|
||||
#define USE_WIN32_CRYPTO
|
||||
#endif
|
||||
|
||||
/* Define to use Unix sockets. */
|
||||
#define USE_UNIX_SOCKETS
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* ADDITIONAL DEFINITIONS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define cpu-machine-OS */
|
||||
#ifndef OS
|
||||
#if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */
|
||||
#define OS "i386-pc-win32"
|
||||
#elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */
|
||||
#define OS "x86_64-pc-win32"
|
||||
#elif defined(_M_IA64) || defined(__ia64__) /* Itanium */
|
||||
#define OS "ia64-pc-win32"
|
||||
#elif defined(_M_ARM_NT) || defined(__arm__) /* ARMv7-Thumb2 (Windows RT) */
|
||||
#define OS "thumbv7a-pc-win32"
|
||||
#elif defined(_M_ARM64) || defined(__aarch64__) /* ARM64 (Windows 10) */
|
||||
#define OS "aarch64-pc-win32"
|
||||
#else
|
||||
#define OS "unknown-pc-win32"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "curl"
|
||||
|
||||
/* If you want to build curl with the built-in manual */
|
||||
#define USE_MANUAL 1
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_WIN32_H */
|
303
third_party/curl/lib/config-win32ce.h
vendored
Normal file
303
third_party/curl/lib/config-win32ce.h
vendored
Normal file
@ -0,0 +1,303 @@
|
||||
#ifndef HEADER_CURL_CONFIG_WIN32CE_H
|
||||
#define HEADER_CURL_CONFIG_WIN32CE_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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* ================================================================ */
|
||||
/* lib/config-win32ce.h - Hand crafted config file for windows ce */
|
||||
/* ================================================================ */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* HEADER FILES */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the <arpa/inet.h> header file. */
|
||||
/* #define HAVE_ARPA_INET_H 1 */
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define if you have the <io.h> header file. */
|
||||
#define HAVE_IO_H 1
|
||||
|
||||
/* Define if you need the malloc.h header file even with stdlib.h */
|
||||
#define NEED_MALLOC_H 1
|
||||
|
||||
/* Define if you have the <netdb.h> header file. */
|
||||
/* #define HAVE_NETDB_H 1 */
|
||||
|
||||
/* Define if you have the <netinet/in.h> header file. */
|
||||
/* #define HAVE_NETINET_IN_H 1 */
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
/* #define HAVE_SYS_PARAM_H 1 */
|
||||
|
||||
/* Define if you have the <sys/select.h> header file. */
|
||||
/* #define HAVE_SYS_SELECT_H 1 */
|
||||
|
||||
/* Define if you have the <sys/socket.h> header file. */
|
||||
/* #define HAVE_SYS_SOCKET_H 1 */
|
||||
|
||||
/* Define if you have the <sys/sockio.h> header file. */
|
||||
/* #define HAVE_SYS_SOCKIO_H 1 */
|
||||
|
||||
/* Define if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define if you have the <sys/time.h> header file */
|
||||
/* #define HAVE_SYS_TIME_H 1 */
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
/* #define HAVE_SYS_TYPES_H 1 */
|
||||
|
||||
/* Define if you have the <sys/utime.h> header file */
|
||||
#define HAVE_SYS_UTIME_H 1
|
||||
|
||||
/* Define if you have the <termio.h> header file. */
|
||||
/* #define HAVE_TERMIO_H 1 */
|
||||
|
||||
/* Define if you have the <termios.h> header file. */
|
||||
/* #define HAVE_TERMIOS_H 1 */
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* OTHER HEADER INFO */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* FUNCTIONS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the closesocket function. */
|
||||
#define HAVE_CLOSESOCKET 1
|
||||
|
||||
/* Define if you have the gethostname function. */
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
|
||||
/* Define if you have the gettimeofday function. */
|
||||
/* #define HAVE_GETTIMEOFDAY 1 */
|
||||
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
#define HAVE_IOCTLSOCKET 1
|
||||
|
||||
/* Define if you have a working ioctlsocket FIONBIO function. */
|
||||
#define HAVE_IOCTLSOCKET_FIONBIO 1
|
||||
|
||||
/* Define if you have the select function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define if you have the socket function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
/* #define HAVE_STRCASECMP 1 */
|
||||
|
||||
/* Define if you have the strdup function. */
|
||||
/* #define HAVE_STRDUP 1 */
|
||||
|
||||
/* Define if you have the stricmp function. */
|
||||
/* #define HAVE_STRICMP 1 */
|
||||
|
||||
/* Define if you have the strtoll function. */
|
||||
#if defined(__MINGW32__)
|
||||
#define HAVE_STRTOLL 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the utime function */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define if you have the recv function. */
|
||||
#define HAVE_RECV 1
|
||||
|
||||
/* Define to the type of arg 1 for recv. */
|
||||
#define RECV_TYPE_ARG1 SOCKET
|
||||
|
||||
/* Define to the type of arg 2 for recv. */
|
||||
#define RECV_TYPE_ARG2 char *
|
||||
|
||||
/* Define to the type of arg 3 for recv. */
|
||||
#define RECV_TYPE_ARG3 int
|
||||
|
||||
/* Define to the type of arg 4 for recv. */
|
||||
#define RECV_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for recv. */
|
||||
#define RECV_TYPE_RETV int
|
||||
|
||||
/* Define if you have the send function. */
|
||||
#define HAVE_SEND 1
|
||||
|
||||
/* Define to the type of arg 1 for send. */
|
||||
#define SEND_TYPE_ARG1 SOCKET
|
||||
|
||||
/* Define to the type qualifier of arg 2 for send. */
|
||||
#define SEND_QUAL_ARG2 const
|
||||
|
||||
/* Define to the type of arg 2 for send. */
|
||||
#define SEND_TYPE_ARG2 char *
|
||||
|
||||
/* Define to the type of arg 3 for send. */
|
||||
#define SEND_TYPE_ARG3 int
|
||||
|
||||
/* Define to the type of arg 4 for send. */
|
||||
#define SEND_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for send. */
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* TYPEDEF REPLACEMENTS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define this if in_addr_t is not an available 'typedefed' type */
|
||||
#define in_addr_t unsigned long
|
||||
|
||||
/* Define ssize_t if it is not an available 'typedefed' type */
|
||||
#if defined(_WIN64)
|
||||
#define ssize_t __int64
|
||||
#else
|
||||
#define ssize_t int
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* TYPE SIZES */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
/* #define SIZEOF_LONG_LONG 8 */
|
||||
|
||||
/* Define to the size of `long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG 4
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#if defined(_WIN64)
|
||||
# define SIZEOF_SIZE_T 8
|
||||
#else
|
||||
# define SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* STRUCT RELATED */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define this if you have struct sockaddr_storage */
|
||||
/* #define HAVE_STRUCT_SOCKADDR_STORAGE 1 */
|
||||
|
||||
/* Define this if you have struct timeval */
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
/* Define this if struct sockaddr_in6 has the sin6_scope_id member */
|
||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* COMPILER SPECIFIC */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Undef keyword 'const' if it does not work. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to avoid VS2005 complaining about portable C functions */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
||||
/* VS2005 and later default size for time_t is 64-bit, unless */
|
||||
/* _USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
# ifndef _USE_32BIT_TIME_T
|
||||
# define SIZEOF_TIME_T 8
|
||||
# else
|
||||
# define SIZEOF_TIME_T 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* LARGE FILE SUPPORT */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_WIN32_WCE)
|
||||
# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
|
||||
# define USE_WIN32_LARGE_FILES
|
||||
# else
|
||||
# define USE_WIN32_SMALL_FILES
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(USE_WIN32_LARGE_FILES) && !defined(USE_WIN32_SMALL_FILES)
|
||||
# define USE_WIN32_SMALL_FILES
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* LDAP SUPPORT */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#define USE_WIN32_LDAP 1
|
||||
#undef HAVE_LDAP_URL_PARSE
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* ADDITIONAL DEFINITIONS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define cpu-machine-OS */
|
||||
#ifndef OS
|
||||
#define OS "i386-pc-win32ce"
|
||||
#endif
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "curl"
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* WinCE */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#ifndef UNICODE
|
||||
# define UNICODE
|
||||
#endif
|
||||
|
||||
#ifndef _UNICODE
|
||||
# define _UNICODE
|
||||
#endif
|
||||
|
||||
#define CURL_DISABLE_FILE 1
|
||||
#define CURL_DISABLE_TELNET 1
|
||||
#define CURL_DISABLE_LDAP 1
|
||||
|
||||
#define ENOSPC 1
|
||||
#define ENOMEM 2
|
||||
#define EAGAIN 3
|
||||
|
||||
extern int stat(const char *path, struct stat *buffer);
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_WIN32CE_H */
|
581
third_party/curl/lib/conncache.c
vendored
Normal file
581
third_party/curl/lib/conncache.c
vendored
Normal file
@ -0,0 +1,581 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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_append(&bundle->conn_list, 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, size_t 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 */
|
||||
connc->closure_handle->state.internal = true;
|
||||
|
||||
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->primary.remote_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 USE_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 %" CURL_FORMAT_CURL_OFF_T ". "
|
||||
"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)
|
||||
{
|
||||
unsigned int maxconnects = !data->multi->maxconnects ?
|
||||
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 && 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) {
|
||||
/* Use the closure handle for this disconnect so that anything that
|
||||
happens during the disconnect is not stored and associated with the
|
||||
'data' handle which already just finished a transfer and it is
|
||||
important that details from this (unrelated) disconnect does not
|
||||
taint meta-data in the data handle. */
|
||||
struct conncache *connc = data->state.conn_cache;
|
||||
Curl_disconnect(connc->closure_handle, 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;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
if(!connc->closure_handle)
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
122
third_party/curl/lib/conncache.h
vendored
Normal file
122
third_party/curl/lib/conncache.h
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
#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;
|
||||
curl_off_t next_connection_id;
|
||||
curl_off_t next_easy_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 *, size_t 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 */
|
1446
third_party/curl/lib/connect.c
vendored
Normal file
1446
third_party/curl/lib/connect.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
133
third_party/curl/lib/connect.h
vendored
Normal file
133
third_party/curl/lib/connect.h
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
#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;
|
||||
struct ip_quadruple;
|
||||
|
||||
/* 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,
|
||||
struct ip_quadruple *ip);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
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 */
|
1079
third_party/curl/lib/content_encoding.c
vendored
Normal file
1079
third_party/curl/lib/content_encoding.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
34
third_party/curl/lib/content_encoding.h
vendored
Normal file
34
third_party/curl/lib/content_encoding.h
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
#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 Curl_cwriter;
|
||||
|
||||
void Curl_all_content_encodings(char *buf, size_t blen);
|
||||
|
||||
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
|
||||
const char *enclist, int is_transfer);
|
||||
#endif /* HEADER_CURL_CONTENT_ENCODING_H */
|
1771
third_party/curl/lib/cookie.c
vendored
Normal file
1771
third_party/curl/lib/cookie.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
138
third_party/curl/lib/cookie.h
vendored
Normal file
138
third_party/curl/lib/cookie.h
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
#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> */
|
||||
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 63
|
||||
|
||||
struct CookieInfo {
|
||||
/* linked list of cookies we know of */
|
||||
struct Cookie *cookies[COOKIE_HASH_SIZE];
|
||||
curl_off_t next_expiration; /* the next time at which expiration happens */
|
||||
int numcookies; /* number of cookies in the "jar" */
|
||||
int lastct; /* last creation-time used in the jar */
|
||||
bool running; /* state info, for cookie adding information */
|
||||
bool newsession; /* new session, discard session cookies on load */
|
||||
};
|
||||
|
||||
/* The maximum sizes we accept for cookies. RFC 6265 section 6.1 says
|
||||
"general-use user agents SHOULD provide each of the following minimum
|
||||
capabilities":
|
||||
|
||||
- At least 4096 bytes per cookie (as measured by the sum of the length of
|
||||
the cookie's name, value, and attributes).
|
||||
In the 6265bis draft document section 5.4 it is phrased even stronger: "If
|
||||
the sum of the lengths of the name string and the value string is more than
|
||||
4096 octets, abort these steps and ignore the set-cookie-string entirely."
|
||||
*/
|
||||
|
||||
/** Limits for INCOMING cookies **/
|
||||
|
||||
/* The longest we allow a line to be when reading a cookie from a HTTP header
|
||||
or from a cookie jar */
|
||||
#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
|
||||
|
||||
/* 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
|
||||
|
||||
/** Limits for OUTGOING cookies **/
|
||||
|
||||
/* 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
|
||||
|
||||
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, const 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 */
|
592
third_party/curl/lib/curl_addrinfo.c
vendored
Normal file
592
third_party/curl/lib/curl_addrinfo.c
vendored
Normal file
@ -0,0 +1,592 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 USE_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 USE_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-terminator */
|
||||
#ifdef USE_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 USE_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 USE_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 USE_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 USE_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 USE_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 USE_IPV6
|
||||
case AF_INET6:
|
||||
addr6 = (void *)ca->ai_addr; /* storage area for this info */
|
||||
addr6->sin6_port = htons((unsigned short)port);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
108
third_party/curl/lib/curl_addrinfo.h
vendored
Normal file
108
third_party/curl/lib/curl_addrinfo.h
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
#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 */
|
41
third_party/curl/lib/curl_base64.h
vendored
Normal file
41
third_party/curl/lib/curl_base64.h
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
#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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BUILDING_LIBCURL
|
||||
/* this renames functions so that the tool code can use the same code
|
||||
without getting symbol collisions */
|
||||
#define Curl_base64_encode(a,b,c,d) curlx_base64_encode(a,b,c,d)
|
||||
#define Curl_base64url_encode(a,b,c,d) curlx_base64url_encode(a,b,c,d)
|
||||
#define Curl_base64_decode(a,b,c) curlx_base64_decode(a,b,c)
|
||||
#endif
|
||||
|
||||
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 */
|
810
third_party/curl/lib/curl_config.h.cmake
vendored
Normal file
810
third_party/curl/lib/curl_config.h.cmake
vendored
Normal file
@ -0,0 +1,810 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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. */
|
||||
|
||||
/* Location of default ca bundle */
|
||||
#cmakedefine CURL_CA_BUNDLE "${CURL_CA_BUNDLE}"
|
||||
|
||||
/* define "1" to use built-in ca store of TLS backend */
|
||||
#cmakedefine CURL_CA_FALLBACK 1
|
||||
|
||||
/* Location of default ca path */
|
||||
#cmakedefine CURL_CA_PATH "${CURL_CA_PATH}"
|
||||
|
||||
/* Default SSL backend */
|
||||
#cmakedefine CURL_DEFAULT_SSL_BACKEND "${CURL_DEFAULT_SSL_BACKEND}"
|
||||
|
||||
/* disables alt-svc */
|
||||
#cmakedefine CURL_DISABLE_ALTSVC 1
|
||||
|
||||
/* disables cookies support */
|
||||
#cmakedefine CURL_DISABLE_COOKIES 1
|
||||
|
||||
/* disables Basic authentication */
|
||||
#cmakedefine CURL_DISABLE_BASIC_AUTH 1
|
||||
|
||||
/* disables Bearer authentication */
|
||||
#cmakedefine CURL_DISABLE_BEARER_AUTH 1
|
||||
|
||||
/* disables Digest authentication */
|
||||
#cmakedefine CURL_DISABLE_DIGEST_AUTH 1
|
||||
|
||||
/* disables Kerberos authentication */
|
||||
#cmakedefine CURL_DISABLE_KERBEROS_AUTH 1
|
||||
|
||||
/* disables negotiate authentication */
|
||||
#cmakedefine CURL_DISABLE_NEGOTIATE_AUTH 1
|
||||
|
||||
/* disables AWS-SIG4 */
|
||||
#cmakedefine CURL_DISABLE_AWS 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 form api */
|
||||
#cmakedefine CURL_DISABLE_FORM_API 1
|
||||
|
||||
/* disables FTP */
|
||||
#cmakedefine CURL_DISABLE_FTP 1
|
||||
|
||||
/* disables curl_easy_options API for existing options to curl_easy_setopt */
|
||||
#cmakedefine CURL_DISABLE_GETOPTIONS 1
|
||||
|
||||
/* disables GOPHER */
|
||||
#cmakedefine CURL_DISABLE_GOPHER 1
|
||||
|
||||
/* disables headers-api support */
|
||||
#cmakedefine CURL_DISABLE_HEADERS_API 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 local binding support */
|
||||
#cmakedefine CURL_DISABLE_BINDLOCAL 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
|
||||
|
||||
/* Define if you want to enable IPv6 support */
|
||||
#cmakedefine USE_IPV6 1
|
||||
|
||||
/* Define to 1 if you have the alarm function. */
|
||||
#cmakedefine HAVE_ALARM 1
|
||||
|
||||
/* Define to 1 if you have the arc4random function. */
|
||||
#cmakedefine HAVE_ARC4RANDOM 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 _Atomic support. */
|
||||
#cmakedefine HAVE_ATOMIC 1
|
||||
|
||||
/* Define to 1 if you have the `fnmatch' function. */
|
||||
#cmakedefine HAVE_FNMATCH 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 clock_gettime function and raw monotonic timer.
|
||||
*/
|
||||
#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC_RAW 1
|
||||
|
||||
/* Define to 1 if you have the `closesocket' function. */
|
||||
#cmakedefine HAVE_CLOSESOCKET 1
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file. */
|
||||
#cmakedefine HAVE_DIRENT_H 1
|
||||
|
||||
/* Define to 1 if you have the `opendir' function. */
|
||||
#cmakedefine HAVE_OPENDIR 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 fseeko function. */
|
||||
#cmakedefine HAVE_FSEEKO 1
|
||||
|
||||
/* Define to 1 if you have the fseeko declaration. */
|
||||
#cmakedefine HAVE_DECL_FSEEKO 1
|
||||
|
||||
/* Define to 1 if you have the _fseeki64 function. */
|
||||
#cmakedefine HAVE__FSEEKI64 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 `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
|
||||
|
||||
/* 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 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 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 'suseconds_t' data type. */
|
||||
#cmakedefine HAVE_SUSECONDS_T 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 <netinet/udp.h> header file. */
|
||||
#cmakedefine HAVE_NETINET_UDP_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 OpenSSL has the `SSL_set0_wbio` function. */
|
||||
#cmakedefine HAVE_SSL_SET0_WBIO 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 sched_yield function. */
|
||||
#cmakedefine HAVE_SCHED_YIELD 1
|
||||
|
||||
/* Define to 1 if you have the send function. */
|
||||
#cmakedefine HAVE_SEND 1
|
||||
|
||||
/* Define to 1 if you have the sendmsg function. */
|
||||
#cmakedefine HAVE_SENDMSG 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 `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 sigsetjmp function or macro. */
|
||||
#cmakedefine HAVE_SIGSETJMP 1
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#cmakedefine HAVE_SNPRINTF 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 <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 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 <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
|
||||
|
||||
/* Define to 1 if you have the memrchr function. */
|
||||
#cmakedefine HAVE_MEMRCHR 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/wait.h> header file. */
|
||||
#cmakedefine HAVE_SYS_WAIT_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 <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 this symbol if your OS supports changing the contents of argv */
|
||||
#cmakedefine HAVE_WRITABLE_ARGV 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 `long', as computed by sizeof. */
|
||||
${SIZEOF_LONG_CODE}
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
${SIZEOF_LONG_LONG_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 `curl_socket_t', as computed by sizeof. */
|
||||
${SIZEOF_CURL_SOCKET_T_CODE}
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
${SIZEOF_SIZE_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 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 use OpenLDAP code instead of legacy ldap implementation */
|
||||
#cmakedefine USE_OPENLDAP 1
|
||||
|
||||
/* if OpenSSL is in use */
|
||||
#cmakedefine USE_OPENSSL 1
|
||||
|
||||
/* if librtmp/rtmpdump is in use */
|
||||
#cmakedefine USE_LIBRTMP 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
|
||||
|
||||
/* to enable openssl + nghttp3 */
|
||||
#cmakedefine USE_OPENSSL_QUIC 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 1
|
||||
|
||||
/* Define to 1 if you are building a Windows target with large file support. */
|
||||
#cmakedefine USE_WIN32_LARGE_FILES 1
|
||||
|
||||
/* 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 `unsigned int' if <sys/types.h> does not define. */
|
||||
#cmakedefine size_t ${size_t}
|
||||
|
||||
/* the signed version of size_t */
|
||||
#cmakedefine ssize_t ${ssize_t}
|
||||
|
||||
/* 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
|
||||
|
||||
/* to enable Apple IDN */
|
||||
#cmakedefine USE_APPLE_IDN 1
|
||||
|
||||
/* Define to 1 to enable websocket support. */
|
||||
#cmakedefine USE_WEBSOCKETS 1
|
||||
|
||||
/* Define to 1 if OpenSSL has the SSL_CTX_set_srp_username function. */
|
||||
#cmakedefine HAVE_OPENSSL_SRP 1
|
||||
|
||||
/* Define to 1 if GnuTLS has the gnutls_srp_verifier function. */
|
||||
#cmakedefine HAVE_GNUTLS_SRP 1
|
||||
|
||||
/* Define to 1 to enable TLS-SRP support. */
|
||||
#cmakedefine USE_TLS_SRP 1
|
||||
|
||||
/* Define to 1 to query for HTTPSRR when using DoH */
|
||||
#cmakedefine USE_HTTPSRR 1
|
||||
|
||||
/* if ECH support is available */
|
||||
#cmakedefine USE_ECH 1
|
1001
third_party/curl/lib/curl_config.h.in
vendored
Normal file
1001
third_party/curl/lib/curl_config.h.in
vendored
Normal file
File diff suppressed because it is too large
Load Diff
51
third_party/curl/lib/curl_ctype.h
vendored
Normal file
51
third_party/curl/lib/curl_ctype.h
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
#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)))
|
||||
#define ISURLPUNTCS(x) (((x) == '-') || ((x) == '.') || ((x) == '_') || \
|
||||
((x) == '~'))
|
||||
#define ISUNRESERVED(x) (ISALNUM(x) || ISURLPUNTCS(x))
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_CTYPE_H */
|
69
third_party/curl/lib/curl_des.c
vendored
Normal file
69
third_party/curl/lib/curl_des.c
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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_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 engine doesn't have its 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
|
40
third_party/curl/lib/curl_des.h
vendored
Normal file
40
third_party/curl/lib/curl_des.h
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
#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_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 */
|
84
third_party/curl/lib/curl_endian.c
vendored
Normal file
84
third_party/curl/lib/curl_endian.c
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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]));
|
||||
}
|
36
third_party/curl/lib/curl_endian.h
vendored
Normal file
36
third_party/curl/lib/curl_endian.h
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
#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 */
|
390
third_party/curl/lib/curl_fnmatch.c
vendored
Normal file
390
third_party/curl/lib/curl_fnmatch.c
vendored
Normal file
@ -0,0 +1,390 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 */
|
46
third_party/curl/lib/curl_fnmatch.h
vendored
Normal file
46
third_party/curl/lib/curl_fnmatch.h
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
#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 */
|
77
third_party/curl/lib/curl_get_line.c
vendored
Normal file
77
third_party/curl/lib/curl_get_line.c
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 end
|
||||
* newlines.
|
||||
*/
|
||||
int Curl_get_line(struct dynbuf *buf, FILE *input)
|
||||
{
|
||||
CURLcode result;
|
||||
char buffer[128];
|
||||
Curl_dyn_reset(buf);
|
||||
while(1) {
|
||||
char *b = fgets(buffer, sizeof(buffer), input);
|
||||
|
||||
if(b) {
|
||||
size_t rlen = strlen(b);
|
||||
|
||||
if(!rlen)
|
||||
break;
|
||||
|
||||
result = Curl_dyn_addn(buf, b, rlen);
|
||||
if(result)
|
||||
/* too long line or out of memory */
|
||||
return 0; /* error */
|
||||
|
||||
else if(b[rlen-1] == '\n')
|
||||
/* end of the line */
|
||||
return 1; /* all good */
|
||||
|
||||
else if(feof(input)) {
|
||||
/* append a newline */
|
||||
result = Curl_dyn_addn(buf, "\n", 1);
|
||||
if(result)
|
||||
/* too long line or out of memory */
|
||||
return 0; /* error */
|
||||
return 1; /* all good */
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* if not disabled */
|
32
third_party/curl/lib/curl_get_line.h
vendored
Normal file
32
third_party/curl/lib/curl_get_line.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "dynbuf.h"
|
||||
|
||||
/* Curl_get_line() returns complete lines that end with a newline. */
|
||||
int Curl_get_line(struct dynbuf *buf, FILE *input);
|
||||
|
||||
#endif /* HEADER_CURL_GET_LINE_H */
|
102
third_party/curl/lib/curl_gethostname.c
vendored
Normal file
102
third_party/curl/lib/curl_gethostname.c
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 - 1);
|
||||
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
|
||||
|
||||
}
|
33
third_party/curl/lib/curl_gethostname.h
vendored
Normal file
33
third_party/curl/lib/curl_gethostname.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
#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 */
|
152
third_party/curl/lib/curl_gssapi.c
vendored
Normal file
152
third_party/curl/lib/curl_gssapi.c
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 */
|
63
third_party/curl/lib/curl_gssapi.h
vendored
Normal file
63
third_party/curl/lib/curl_gssapi.h
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
#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 */
|
78
third_party/curl/lib/curl_hmac.h
vendored
Normal file
78
third_party/curl/lib/curl_hmac.h
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
#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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \
|
||||
|| !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) \
|
||||
|| defined(USE_LIBSSH2)
|
||||
|
||||
#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 */
|
52
third_party/curl/lib/curl_krb5.h
vendored
Normal file
52
third_party/curl/lib/curl_krb5.h
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
#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 */
|
36
third_party/curl/lib/curl_ldap.h
vendored
Normal file
36
third_party/curl/lib/curl_ldap.h
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
#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 */
|
39
third_party/curl/lib/curl_md4.h
vendored
Normal file
39
third_party/curl/lib/curl_md4.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
#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"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if defined(USE_CURL_NTLM_CORE)
|
||||
|
||||
#define MD4_DIGEST_LENGTH 16
|
||||
|
||||
CURLcode Curl_md4it(unsigned char *output, const unsigned char *input,
|
||||
const size_t len);
|
||||
|
||||
#endif /* defined(USE_CURL_NTLM_CORE) */
|
||||
|
||||
#endif /* HEADER_CURL_MD4_H */
|
67
third_party/curl/lib/curl_md5.h
vendored
Normal file
67
third_party/curl/lib/curl_md5.h
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
#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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \
|
||||
|| !defined(CURL_DISABLE_DIGEST_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 */
|
178
third_party/curl/lib/curl_memory.h
vendored
Normal file
178
third_party/curl/lib/curl_memory.h
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
#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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HEADER_CURL_MEMDEBUG_H
|
||||
/* cleanup after memdebug.h */
|
||||
|
||||
#ifdef MEMDEBUG_NODEFINES
|
||||
#ifdef CURLDEBUG
|
||||
|
||||
#undef strdup
|
||||
#undef malloc
|
||||
#undef calloc
|
||||
#undef realloc
|
||||
#undef free
|
||||
#undef send
|
||||
#undef recv
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef UNICODE
|
||||
# undef wcsdup
|
||||
# undef _wcsdup
|
||||
# undef _tcsdup
|
||||
# else
|
||||
# undef _tcsdup
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef socket
|
||||
#undef accept
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
#undef socketpair
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#if defined(getaddrinfo) && defined(__osf__)
|
||||
#undef ogetaddrinfo
|
||||
#else
|
||||
#undef getaddrinfo
|
||||
#endif
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
#ifdef HAVE_FREEADDRINFO
|
||||
#undef freeaddrinfo
|
||||
#endif /* HAVE_FREEADDRINFO */
|
||||
|
||||
/* sclose is probably already defined, redefine it! */
|
||||
#undef sclose
|
||||
#undef fopen
|
||||
#undef fdopen
|
||||
#undef fclose
|
||||
|
||||
#endif /* MEMDEBUG_NODEFINES */
|
||||
#endif /* CURLDEBUG */
|
||||
|
||||
#undef HEADER_CURL_MEMDEBUG_H
|
||||
#endif /* HEADER_CURL_MEMDEBUG_H */
|
||||
|
||||
/*
|
||||
** Following section applies even when CURLDEBUG is not defined.
|
||||
*/
|
||||
|
||||
#undef fake_sclose
|
||||
|
||||
#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 */
|
||||
#endif /* HEADER_CURL_MEMORY_H */
|
64
third_party/curl/lib/curl_memrchr.c
vendored
Normal file
64
third_party/curl/lib/curl_memrchr.c
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 */
|
44
third_party/curl/lib/curl_memrchr.h
vendored
Normal file
44
third_party/curl/lib/curl_memrchr.h
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
#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
|
||||
|
||||
#include <string.h>
|
||||
#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 */
|
162
third_party/curl/lib/curl_multibyte.c
vendored
Normal file
162
third_party/curl/lib/curl_multibyte.c
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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
|
||||
}
|
||||
|
||||
#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
|
91
third_party/curl/lib/curl_multibyte.h
vendored
Normal file
91
third_party/curl/lib/curl_multibyte.h
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
#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 */
|
669
third_party/curl/lib/curl_ntlm_core.c
vendored
Normal file
669
third_party/curl/lib/curl_ntlm_core.c
vendored
Normal file
@ -0,0 +1,669 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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. -
|
||||
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 has 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
|
||||
# elif defined(OPENSSL_IS_AWSLC)
|
||||
# define DES_set_key_unchecked (void)DES_set_key
|
||||
# define DESKEYARG(x) *x
|
||||
# define DESKEY(x) &x
|
||||
# else
|
||||
# define DESKEYARG(x) *x
|
||||
# define DESKEY(x) &x
|
||||
# endif
|
||||
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
# include <nettle/des.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."
|
||||
# define CURL_NTLM_NOT_SUPPORTED
|
||||
#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)
|
||||
|
||||
#if !defined(CURL_NTLM_NOT_SUPPORTED)
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
#endif
|
||||
|
||||
#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_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_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);
|
||||
#else
|
||||
(void)keys;
|
||||
(void)plaintext;
|
||||
(void)results;
|
||||
#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];
|
||||
#if !defined(CURL_NTLM_NOT_SUPPORTED)
|
||||
static const unsigned char magic[] = {
|
||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
||||
};
|
||||
#endif
|
||||
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_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;
|
||||
CURLcode result;
|
||||
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. */
|
||||
result = Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
if(!result)
|
||||
memset(ntbuffer + 16, 0, 21 - 16);
|
||||
|
||||
free(pw);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#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 */
|
79
third_party/curl/lib/curl_ntlm_core.h
vendored
Normal file
79
third_party/curl/lib/curl_ntlm_core.h
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
#ifndef HEADER_CURL_NTLM_CORE_H
|
||||
#define HEADER_CURL_NTLM_CORE_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(USE_CURL_NTLM_CORE)
|
||||
|
||||
#if defined(USE_OPENSSL)
|
||||
# include <openssl/ssl.h>
|
||||
#elif defined(USE_WOLFSSL)
|
||||
# include <wolfssl/options.h>
|
||||
# include <wolfssl/openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
/* Helpers to generate function byte arguments in little endian order */
|
||||
#define SHORTPAIR(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff))
|
||||
#define LONGQUARTET(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)), \
|
||||
((int)(((x) >> 16) & 0xff)), ((int)(((x) >> 24) & 0xff))
|
||||
|
||||
void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */);
|
||||
|
||||
#if !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
unsigned char *output);
|
||||
|
||||
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);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
unsigned char *challenge_client,
|
||||
struct ntlmdata *ntlm,
|
||||
unsigned char **ntresp,
|
||||
unsigned int *ntresp_len);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
||||
unsigned char *challenge_client,
|
||||
unsigned char *challenge_server,
|
||||
unsigned char *lmresp);
|
||||
|
||||
#endif /* !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* USE_CURL_NTLM_CORE */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_CORE_H */
|
203
third_party/curl/lib/curl_path.c
vendored
Normal file
203
third_party/curl/lib/curl_path.c
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 AND ISC
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_SSH)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_memory.h"
|
||||
#include "curl_path.h"
|
||||
#include "escape.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAX_SSHPATH_LEN 100000 /* arbitrary */
|
||||
|
||||
/* figure out the path to work with in this particular request */
|
||||
CURLcode Curl_getworkingpath(struct Curl_easy *data,
|
||||
char *homedir, /* when SFTP is used */
|
||||
char **path) /* returns the allocated
|
||||
real path to work with */
|
||||
{
|
||||
char *working_path;
|
||||
size_t working_path_len;
|
||||
struct dynbuf npath;
|
||||
CURLcode result =
|
||||
Curl_urldecode(data->state.up.path, 0, &working_path,
|
||||
&working_path_len, REJECT_ZERO);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* new path to switch to in case we need to */
|
||||
Curl_dyn_init(&npath, MAX_SSHPATH_LEN);
|
||||
|
||||
/* Check for /~/, indicating relative to the user's home directory */
|
||||
if((data->conn->handler->protocol & CURLPROTO_SCP) &&
|
||||
(working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) {
|
||||
/* It is referenced to the home directory, so strip the leading '/~/' */
|
||||
if(Curl_dyn_addn(&npath, &working_path[3], working_path_len - 3)) {
|
||||
free(working_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else if((data->conn->handler->protocol & CURLPROTO_SFTP) &&
|
||||
(!strcmp("/~", working_path) ||
|
||||
((working_path_len > 2) && !memcmp(working_path, "/~/", 3)))) {
|
||||
if(Curl_dyn_add(&npath, homedir)) {
|
||||
free(working_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(working_path_len > 2) {
|
||||
size_t len;
|
||||
const char *p;
|
||||
int copyfrom = 3;
|
||||
/* Copy a separating '/' if homedir does not end with one */
|
||||
len = Curl_dyn_len(&npath);
|
||||
p = Curl_dyn_ptr(&npath);
|
||||
if(len && (p[len-1] != '/'))
|
||||
copyfrom = 2;
|
||||
|
||||
if(Curl_dyn_addn(&npath,
|
||||
&working_path[copyfrom], working_path_len - copyfrom)) {
|
||||
free(working_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(Curl_dyn_len(&npath)) {
|
||||
free(working_path);
|
||||
|
||||
/* store the pointer for the caller to receive */
|
||||
*path = Curl_dyn_ptr(&npath);
|
||||
}
|
||||
else
|
||||
*path = working_path;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* The original get_pathname() function came from OpenSSH sftp.c version
|
||||
4.6p1. */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
* 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" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define MAX_PATHLENGTH 65535 /* arbitrary long */
|
||||
|
||||
CURLcode Curl_get_pathname(const char **cpp, char **path, const char *homedir)
|
||||
{
|
||||
const char *cp = *cpp, *end;
|
||||
char quot;
|
||||
unsigned int i;
|
||||
static const char WHITESPACE[] = " \t\r\n";
|
||||
struct dynbuf out;
|
||||
CURLcode result;
|
||||
|
||||
DEBUGASSERT(homedir);
|
||||
*path = NULL;
|
||||
*cpp = NULL;
|
||||
if(!*cp || !homedir)
|
||||
return CURLE_QUOTE_ERROR;
|
||||
|
||||
Curl_dyn_init(&out, MAX_PATHLENGTH);
|
||||
|
||||
/* Ignore leading whitespace */
|
||||
cp += strspn(cp, WHITESPACE);
|
||||
|
||||
/* Check for quoted filenames */
|
||||
if(*cp == '\"' || *cp == '\'') {
|
||||
quot = *cp++;
|
||||
|
||||
/* Search for terminating quote, unescape some chars */
|
||||
for(i = 0; i <= strlen(cp); i++) {
|
||||
if(cp[i] == quot) { /* Found quote */
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
if(cp[i] == '\0') { /* End of string */
|
||||
goto fail;
|
||||
}
|
||||
if(cp[i] == '\\') { /* Escaped characters */
|
||||
i++;
|
||||
if(cp[i] != '\'' && cp[i] != '\"' &&
|
||||
cp[i] != '\\') {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
result = Curl_dyn_addn(&out, &cp[i], 1);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!Curl_dyn_len(&out))
|
||||
goto fail;
|
||||
|
||||
/* return pointer to second parameter if it exists */
|
||||
*cpp = &cp[i] + strspn(&cp[i], WHITESPACE);
|
||||
}
|
||||
else {
|
||||
/* Read to end of filename - either to whitespace or terminator */
|
||||
end = strpbrk(cp, WHITESPACE);
|
||||
if(!end)
|
||||
end = strchr(cp, '\0');
|
||||
|
||||
/* return pointer to second parameter if it exists */
|
||||
*cpp = end + strspn(end, WHITESPACE);
|
||||
|
||||
/* Handling for relative path - prepend home directory */
|
||||
if(cp[0] == '/' && cp[1] == '~' && cp[2] == '/') {
|
||||
result = Curl_dyn_add(&out, homedir);
|
||||
if(!result)
|
||||
result = Curl_dyn_addn(&out, "/", 1);
|
||||
if(result)
|
||||
return result;
|
||||
cp += 3;
|
||||
}
|
||||
/* Copy path name up until first "whitespace" */
|
||||
result = Curl_dyn_addn(&out, cp, (end - cp));
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
*path = Curl_dyn_ptr(&out);
|
||||
return CURLE_OK;
|
||||
|
||||
fail:
|
||||
Curl_dyn_free(&out);
|
||||
return CURLE_QUOTE_ERROR;
|
||||
}
|
||||
|
||||
#endif /* if SSH is used */
|
49
third_party/curl/lib/curl_path.h
vendored
Normal file
49
third_party/curl/lib/curl_path.h
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef HEADER_CURL_PATH_H
|
||||
#define HEADER_CURL_PATH_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>
|
||||
#include "urldata.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# undef PATH_MAX
|
||||
# define PATH_MAX MAX_PATH
|
||||
# ifndef R_OK
|
||||
# define R_OK 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 1024 /* just an extra precaution since there are systems that
|
||||
have their definition hidden well */
|
||||
#endif
|
||||
|
||||
CURLcode Curl_getworkingpath(struct Curl_easy *data,
|
||||
char *homedir,
|
||||
char **path);
|
||||
|
||||
CURLcode Curl_get_pathname(const char **cpp, char **path, const char *homedir);
|
||||
#endif /* HEADER_CURL_PATH_H */
|
55
third_party/curl/lib/curl_printf.h
vendored
Normal file
55
third_party/curl/lib/curl_printf.h
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef HEADER_CURL_PRINTF_H
|
||||
#define HEADER_CURL_PRINTF_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 should be included by ALL code in libcurl that uses any
|
||||
* *rintf() functions.
|
||||
*/
|
||||
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#define MERR_OK 0
|
||||
#define MERR_MEM 1
|
||||
#define MERR_TOO_LARGE 2
|
||||
|
||||
# undef printf
|
||||
# undef fprintf
|
||||
# undef msnprintf
|
||||
# undef vprintf
|
||||
# undef vfprintf
|
||||
# undef vsnprintf
|
||||
# undef mvsnprintf
|
||||
# undef aprintf
|
||||
# undef vaprintf
|
||||
# define printf curl_mprintf
|
||||
# define fprintf curl_mfprintf
|
||||
# define msnprintf curl_msnprintf
|
||||
# define vprintf curl_mvprintf
|
||||
# define vfprintf curl_mvfprintf
|
||||
# define mvsnprintf curl_mvsnprintf
|
||||
# define aprintf curl_maprintf
|
||||
# define vaprintf curl_mvaprintf
|
||||
#endif /* HEADER_CURL_PRINTF_H */
|
96
third_party/curl/lib/curl_range.c
vendored
Normal file
96
third_party/curl/lib/curl_range.c
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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_range.h"
|
||||
#include "sendf.h"
|
||||
#include "strtoofft.h"
|
||||
|
||||
/* Only include this function if one or more of FTP, FILE are enabled. */
|
||||
#if !defined(CURL_DISABLE_FTP) || !defined(CURL_DISABLE_FILE)
|
||||
|
||||
/*
|
||||
Check if this is a range download, and if so, set the internal variables
|
||||
properly.
|
||||
*/
|
||||
CURLcode Curl_range(struct Curl_easy *data)
|
||||
{
|
||||
curl_off_t from, to;
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
|
||||
if(data->state.use_range && data->state.range) {
|
||||
CURLofft from_t;
|
||||
CURLofft to_t;
|
||||
from_t = curlx_strtoofft(data->state.range, &ptr, 10, &from);
|
||||
if(from_t == CURL_OFFT_FLOW)
|
||||
return CURLE_RANGE_ERROR;
|
||||
while(*ptr && (ISBLANK(*ptr) || (*ptr == '-')))
|
||||
ptr++;
|
||||
to_t = curlx_strtoofft(ptr, &ptr2, 10, &to);
|
||||
if(to_t == CURL_OFFT_FLOW)
|
||||
return CURLE_RANGE_ERROR;
|
||||
if((to_t == CURL_OFFT_INVAL) && !from_t) {
|
||||
/* X - */
|
||||
data->state.resume_from = from;
|
||||
DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file",
|
||||
from));
|
||||
}
|
||||
else if((from_t == CURL_OFFT_INVAL) && !to_t) {
|
||||
/* -Y */
|
||||
data->req.maxdownload = to;
|
||||
data->state.resume_from = -to;
|
||||
DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
to));
|
||||
}
|
||||
else {
|
||||
/* X-Y */
|
||||
curl_off_t totalsize;
|
||||
|
||||
/* Ensure the range is sensible - to should follow from. */
|
||||
if(from > to)
|
||||
return CURLE_RANGE_ERROR;
|
||||
|
||||
totalsize = to - from;
|
||||
if(totalsize == CURL_OFF_T_MAX)
|
||||
return CURLE_RANGE_ERROR;
|
||||
|
||||
data->req.maxdownload = totalsize + 1; /* include last byte */
|
||||
data->state.resume_from = from;
|
||||
DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T
|
||||
" getting %" CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
from, data->req.maxdownload));
|
||||
}
|
||||
DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T
|
||||
" to %" CURL_FORMAT_CURL_OFF_T ", totally %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes",
|
||||
from, to, data->req.maxdownload));
|
||||
}
|
||||
else
|
||||
data->req.maxdownload = -1;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif
|
31
third_party/curl/lib/curl_range.h
vendored
Normal file
31
third_party/curl/lib/curl_range.h
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef HEADER_CURL_RANGE_H
|
||||
#define HEADER_CURL_RANGE_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"
|
||||
|
||||
CURLcode Curl_range(struct Curl_easy *data);
|
||||
#endif /* HEADER_CURL_RANGE_H */
|
362
third_party/curl/lib/curl_rtmp.c
vendored
Normal file
362
third_party/curl/lib/curl_rtmp.c
vendored
Normal file
@ -0,0 +1,362 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) Howard Chu, <hyc@highlandsun.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"
|
||||
|
||||
#ifdef USE_LIBRTMP
|
||||
|
||||
#include "curl_rtmp.h"
|
||||
#include "urldata.h"
|
||||
#include "nonblock.h" /* for curlx_nonblock */
|
||||
#include "progress.h" /* for Curl_pgrsSetUploadSize */
|
||||
#include "transfer.h"
|
||||
#include "warnless.h"
|
||||
#include <curl/curl.h>
|
||||
#include <librtmp/rtmp.h>
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(USE_LWIPSOCK)
|
||||
#define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e)
|
||||
#define SET_RCVTIMEO(tv,s) int tv = s*1000
|
||||
#elif defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD)
|
||||
#define SET_RCVTIMEO(tv,s) int tv = s*1000
|
||||
#else
|
||||
#define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0}
|
||||
#endif
|
||||
|
||||
#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */
|
||||
|
||||
static CURLcode rtmp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static CURLcode rtmp_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode rtmp_done(struct Curl_easy *data, CURLcode, bool premature);
|
||||
static CURLcode rtmp_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode rtmp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
|
||||
static Curl_recv rtmp_recv;
|
||||
static Curl_send rtmp_send;
|
||||
|
||||
/*
|
||||
* RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmp = {
|
||||
"rtmp", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
PORT_RTMP, /* defport */
|
||||
CURLPROTO_RTMP, /* protocol */
|
||||
CURLPROTO_RTMP, /* family */
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpt = {
|
||||
"rtmpt", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
PORT_RTMPT, /* defport */
|
||||
CURLPROTO_RTMPT, /* protocol */
|
||||
CURLPROTO_RTMPT, /* family */
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpe = {
|
||||
"rtmpe", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
PORT_RTMP, /* defport */
|
||||
CURLPROTO_RTMPE, /* protocol */
|
||||
CURLPROTO_RTMPE, /* family */
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpte = {
|
||||
"rtmpte", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
PORT_RTMPT, /* defport */
|
||||
CURLPROTO_RTMPTE, /* protocol */
|
||||
CURLPROTO_RTMPTE, /* family */
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmps = {
|
||||
"rtmps", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
PORT_RTMPS, /* defport */
|
||||
CURLPROTO_RTMPS, /* protocol */
|
||||
CURLPROTO_RTMP, /* family */
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpts = {
|
||||
"rtmpts", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* write_resp */
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
PORT_RTMPS, /* defport */
|
||||
CURLPROTO_RTMPTS, /* protocol */
|
||||
CURLPROTO_RTMPT, /* family */
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
static CURLcode rtmp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
RTMP *r = RTMP_Alloc();
|
||||
if(!r)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
RTMP_Init(r);
|
||||
RTMP_SetBufferMS(r, DEF_BUFTIME);
|
||||
if(!RTMP_SetupURL(r, data->state.url)) {
|
||||
RTMP_Free(r);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
conn->proto.rtmp = r;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
SET_RCVTIMEO(tv, 10);
|
||||
|
||||
r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET];
|
||||
|
||||
/* We have to know if it's a write before we send the
|
||||
* connect request packet
|
||||
*/
|
||||
if(data->state.upload)
|
||||
r->Link.protocol |= RTMP_FEATURE_WRITE;
|
||||
|
||||
/* For plain streams, use the buffer toggle trick to keep data flowing */
|
||||
if(!(r->Link.lFlags & RTMP_LF_LIVE) &&
|
||||
!(r->Link.protocol & RTMP_FEATURE_HTTP))
|
||||
r->Link.lFlags |= RTMP_LF_BUFX;
|
||||
|
||||
(void)curlx_nonblock(r->m_sb.sb_socket, FALSE);
|
||||
setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
|
||||
(char *)&tv, sizeof(tv));
|
||||
|
||||
if(!RTMP_Connect1(r, NULL))
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Clients must send a periodic BytesReceived report to the server */
|
||||
r->m_bSendCounter = true;
|
||||
|
||||
*done = TRUE;
|
||||
conn->recv[FIRSTSOCKET] = rtmp_recv;
|
||||
conn->send[FIRSTSOCKET] = rtmp_send;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
|
||||
if(!RTMP_ConnectStream(r, 0))
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
if(data->state.upload) {
|
||||
Curl_pgrsSetUploadSize(data, data->state.infilesize);
|
||||
Curl_xfer_setup(data, -1, -1, FALSE, FIRSTSOCKET);
|
||||
}
|
||||
else
|
||||
Curl_xfer_setup(data, FIRSTSOCKET, -1, FALSE, -1);
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
(void)data; /* unused */
|
||||
(void)status; /* unused */
|
||||
(void)premature; /* unused */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
(void)data;
|
||||
(void)dead_connection;
|
||||
if(r) {
|
||||
conn->proto.rtmp = NULL;
|
||||
RTMP_Close(r);
|
||||
RTMP_Free(r);
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static ssize_t rtmp_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
size_t len, CURLcode *err)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
ssize_t nread;
|
||||
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
nread = RTMP_Read(r, buf, curlx_uztosi(len));
|
||||
if(nread < 0) {
|
||||
if(r->m_read.status == RTMP_READ_COMPLETE ||
|
||||
r->m_read.status == RTMP_READ_EOF) {
|
||||
data->req.size = data->req.bytecount;
|
||||
nread = 0;
|
||||
}
|
||||
else
|
||||
*err = CURLE_RECV_ERROR;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
static ssize_t rtmp_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t len, CURLcode *err)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
ssize_t num;
|
||||
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
num = RTMP_Write(r, (char *)buf, curlx_uztosi(len));
|
||||
if(num < 0)
|
||||
*err = CURLE_SEND_ERROR;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
void Curl_rtmp_version(char *version, size_t len)
|
||||
{
|
||||
char suff[2];
|
||||
if(RTMP_LIB_VERSION & 0xff) {
|
||||
suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1;
|
||||
suff[1] = '\0';
|
||||
}
|
||||
else
|
||||
suff[0] = '\0';
|
||||
|
||||
msnprintf(version, len, "librtmp/%d.%d%s",
|
||||
RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
|
||||
suff);
|
||||
}
|
||||
|
||||
#endif /* USE_LIBRTMP */
|
37
third_party/curl/lib/curl_rtmp.h
vendored
Normal file
37
third_party/curl/lib/curl_rtmp.h
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef HEADER_CURL_RTMP_H
|
||||
#define HEADER_CURL_RTMP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Howard Chu, <hyc@highlandsun.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
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifdef USE_LIBRTMP
|
||||
extern const struct Curl_handler Curl_handler_rtmp;
|
||||
extern const struct Curl_handler Curl_handler_rtmpt;
|
||||
extern const struct Curl_handler Curl_handler_rtmpe;
|
||||
extern const struct Curl_handler Curl_handler_rtmpte;
|
||||
extern const struct Curl_handler Curl_handler_rtmps;
|
||||
extern const struct Curl_handler Curl_handler_rtmpts;
|
||||
|
||||
void Curl_rtmp_version(char *version, size_t len);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_RTMP_H */
|
760
third_party/curl/lib/curl_sasl.c
vendored
Normal file
760
third_party/curl/lib/curl_sasl.c
vendored
Normal file
@ -0,0 +1,760 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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
|
||||
*
|
||||
* RFC2195 CRAM-MD5 authentication
|
||||
* RFC2617 Basic and Digest Access Authentication
|
||||
* RFC2831 DIGEST-MD5 authentication
|
||||
* RFC4422 Simple Authentication and Security Layer (SASL)
|
||||
* RFC4616 PLAIN authentication
|
||||
* RFC5802 SCRAM-SHA-1 authentication
|
||||
* RFC7677 SCRAM-SHA-256 authentication
|
||||
* RFC6749 OAuth 2.0 Authorization Framework
|
||||
* RFC7628 A Set of SASL Mechanisms for OAuth
|
||||
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \
|
||||
!defined(CURL_DISABLE_POP3) || \
|
||||
(!defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP))
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
|
||||
#include "curl_base64.h"
|
||||
#include "curl_md5.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "cfilters.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "curl_hmac.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "warnless.h"
|
||||
#include "strtok.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"
|
||||
|
||||
/* Supported mechanisms */
|
||||
static const struct {
|
||||
const char *name; /* Name */
|
||||
size_t len; /* Name length */
|
||||
unsigned short bit; /* Flag bit */
|
||||
} mechtable[] = {
|
||||
{ "LOGIN", 5, SASL_MECH_LOGIN },
|
||||
{ "PLAIN", 5, SASL_MECH_PLAIN },
|
||||
{ "CRAM-MD5", 8, SASL_MECH_CRAM_MD5 },
|
||||
{ "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 },
|
||||
{ "GSSAPI", 6, SASL_MECH_GSSAPI },
|
||||
{ "EXTERNAL", 8, SASL_MECH_EXTERNAL },
|
||||
{ "NTLM", 4, SASL_MECH_NTLM },
|
||||
{ "XOAUTH2", 7, SASL_MECH_XOAUTH2 },
|
||||
{ "OAUTHBEARER", 11, SASL_MECH_OAUTHBEARER },
|
||||
{ "SCRAM-SHA-1", 11, SASL_MECH_SCRAM_SHA_1 },
|
||||
{ "SCRAM-SHA-256",13, SASL_MECH_SCRAM_SHA_256 },
|
||||
{ ZERO_NULL, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Curl_sasl_cleanup()
|
||||
*
|
||||
* This is used to cleanup any libraries or curl modules used by the sasl
|
||||
* functions.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* conn [in] - The connection data.
|
||||
* authused [in] - The authentication mechanism used.
|
||||
*/
|
||||
void Curl_sasl_cleanup(struct connectdata *conn, unsigned short authused)
|
||||
{
|
||||
(void)conn;
|
||||
(void)authused;
|
||||
|
||||
#if defined(USE_KERBEROS5)
|
||||
/* Cleanup the gssapi structure */
|
||||
if(authused == SASL_MECH_GSSAPI) {
|
||||
Curl_auth_cleanup_gssapi(&conn->krb5);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_GSASL)
|
||||
/* Cleanup the GSASL structure */
|
||||
if(authused & (SASL_MECH_SCRAM_SHA_1 | SASL_MECH_SCRAM_SHA_256)) {
|
||||
Curl_auth_gsasl_cleanup(&conn->gsasl);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_NTLM)
|
||||
/* Cleanup the NTLM structure */
|
||||
if(authused == SASL_MECH_NTLM) {
|
||||
Curl_auth_cleanup_ntlm(&conn->ntlm);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_decode_mech()
|
||||
*
|
||||
* Convert a SASL mechanism name into a token.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* ptr [in] - The mechanism string.
|
||||
* maxlen [in] - Maximum mechanism string length.
|
||||
* len [out] - If not NULL, effective name length.
|
||||
*
|
||||
* Returns the SASL mechanism token or 0 if no match.
|
||||
*/
|
||||
unsigned short Curl_sasl_decode_mech(const char *ptr, size_t maxlen,
|
||||
size_t *len)
|
||||
{
|
||||
unsigned int i;
|
||||
char c;
|
||||
|
||||
for(i = 0; mechtable[i].name; i++) {
|
||||
if(maxlen >= mechtable[i].len &&
|
||||
!memcmp(ptr, mechtable[i].name, mechtable[i].len)) {
|
||||
if(len)
|
||||
*len = mechtable[i].len;
|
||||
|
||||
if(maxlen == mechtable[i].len)
|
||||
return mechtable[i].bit;
|
||||
|
||||
c = ptr[mechtable[i].len];
|
||||
if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_')
|
||||
return mechtable[i].bit;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_parse_url_auth_option()
|
||||
*
|
||||
* Parse the URL login options.
|
||||
*/
|
||||
CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
|
||||
const char *value, size_t len)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t mechlen;
|
||||
|
||||
if(!len)
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
if(sasl->resetprefs) {
|
||||
sasl->resetprefs = FALSE;
|
||||
sasl->prefmech = SASL_AUTH_NONE;
|
||||
}
|
||||
|
||||
if(!strncmp(value, "*", len))
|
||||
sasl->prefmech = SASL_AUTH_DEFAULT;
|
||||
else {
|
||||
unsigned short mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
|
||||
if(mechbit && mechlen == len)
|
||||
sasl->prefmech |= mechbit;
|
||||
else
|
||||
result = CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_init()
|
||||
*
|
||||
* Initializes the SASL structure.
|
||||
*/
|
||||
void Curl_sasl_init(struct SASL *sasl, struct Curl_easy *data,
|
||||
const struct SASLproto *params)
|
||||
{
|
||||
unsigned long auth = data->set.httpauth;
|
||||
|
||||
sasl->params = params; /* Set protocol dependent parameters */
|
||||
sasl->state = SASL_STOP; /* Not yet running */
|
||||
sasl->curmech = NULL; /* No mechanism yet. */
|
||||
sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */
|
||||
sasl->prefmech = params->defmechs; /* Default preferred mechanisms */
|
||||
sasl->authused = SASL_AUTH_NONE; /* The authentication mechanism used */
|
||||
sasl->resetprefs = TRUE; /* Reset prefmech upon AUTH parsing. */
|
||||
sasl->mutual_auth = FALSE; /* No mutual authentication (GSSAPI only) */
|
||||
sasl->force_ir = FALSE; /* Respect external option */
|
||||
|
||||
if(auth != CURLAUTH_BASIC) {
|
||||
unsigned short mechs = SASL_AUTH_NONE;
|
||||
|
||||
/* If some usable http authentication options have been set, determine
|
||||
new defaults from them. */
|
||||
if(auth & CURLAUTH_BASIC)
|
||||
mechs |= SASL_MECH_PLAIN | SASL_MECH_LOGIN;
|
||||
if(auth & CURLAUTH_DIGEST)
|
||||
mechs |= SASL_MECH_DIGEST_MD5;
|
||||
if(auth & CURLAUTH_NTLM)
|
||||
mechs |= SASL_MECH_NTLM;
|
||||
if(auth & CURLAUTH_BEARER)
|
||||
mechs |= SASL_MECH_OAUTHBEARER | SASL_MECH_XOAUTH2;
|
||||
if(auth & CURLAUTH_GSSAPI)
|
||||
mechs |= SASL_MECH_GSSAPI;
|
||||
|
||||
if(mechs != SASL_AUTH_NONE)
|
||||
sasl->prefmech = mechs;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sasl_state()
|
||||
*
|
||||
* This is the ONLY way to change SASL state!
|
||||
*/
|
||||
static void sasl_state(struct SASL *sasl, struct Curl_easy *data,
|
||||
saslstate newstate)
|
||||
{
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
/* for debug purposes */
|
||||
static const char * const names[]={
|
||||
"STOP",
|
||||
"PLAIN",
|
||||
"LOGIN",
|
||||
"LOGIN_PASSWD",
|
||||
"EXTERNAL",
|
||||
"CRAMMD5",
|
||||
"DIGESTMD5",
|
||||
"DIGESTMD5_RESP",
|
||||
"NTLM",
|
||||
"NTLM_TYPE2MSG",
|
||||
"GSSAPI",
|
||||
"GSSAPI_TOKEN",
|
||||
"GSSAPI_NO_DATA",
|
||||
"OAUTH2",
|
||||
"OAUTH2_RESP",
|
||||
"GSASL",
|
||||
"CANCEL",
|
||||
"FINAL",
|
||||
/* LAST */
|
||||
};
|
||||
|
||||
if(sasl->state != newstate)
|
||||
infof(data, "SASL %p state change from %s to %s",
|
||||
(void *)sasl, names[sasl->state], names[newstate]);
|
||||
#else
|
||||
(void) data;
|
||||
#endif
|
||||
|
||||
sasl->state = newstate;
|
||||
}
|
||||
|
||||
#if defined(USE_NTLM) || defined(USE_GSASL) || defined(USE_KERBEROS5) || \
|
||||
!defined(CURL_DISABLE_DIGEST_AUTH)
|
||||
/* Get the SASL server message and convert it to binary. */
|
||||
static CURLcode get_server_message(struct SASL *sasl, struct Curl_easy *data,
|
||||
struct bufref *out)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
result = sasl->params->getmessage(data, out);
|
||||
if(!result && (sasl->params->flags & SASL_FLAG_BASE64)) {
|
||||
unsigned char *msg;
|
||||
size_t msglen;
|
||||
const char *serverdata = (const char *) Curl_bufref_ptr(out);
|
||||
|
||||
if(!*serverdata || *serverdata == '=')
|
||||
Curl_bufref_set(out, NULL, 0, NULL);
|
||||
else {
|
||||
result = Curl_base64_decode(serverdata, &msg, &msglen);
|
||||
if(!result)
|
||||
Curl_bufref_set(out, msg, msglen, curl_free);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Encode the outgoing SASL message. */
|
||||
static CURLcode build_message(struct SASL *sasl, struct bufref *msg)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(sasl->params->flags & SASL_FLAG_BASE64) {
|
||||
if(!Curl_bufref_ptr(msg)) /* Empty message. */
|
||||
Curl_bufref_set(msg, "", 0, NULL);
|
||||
else if(!Curl_bufref_len(msg)) /* Explicit empty response. */
|
||||
Curl_bufref_set(msg, "=", 1, NULL);
|
||||
else {
|
||||
char *base64;
|
||||
size_t base64len;
|
||||
|
||||
result = Curl_base64_encode((const char *) Curl_bufref_ptr(msg),
|
||||
Curl_bufref_len(msg), &base64, &base64len);
|
||||
if(!result)
|
||||
Curl_bufref_set(msg, base64, base64len, curl_free);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_can_authenticate()
|
||||
*
|
||||
* Check if we have enough auth data and capabilities to authenticate.
|
||||
*/
|
||||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data)
|
||||
{
|
||||
/* Have credentials been provided? */
|
||||
if(data->state.aptr.user)
|
||||
return TRUE;
|
||||
|
||||
/* EXTERNAL can authenticate without a user name and/or password */
|
||||
if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_start()
|
||||
*
|
||||
* Calculate the required login details for SASL authentication.
|
||||
*/
|
||||
CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
|
||||
bool force_ir, saslprogress *progress)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
unsigned short enabledmechs;
|
||||
const char *mech = NULL;
|
||||
struct bufref resp;
|
||||
saslstate state1 = SASL_STOP;
|
||||
saslstate state2 = SASL_FINAL;
|
||||
const char *hostname, *disp_hostname;
|
||||
int port;
|
||||
#if defined(USE_KERBEROS5) || defined(USE_NTLM)
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
sasl->params->service;
|
||||
#endif
|
||||
const char *oauth_bearer = data->set.str[STRING_BEARER];
|
||||
struct bufref nullmsg;
|
||||
|
||||
Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
|
||||
Curl_bufref_init(&nullmsg);
|
||||
Curl_bufref_init(&resp);
|
||||
sasl->force_ir = force_ir; /* Latch for future use */
|
||||
sasl->authused = 0; /* No mechanism used yet */
|
||||
enabledmechs = sasl->authmechs & sasl->prefmech;
|
||||
*progress = SASL_IDLE;
|
||||
|
||||
/* Calculate the supported authentication mechanism, by decreasing order of
|
||||
security, as well as the initial response where appropriate */
|
||||
if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) {
|
||||
mech = SASL_MECH_STRING_EXTERNAL;
|
||||
state1 = SASL_EXTERNAL;
|
||||
sasl->authused = SASL_MECH_EXTERNAL;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
Curl_auth_create_external_message(conn->user, &resp);
|
||||
}
|
||||
else if(data->state.aptr.user) {
|
||||
#if defined(USE_KERBEROS5)
|
||||
if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() &&
|
||||
Curl_auth_user_contains_domain(conn->user)) {
|
||||
sasl->mutual_auth = FALSE;
|
||||
mech = SASL_MECH_STRING_GSSAPI;
|
||||
state1 = SASL_GSSAPI;
|
||||
state2 = SASL_GSSAPI_TOKEN;
|
||||
sasl->authused = SASL_MECH_GSSAPI;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd,
|
||||
service,
|
||||
conn->host.name,
|
||||
sasl->mutual_auth,
|
||||
NULL, &conn->krb5,
|
||||
&resp);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_GSASL
|
||||
if((enabledmechs & SASL_MECH_SCRAM_SHA_256) &&
|
||||
Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_256,
|
||||
&conn->gsasl)) {
|
||||
mech = SASL_MECH_STRING_SCRAM_SHA_256;
|
||||
sasl->authused = SASL_MECH_SCRAM_SHA_256;
|
||||
state1 = SASL_GSASL;
|
||||
state2 = SASL_GSASL;
|
||||
|
||||
result = Curl_auth_gsasl_start(data, conn->user,
|
||||
conn->passwd, &conn->gsasl);
|
||||
if(result == CURLE_OK && (force_ir || data->set.sasl_ir))
|
||||
result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp);
|
||||
}
|
||||
else if((enabledmechs & SASL_MECH_SCRAM_SHA_1) &&
|
||||
Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1,
|
||||
&conn->gsasl)) {
|
||||
mech = SASL_MECH_STRING_SCRAM_SHA_1;
|
||||
sasl->authused = SASL_MECH_SCRAM_SHA_1;
|
||||
state1 = SASL_GSASL;
|
||||
state2 = SASL_GSASL;
|
||||
|
||||
result = Curl_auth_gsasl_start(data, conn->user,
|
||||
conn->passwd, &conn->gsasl);
|
||||
if(result == CURLE_OK && (force_ir || data->set.sasl_ir))
|
||||
result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_DIGEST_AUTH
|
||||
if((enabledmechs & SASL_MECH_DIGEST_MD5) &&
|
||||
Curl_auth_is_digest_supported()) {
|
||||
mech = SASL_MECH_STRING_DIGEST_MD5;
|
||||
state1 = SASL_DIGESTMD5;
|
||||
sasl->authused = SASL_MECH_DIGEST_MD5;
|
||||
}
|
||||
else if(enabledmechs & SASL_MECH_CRAM_MD5) {
|
||||
mech = SASL_MECH_STRING_CRAM_MD5;
|
||||
state1 = SASL_CRAMMD5;
|
||||
sasl->authused = SASL_MECH_CRAM_MD5;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_NTLM
|
||||
if((enabledmechs & SASL_MECH_NTLM) && Curl_auth_is_ntlm_supported()) {
|
||||
mech = SASL_MECH_STRING_NTLM;
|
||||
state1 = SASL_NTLM;
|
||||
state2 = SASL_NTLM_TYPE2MSG;
|
||||
sasl->authused = SASL_MECH_NTLM;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_ntlm_type1_message(data,
|
||||
conn->user, conn->passwd,
|
||||
service,
|
||||
hostname,
|
||||
&conn->ntlm, &resp);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if((enabledmechs & SASL_MECH_OAUTHBEARER) && oauth_bearer) {
|
||||
mech = SASL_MECH_STRING_OAUTHBEARER;
|
||||
state1 = SASL_OAUTH2;
|
||||
state2 = SASL_OAUTH2_RESP;
|
||||
sasl->authused = SASL_MECH_OAUTHBEARER;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_oauth_bearer_message(conn->user,
|
||||
hostname,
|
||||
port,
|
||||
oauth_bearer,
|
||||
&resp);
|
||||
}
|
||||
else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) {
|
||||
mech = SASL_MECH_STRING_XOAUTH2;
|
||||
state1 = SASL_OAUTH2;
|
||||
sasl->authused = SASL_MECH_XOAUTH2;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_xoauth_bearer_message(conn->user,
|
||||
oauth_bearer,
|
||||
&resp);
|
||||
}
|
||||
else if(enabledmechs & SASL_MECH_PLAIN) {
|
||||
mech = SASL_MECH_STRING_PLAIN;
|
||||
state1 = SASL_PLAIN;
|
||||
sasl->authused = SASL_MECH_PLAIN;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_plain_message(conn->sasl_authzid,
|
||||
conn->user, conn->passwd,
|
||||
&resp);
|
||||
}
|
||||
else if(enabledmechs & SASL_MECH_LOGIN) {
|
||||
mech = SASL_MECH_STRING_LOGIN;
|
||||
state1 = SASL_LOGIN;
|
||||
state2 = SASL_LOGIN_PASSWD;
|
||||
sasl->authused = SASL_MECH_LOGIN;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
Curl_auth_create_login_message(conn->user, &resp);
|
||||
}
|
||||
}
|
||||
|
||||
if(!result && mech) {
|
||||
sasl->curmech = mech;
|
||||
if(Curl_bufref_ptr(&resp))
|
||||
result = build_message(sasl, &resp);
|
||||
|
||||
if(sasl->params->maxirlen &&
|
||||
strlen(mech) + Curl_bufref_len(&resp) > sasl->params->maxirlen)
|
||||
Curl_bufref_free(&resp);
|
||||
|
||||
if(!result)
|
||||
result = sasl->params->sendauth(data, mech, &resp);
|
||||
|
||||
if(!result) {
|
||||
*progress = SASL_INPROGRESS;
|
||||
sasl_state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1);
|
||||
}
|
||||
}
|
||||
|
||||
Curl_bufref_free(&resp);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_continue()
|
||||
*
|
||||
* Continue the authentication.
|
||||
*/
|
||||
CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||
int code, saslprogress *progress)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
saslstate newstate = SASL_FINAL;
|
||||
struct bufref resp;
|
||||
const char *hostname, *disp_hostname;
|
||||
int port;
|
||||
#if defined(USE_KERBEROS5) || defined(USE_NTLM) \
|
||||
|| !defined(CURL_DISABLE_DIGEST_AUTH)
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
sasl->params->service;
|
||||
#endif
|
||||
const char *oauth_bearer = data->set.str[STRING_BEARER];
|
||||
struct bufref serverdata;
|
||||
|
||||
Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
|
||||
Curl_bufref_init(&serverdata);
|
||||
Curl_bufref_init(&resp);
|
||||
*progress = SASL_INPROGRESS;
|
||||
|
||||
if(sasl->state == SASL_FINAL) {
|
||||
if(code != sasl->params->finalcode)
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
*progress = SASL_DONE;
|
||||
sasl_state(sasl, data, SASL_STOP);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP &&
|
||||
code != sasl->params->contcode) {
|
||||
*progress = SASL_DONE;
|
||||
sasl_state(sasl, data, SASL_STOP);
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
switch(sasl->state) {
|
||||
case SASL_STOP:
|
||||
*progress = SASL_DONE;
|
||||
return result;
|
||||
case SASL_PLAIN:
|
||||
result = Curl_auth_create_plain_message(conn->sasl_authzid,
|
||||
conn->user, conn->passwd, &resp);
|
||||
break;
|
||||
case SASL_LOGIN:
|
||||
Curl_auth_create_login_message(conn->user, &resp);
|
||||
newstate = SASL_LOGIN_PASSWD;
|
||||
break;
|
||||
case SASL_LOGIN_PASSWD:
|
||||
Curl_auth_create_login_message(conn->passwd, &resp);
|
||||
break;
|
||||
case SASL_EXTERNAL:
|
||||
Curl_auth_create_external_message(conn->user, &resp);
|
||||
break;
|
||||
#ifdef USE_GSASL
|
||||
case SASL_GSASL:
|
||||
result = get_server_message(sasl, data, &serverdata);
|
||||
if(!result)
|
||||
result = Curl_auth_gsasl_token(data, &serverdata, &conn->gsasl, &resp);
|
||||
if(!result && Curl_bufref_len(&resp) > 0)
|
||||
newstate = SASL_GSASL;
|
||||
break;
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_DIGEST_AUTH
|
||||
case SASL_CRAMMD5:
|
||||
result = get_server_message(sasl, data, &serverdata);
|
||||
if(!result)
|
||||
result = Curl_auth_create_cram_md5_message(&serverdata, conn->user,
|
||||
conn->passwd, &resp);
|
||||
break;
|
||||
case SASL_DIGESTMD5:
|
||||
result = get_server_message(sasl, data, &serverdata);
|
||||
if(!result)
|
||||
result = Curl_auth_create_digest_md5_message(data, &serverdata,
|
||||
conn->user, conn->passwd,
|
||||
service, &resp);
|
||||
if(!result && (sasl->params->flags & SASL_FLAG_BASE64))
|
||||
newstate = SASL_DIGESTMD5_RESP;
|
||||
break;
|
||||
case SASL_DIGESTMD5_RESP:
|
||||
/* Keep response NULL to output an empty line. */
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NTLM
|
||||
case SASL_NTLM:
|
||||
/* Create the type-1 message */
|
||||
result = Curl_auth_create_ntlm_type1_message(data,
|
||||
conn->user, conn->passwd,
|
||||
service, hostname,
|
||||
&conn->ntlm, &resp);
|
||||
newstate = SASL_NTLM_TYPE2MSG;
|
||||
break;
|
||||
case SASL_NTLM_TYPE2MSG:
|
||||
/* Decode the type-2 message */
|
||||
result = get_server_message(sasl, data, &serverdata);
|
||||
if(!result)
|
||||
result = Curl_auth_decode_ntlm_type2_message(data, &serverdata,
|
||||
&conn->ntlm);
|
||||
if(!result)
|
||||
result = Curl_auth_create_ntlm_type3_message(data, conn->user,
|
||||
conn->passwd, &conn->ntlm,
|
||||
&resp);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(USE_KERBEROS5)
|
||||
case SASL_GSSAPI:
|
||||
result = Curl_auth_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd,
|
||||
service,
|
||||
conn->host.name,
|
||||
sasl->mutual_auth, NULL,
|
||||
&conn->krb5,
|
||||
&resp);
|
||||
newstate = SASL_GSSAPI_TOKEN;
|
||||
break;
|
||||
case SASL_GSSAPI_TOKEN:
|
||||
result = get_server_message(sasl, data, &serverdata);
|
||||
if(!result) {
|
||||
if(sasl->mutual_auth) {
|
||||
/* Decode the user token challenge and create the optional response
|
||||
message */
|
||||
result = Curl_auth_create_gssapi_user_message(data, NULL, NULL,
|
||||
NULL, NULL,
|
||||
sasl->mutual_auth,
|
||||
&serverdata,
|
||||
&conn->krb5,
|
||||
&resp);
|
||||
newstate = SASL_GSSAPI_NO_DATA;
|
||||
}
|
||||
else
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = Curl_auth_create_gssapi_security_message(data,
|
||||
conn->sasl_authzid,
|
||||
&serverdata,
|
||||
&conn->krb5,
|
||||
&resp);
|
||||
}
|
||||
break;
|
||||
case SASL_GSSAPI_NO_DATA:
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = get_server_message(sasl, data, &serverdata);
|
||||
if(!result)
|
||||
result = Curl_auth_create_gssapi_security_message(data,
|
||||
conn->sasl_authzid,
|
||||
&serverdata,
|
||||
&conn->krb5,
|
||||
&resp);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SASL_OAUTH2:
|
||||
/* Create the authorization message */
|
||||
if(sasl->authused == SASL_MECH_OAUTHBEARER) {
|
||||
result = Curl_auth_create_oauth_bearer_message(conn->user,
|
||||
hostname,
|
||||
port,
|
||||
oauth_bearer,
|
||||
&resp);
|
||||
|
||||
/* Failures maybe sent by the server as continuations for OAUTHBEARER */
|
||||
newstate = SASL_OAUTH2_RESP;
|
||||
}
|
||||
else
|
||||
result = Curl_auth_create_xoauth_bearer_message(conn->user,
|
||||
oauth_bearer,
|
||||
&resp);
|
||||
break;
|
||||
|
||||
case SASL_OAUTH2_RESP:
|
||||
/* The continuation is optional so check the response code */
|
||||
if(code == sasl->params->finalcode) {
|
||||
/* Final response was received so we are done */
|
||||
*progress = SASL_DONE;
|
||||
sasl_state(sasl, data, SASL_STOP);
|
||||
return result;
|
||||
}
|
||||
else if(code == sasl->params->contcode) {
|
||||
/* Acknowledge the continuation by sending a 0x01 response. */
|
||||
Curl_bufref_set(&resp, "\x01", 1, NULL);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
*progress = SASL_DONE;
|
||||
sasl_state(sasl, data, SASL_STOP);
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
case SASL_CANCEL:
|
||||
/* Remove the offending mechanism from the supported list */
|
||||
sasl->authmechs ^= sasl->authused;
|
||||
|
||||
/* Start an alternative SASL authentication */
|
||||
return Curl_sasl_start(sasl, data, sasl->force_ir, progress);
|
||||
default:
|
||||
failf(data, "Unsupported SASL authentication mechanism");
|
||||
result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */
|
||||
break;
|
||||
}
|
||||
|
||||
Curl_bufref_free(&serverdata);
|
||||
|
||||
switch(result) {
|
||||
case CURLE_BAD_CONTENT_ENCODING:
|
||||
/* Cancel dialog */
|
||||
result = sasl->params->cancelauth(data, sasl->curmech);
|
||||
newstate = SASL_CANCEL;
|
||||
break;
|
||||
case CURLE_OK:
|
||||
result = build_message(sasl, &resp);
|
||||
if(!result)
|
||||
result = sasl->params->contauth(data, sasl->curmech, &resp);
|
||||
break;
|
||||
default:
|
||||
newstate = SASL_STOP; /* Stop on error */
|
||||
*progress = SASL_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
Curl_bufref_free(&resp);
|
||||
|
||||
sasl_state(sasl, data, newstate);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif /* protocols are enabled that use SASL */
|
165
third_party/curl/lib/curl_sasl.h
vendored
Normal file
165
third_party/curl/lib/curl_sasl.h
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
#ifndef HEADER_CURL_SASL_H
|
||||
#define HEADER_CURL_SASL_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/curl.h>
|
||||
|
||||
#include "bufref.h"
|
||||
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
|
||||
/* Authentication mechanism flags */
|
||||
#define SASL_MECH_LOGIN (1 << 0)
|
||||
#define SASL_MECH_PLAIN (1 << 1)
|
||||
#define SASL_MECH_CRAM_MD5 (1 << 2)
|
||||
#define SASL_MECH_DIGEST_MD5 (1 << 3)
|
||||
#define SASL_MECH_GSSAPI (1 << 4)
|
||||
#define SASL_MECH_EXTERNAL (1 << 5)
|
||||
#define SASL_MECH_NTLM (1 << 6)
|
||||
#define SASL_MECH_XOAUTH2 (1 << 7)
|
||||
#define SASL_MECH_OAUTHBEARER (1 << 8)
|
||||
#define SASL_MECH_SCRAM_SHA_1 (1 << 9)
|
||||
#define SASL_MECH_SCRAM_SHA_256 (1 << 10)
|
||||
|
||||
/* Authentication mechanism values */
|
||||
#define SASL_AUTH_NONE 0
|
||||
#define SASL_AUTH_ANY 0xffff
|
||||
#define SASL_AUTH_DEFAULT (SASL_AUTH_ANY & ~SASL_MECH_EXTERNAL)
|
||||
|
||||
/* Authentication mechanism strings */
|
||||
#define SASL_MECH_STRING_LOGIN "LOGIN"
|
||||
#define SASL_MECH_STRING_PLAIN "PLAIN"
|
||||
#define SASL_MECH_STRING_CRAM_MD5 "CRAM-MD5"
|
||||
#define SASL_MECH_STRING_DIGEST_MD5 "DIGEST-MD5"
|
||||
#define SASL_MECH_STRING_GSSAPI "GSSAPI"
|
||||
#define SASL_MECH_STRING_EXTERNAL "EXTERNAL"
|
||||
#define SASL_MECH_STRING_NTLM "NTLM"
|
||||
#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2"
|
||||
#define SASL_MECH_STRING_OAUTHBEARER "OAUTHBEARER"
|
||||
#define SASL_MECH_STRING_SCRAM_SHA_1 "SCRAM-SHA-1"
|
||||
#define SASL_MECH_STRING_SCRAM_SHA_256 "SCRAM-SHA-256"
|
||||
|
||||
/* SASL flags */
|
||||
#define SASL_FLAG_BASE64 0x0001 /* Messages are base64-encoded */
|
||||
|
||||
/* SASL machine states */
|
||||
typedef enum {
|
||||
SASL_STOP,
|
||||
SASL_PLAIN,
|
||||
SASL_LOGIN,
|
||||
SASL_LOGIN_PASSWD,
|
||||
SASL_EXTERNAL,
|
||||
SASL_CRAMMD5,
|
||||
SASL_DIGESTMD5,
|
||||
SASL_DIGESTMD5_RESP,
|
||||
SASL_NTLM,
|
||||
SASL_NTLM_TYPE2MSG,
|
||||
SASL_GSSAPI,
|
||||
SASL_GSSAPI_TOKEN,
|
||||
SASL_GSSAPI_NO_DATA,
|
||||
SASL_OAUTH2,
|
||||
SASL_OAUTH2_RESP,
|
||||
SASL_GSASL,
|
||||
SASL_CANCEL,
|
||||
SASL_FINAL
|
||||
} saslstate;
|
||||
|
||||
/* Progress indicator */
|
||||
typedef enum {
|
||||
SASL_IDLE,
|
||||
SASL_INPROGRESS,
|
||||
SASL_DONE
|
||||
} saslprogress;
|
||||
|
||||
/* Protocol dependent SASL parameters */
|
||||
struct SASLproto {
|
||||
const char *service; /* The service name */
|
||||
CURLcode (*sendauth)(struct Curl_easy *data, const char *mech,
|
||||
const struct bufref *ir);
|
||||
/* Send authentication command */
|
||||
CURLcode (*contauth)(struct Curl_easy *data, const char *mech,
|
||||
const struct bufref *contauth);
|
||||
/* Send authentication continuation */
|
||||
CURLcode (*cancelauth)(struct Curl_easy *data, const char *mech);
|
||||
/* Cancel authentication. */
|
||||
CURLcode (*getmessage)(struct Curl_easy *data, struct bufref *out);
|
||||
/* Get SASL response message */
|
||||
size_t maxirlen; /* Maximum initial response + mechanism length,
|
||||
or zero if no max. This is normally the max
|
||||
command length - other characters count.
|
||||
This has to be zero for non-base64 protocols. */
|
||||
int contcode; /* Code to receive when continuation is expected */
|
||||
int finalcode; /* Code to receive upon authentication success */
|
||||
unsigned short defmechs; /* Mechanisms enabled by default */
|
||||
unsigned short flags; /* Configuration flags. */
|
||||
};
|
||||
|
||||
/* Per-connection parameters */
|
||||
struct SASL {
|
||||
const struct SASLproto *params; /* Protocol dependent parameters */
|
||||
saslstate state; /* Current machine state */
|
||||
const char *curmech; /* Current mechanism id. */
|
||||
unsigned short authmechs; /* Accepted authentication mechanisms */
|
||||
unsigned short prefmech; /* Preferred authentication mechanism */
|
||||
unsigned short authused; /* Auth mechanism used for the connection */
|
||||
BIT(resetprefs); /* For URL auth option parsing. */
|
||||
BIT(mutual_auth); /* Mutual authentication enabled (GSSAPI only) */
|
||||
BIT(force_ir); /* Protocol always supports initial response */
|
||||
};
|
||||
|
||||
/* This is used to test whether the line starts with the given mechanism */
|
||||
#define sasl_mech_equal(line, wordlen, mech) \
|
||||
(wordlen == (sizeof(mech) - 1) / sizeof(char) && \
|
||||
!memcmp(line, mech, wordlen))
|
||||
|
||||
/* This is used to cleanup any libraries or curl modules used by the sasl
|
||||
functions */
|
||||
void Curl_sasl_cleanup(struct connectdata *conn, unsigned short authused);
|
||||
|
||||
/* Convert a mechanism name to a token */
|
||||
unsigned short Curl_sasl_decode_mech(const char *ptr,
|
||||
size_t maxlen, size_t *len);
|
||||
|
||||
/* Parse the URL login options */
|
||||
CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
|
||||
const char *value, size_t len);
|
||||
|
||||
/* Initializes an SASL structure */
|
||||
void Curl_sasl_init(struct SASL *sasl, struct Curl_easy *data,
|
||||
const struct SASLproto *params);
|
||||
|
||||
/* Check if we have enough auth data and capabilities to authenticate */
|
||||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data);
|
||||
|
||||
/* Calculate the required login details for SASL authentication */
|
||||
CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
|
||||
bool force_ir, saslprogress *progress);
|
||||
|
||||
/* Continue an SASL authentication */
|
||||
CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||
int code, saslprogress *progress);
|
||||
|
||||
#endif /* HEADER_CURL_SASL_H */
|
921
third_party/curl/lib/curl_setup.h
vendored
Normal file
921
third_party/curl/lib/curl_setup.h
vendored
Normal file
@ -0,0 +1,921 @@
|
||||
#ifndef HEADER_CURL_SETUP_H
|
||||
#define HEADER_CURL_SETUP_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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#if defined(BUILDING_LIBCURL) && !defined(CURL_NO_OLDIES)
|
||||
#define CURL_NO_OLDIES
|
||||
#endif
|
||||
|
||||
/* FIXME: Delete this once the warnings have been fixed. */
|
||||
#if !defined(CURL_WARN_SIGN_CONVERSION)
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Set default _WIN32_WINNT */
|
||||
#ifdef __MINGW32__
|
||||
#include <_mingw.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disable Visual Studio warnings:
|
||||
* 4127 "conditional expression is constant"
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4127)
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Don't include unneeded stuff in Windows headers to avoid compiler
|
||||
* warnings and macro clashes.
|
||||
* Make sure to define this macro before including any Windows headers.
|
||||
*/
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# ifndef NOGDI
|
||||
# define NOGDI
|
||||
# endif
|
||||
/* Detect Windows App environment which has a restricted access
|
||||
* to the Win32 APIs. */
|
||||
# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \
|
||||
defined(WINAPI_FAMILY)
|
||||
# include <winapifamily.h>
|
||||
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
|
||||
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
# define CURL_WINDOWS_APP
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Compatibility */
|
||||
#if defined(ENABLE_IPV6)
|
||||
# define USE_IPV6 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include configuration script results or hand-crafted
|
||||
* configuration file for platforms which lack config tool.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
||||
#include "curl_config.h"
|
||||
|
||||
#else /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
# include "config-win32ce.h"
|
||||
#else
|
||||
# ifdef _WIN32
|
||||
# include "config-win32.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef macintosh
|
||||
# include "config-mac.h"
|
||||
#endif
|
||||
|
||||
#ifdef __riscos__
|
||||
# include "config-riscos.h"
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# include "config-amigaos.h"
|
||||
#endif
|
||||
|
||||
#ifdef __OS400__
|
||||
# include "config-os400.h"
|
||||
#endif
|
||||
|
||||
#ifdef __PLAN9__
|
||||
# include "config-plan9.h"
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
# include "config-dos.h"
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
/* ================================================================ */
|
||||
/* Definition of preprocessor macros/symbols which modify compiler */
|
||||
/* behavior or generated code characteristics must be done here, */
|
||||
/* as appropriate, before any system header file is included. It is */
|
||||
/* also possible to have them defined in the config file included */
|
||||
/* before this point. As a result of all this we frown inclusion of */
|
||||
/* system header files in our config files, avoid this at any cost. */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* AIX 4.3 and newer needs _THREAD_SAFE defined to build
|
||||
* proper reentrant code. Others may also need it.
|
||||
*/
|
||||
|
||||
#ifdef NEED_THREAD_SAFE
|
||||
# ifndef _THREAD_SAFE
|
||||
# define _THREAD_SAFE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tru64 needs _REENTRANT set for a few function prototypes and
|
||||
* things to appear in the system header files. Unixware needs it
|
||||
* to build proper reentrant code. Others may also need it.
|
||||
*/
|
||||
|
||||
#ifdef NEED_REENTRANT
|
||||
# ifndef _REENTRANT
|
||||
# define _REENTRANT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Solaris needs this to get a POSIX-conformant getpwuid_r */
|
||||
#if defined(sun) || defined(__sun)
|
||||
# ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ================================================================ */
|
||||
/* If you need to include a system header file for your platform, */
|
||||
/* please, do it beyond the point further indicated in this file. */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* Disable other protocols when http is the only one desired.
|
||||
*/
|
||||
|
||||
#ifdef HTTP_ONLY
|
||||
# ifndef CURL_DISABLE_DICT
|
||||
# define CURL_DISABLE_DICT
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_FILE
|
||||
# define CURL_DISABLE_FILE
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_FTP
|
||||
# define CURL_DISABLE_FTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_GOPHER
|
||||
# define CURL_DISABLE_GOPHER
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_IMAP
|
||||
# define CURL_DISABLE_IMAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_LDAP
|
||||
# define CURL_DISABLE_LDAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_LDAPS
|
||||
# define CURL_DISABLE_LDAPS
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_MQTT
|
||||
# define CURL_DISABLE_MQTT
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_POP3
|
||||
# define CURL_DISABLE_POP3
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_RTSP
|
||||
# define CURL_DISABLE_RTSP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMB
|
||||
# define CURL_DISABLE_SMB
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMTP
|
||||
# define CURL_DISABLE_SMTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_TELNET
|
||||
# define CURL_DISABLE_TELNET
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_TFTP
|
||||
# define CURL_DISABLE_TFTP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When http is disabled rtsp is not supported.
|
||||
*/
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP)
|
||||
# define CURL_DISABLE_RTSP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When HTTP is disabled, disable HTTP-only features
|
||||
*/
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP)
|
||||
# define CURL_DISABLE_ALTSVC 1
|
||||
# define CURL_DISABLE_COOKIES 1
|
||||
# define CURL_DISABLE_BASIC_AUTH 1
|
||||
# define CURL_DISABLE_BEARER_AUTH 1
|
||||
# define CURL_DISABLE_AWS 1
|
||||
# define CURL_DISABLE_DOH 1
|
||||
# define CURL_DISABLE_FORM_API 1
|
||||
# define CURL_DISABLE_HEADERS_API 1
|
||||
# define CURL_DISABLE_HSTS 1
|
||||
# define CURL_DISABLE_HTTP_AUTH 1
|
||||
#endif
|
||||
|
||||
/* ================================================================ */
|
||||
/* No system header file shall be included in this file before this */
|
||||
/* point. */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* OS/400 setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef __OS400__
|
||||
# include "setup-os400.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VMS setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef __VMS
|
||||
# include "setup-vms.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Windows setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
# include "setup-win32.h"
|
||||
#endif
|
||||
|
||||
#include <curl/system.h>
|
||||
|
||||
/* Helper macro to expand and concatenate two macros.
|
||||
* Direct macros concatenation does not work because macros
|
||||
* are not expanded before direct concatenation.
|
||||
*/
|
||||
#define CURL_CONC_MACROS_(A,B) A ## B
|
||||
#define CURL_CONC_MACROS(A,B) CURL_CONC_MACROS_(A,B)
|
||||
|
||||
/* curl uses its own printf() function internally. It understands the GNU
|
||||
* format. Use this format, so that is matches the GNU format attribute we
|
||||
* use with the mingw compiler, allowing it to verify them at compile-time.
|
||||
*/
|
||||
#ifdef __MINGW32__
|
||||
# undef CURL_FORMAT_CURL_OFF_T
|
||||
# undef CURL_FORMAT_CURL_OFF_TU
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
#endif
|
||||
|
||||
/* based on logic in "curl/mprintf.h" */
|
||||
|
||||
#if (defined(__GNUC__) || defined(__clang__) || \
|
||||
defined(__IAR_SYSTEMS_ICC__)) && \
|
||||
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
||||
!defined(CURL_NO_FMT_CHECKS)
|
||||
#if defined(__MINGW32__) && !defined(__clang__)
|
||||
#define CURL_PRINTF(fmt, arg) \
|
||||
__attribute__((format(gnu_printf, fmt, arg)))
|
||||
#else
|
||||
#define CURL_PRINTF(fmt, arg) \
|
||||
__attribute__((format(__printf__, fmt, arg)))
|
||||
#endif
|
||||
#else
|
||||
#define CURL_PRINTF(fmt, arg)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use getaddrinfo to resolve the IPv4 address literal. If the current network
|
||||
* interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
|
||||
* performing this task will result in a synthesized IPv6 address.
|
||||
*/
|
||||
#if defined(__APPLE__) && !defined(USE_ARES)
|
||||
#include <TargetConditionals.h>
|
||||
#define USE_RESOLVE_ON_IPS 1
|
||||
# if TARGET_OS_MAC && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && \
|
||||
defined(USE_IPV6)
|
||||
# define CURL_MACOS_CALL_COPYPROXIES 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_LWIPSOCK
|
||||
# include <lwip/init.h>
|
||||
# include <lwip/sockets.h>
|
||||
# include <lwip/netdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTRA_STRICMP_H
|
||||
# include <extra/stricmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTRA_STRDUP_H
|
||||
# include <extra/strdup.h>
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# ifdef __amigaos4__
|
||||
# define __USE_INLINE__
|
||||
/* use our own resolver which uses runtime feature detection */
|
||||
# define CURLRES_AMIGA
|
||||
/* getaddrinfo() currently crashes bsdsocket.library, so disable */
|
||||
# undef HAVE_GETADDRINFO
|
||||
# if !(defined(__NEWLIB__) || \
|
||||
(defined(__CLIB2__) && defined(__THREAD_SAFE)))
|
||||
/* disable threaded resolver with clib2 - requires newlib or clib-ts */
|
||||
# undef USE_THREADS_POSIX
|
||||
# endif
|
||||
# endif
|
||||
# include <exec/types.h>
|
||||
# include <exec/execbase.h>
|
||||
# include <proto/exec.h>
|
||||
# include <proto/dos.h>
|
||||
# include <unistd.h>
|
||||
# if defined(HAVE_PROTO_BSDSOCKET_H) && \
|
||||
(!defined(__amigaos4__) || defined(USE_AMISSL))
|
||||
/* use bsdsocket.library directly, instead of libc networking functions */
|
||||
# define _SYS_MBUF_H /* m_len define clashes with curl */
|
||||
# include <proto/bsdsocket.h>
|
||||
# ifdef __amigaos4__
|
||||
int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *errorfds, struct timeval *timeout);
|
||||
# define select(a,b,c,d,e) Curl_amiga_select(a,b,c,d,e)
|
||||
# else
|
||||
# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
|
||||
# endif
|
||||
/* must not use libc's fcntl() on bsdsocket.library sockfds! */
|
||||
# undef HAVE_FCNTL
|
||||
# undef HAVE_FCNTL_O_NONBLOCK
|
||||
# else
|
||||
/* use libc networking and hence close() and fnctl() */
|
||||
# undef HAVE_CLOSESOCKET_CAMEL
|
||||
# undef HAVE_IOCTLSOCKET_CAMEL
|
||||
# endif
|
||||
/*
|
||||
* In clib2 arpa/inet.h warns that some prototypes may clash
|
||||
* with bsdsocket.library. This avoids the definition of those.
|
||||
*/
|
||||
# define __NO_NET_API
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __TANDEM /* for ns*-tandem-nsk systems */
|
||||
# if ! defined __LP64
|
||||
# include <floss.h> /* FLOSS is only used for 32-bit builds. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef STDC_HEADERS /* no standard C headers! */
|
||||
#include <curl/stdcheaders.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Large file (>2Gb) support using WIN32 functions.
|
||||
*/
|
||||
|
||||
#ifdef USE_WIN32_LARGE_FILES
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
|
||||
# undef fstat
|
||||
# define fstat(fdes,stp) _fstati64(fdes, stp)
|
||||
# undef stat
|
||||
# define stat(fname,stp) curlx_win32_stat(fname, stp)
|
||||
# define struct_stat struct _stati64
|
||||
# define LSEEK_ERROR (__int64)-1
|
||||
# define open curlx_win32_open
|
||||
# define fopen(fname,mode) curlx_win32_fopen(fname, mode)
|
||||
int curlx_win32_open(const char *filename, int oflag, ...);
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer);
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Small file (<2Gb) support using WIN32 functions.
|
||||
*/
|
||||
|
||||
#ifdef USE_WIN32_SMALL_FILES
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# ifndef _WIN32_WCE
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence)
|
||||
# define fstat(fdes,stp) _fstat(fdes, stp)
|
||||
# define stat(fname,stp) curlx_win32_stat(fname, stp)
|
||||
# define struct_stat struct _stat
|
||||
# define open curlx_win32_open
|
||||
# define fopen(fname,mode) curlx_win32_fopen(fname, mode)
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer);
|
||||
int curlx_win32_open(const char *filename, int oflag, ...);
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode);
|
||||
# endif
|
||||
# define LSEEK_ERROR (long)-1
|
||||
#endif
|
||||
|
||||
#ifndef struct_stat
|
||||
# define struct_stat struct stat
|
||||
#endif
|
||||
|
||||
#ifndef LSEEK_ERROR
|
||||
# define LSEEK_ERROR (off_t)-1
|
||||
#endif
|
||||
|
||||
#ifndef SIZEOF_TIME_T
|
||||
/* assume default size of time_t to be 32 bit */
|
||||
#define SIZEOF_TIME_T 4
|
||||
#endif
|
||||
|
||||
#ifndef SIZEOF_CURL_SOCKET_T
|
||||
/* configure and cmake check and set the define */
|
||||
# ifdef _WIN64
|
||||
# define SIZEOF_CURL_SOCKET_T 8
|
||||
# else
|
||||
/* default guess */
|
||||
# define SIZEOF_CURL_SOCKET_T 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if SIZEOF_CURL_SOCKET_T < 8
|
||||
# define CURL_FORMAT_SOCKET_T "d"
|
||||
#elif defined(__MINGW32__)
|
||||
# define CURL_FORMAT_SOCKET_T "zd"
|
||||
#else
|
||||
# define CURL_FORMAT_SOCKET_T "qd"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default sizeof(off_t) in case it hasn't been defined in config file.
|
||||
*/
|
||||
|
||||
#ifndef SIZEOF_OFF_T
|
||||
# if defined(__VMS) && !defined(__VAX)
|
||||
# if defined(_LARGEFILE)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# elif defined(__OS400__) && defined(__ILEC400__)
|
||||
# if defined(_LARGE_FILES)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# elif defined(__MVS__) && defined(__IBMC__)
|
||||
# if defined(_LP64) || defined(_LARGE_FILES)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# elif defined(__370__) && defined(__IBMC__)
|
||||
# if defined(_LP64) || defined(_LARGE_FILES)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# endif
|
||||
# ifndef SIZEOF_OFF_T
|
||||
# define SIZEOF_OFF_T 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (SIZEOF_CURL_OFF_T < 8)
|
||||
#error "too small curl_off_t"
|
||||
#else
|
||||
/* assume SIZEOF_CURL_OFF_T == 8 */
|
||||
# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF)
|
||||
#endif
|
||||
#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1))
|
||||
|
||||
#if (SIZEOF_CURL_OFF_T != 8)
|
||||
# error "curl_off_t must be exactly 64 bits"
|
||||
#else
|
||||
typedef unsigned CURL_TYPEOF_CURL_OFF_T curl_uint64_t;
|
||||
typedef CURL_TYPEOF_CURL_OFF_T curl_int64_t;
|
||||
# ifndef CURL_SUFFIX_CURL_OFF_TU
|
||||
# error "CURL_SUFFIX_CURL_OFF_TU must be defined"
|
||||
# endif
|
||||
# define CURL_UINT64_SUFFIX CURL_SUFFIX_CURL_OFF_TU
|
||||
# define CURL_UINT64_C(val) CURL_CONC_MACROS(val,CURL_UINT64_SUFFIX)
|
||||
# define CURL_PRId64 CURL_FORMAT_CURL_OFF_T
|
||||
# define CURL_PRIu64 CURL_FORMAT_CURL_OFF_TU
|
||||
#endif
|
||||
|
||||
#if (SIZEOF_TIME_T == 4)
|
||||
# ifdef HAVE_TIME_T_UNSIGNED
|
||||
# define TIME_T_MAX UINT_MAX
|
||||
# define TIME_T_MIN 0
|
||||
# else
|
||||
# define TIME_T_MAX INT_MAX
|
||||
# define TIME_T_MIN INT_MIN
|
||||
# endif
|
||||
#else
|
||||
# ifdef HAVE_TIME_T_UNSIGNED
|
||||
# define TIME_T_MAX 0xFFFFFFFFFFFFFFFF
|
||||
# define TIME_T_MIN 0
|
||||
# else
|
||||
# define TIME_T_MAX 0x7FFFFFFFFFFFFFFF
|
||||
# define TIME_T_MIN (-TIME_T_MAX - 1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_T_MAX
|
||||
/* some limits.h headers have this defined, some don't */
|
||||
#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
|
||||
#define SIZE_T_MAX 18446744073709551615U
|
||||
#else
|
||||
#define SIZE_T_MAX 4294967295U
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SSIZE_T_MAX
|
||||
/* some limits.h headers have this defined, some don't */
|
||||
#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
|
||||
#define SSIZE_T_MAX 9223372036854775807
|
||||
#else
|
||||
#define SSIZE_T_MAX 2147483647
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Arg 2 type for gethostname in case it hasn't been defined in config file.
|
||||
*/
|
||||
|
||||
#ifndef GETHOSTNAME_TYPE_ARG2
|
||||
# ifdef USE_WINSOCK
|
||||
# define GETHOSTNAME_TYPE_ARG2 int
|
||||
# else
|
||||
# define GETHOSTNAME_TYPE_ARG2 size_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Below we define some functions. They should
|
||||
|
||||
4. set the SIGALRM signal timeout
|
||||
5. set dir/file naming defines
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# define DIR_CHAR "\\"
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
# ifdef MSDOS /* Watt-32 */
|
||||
|
||||
# include <sys/ioctl.h>
|
||||
# define select(n,r,w,x,t) select_s(n,r,w,x,t)
|
||||
# define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
|
||||
# include <tcp.h>
|
||||
# ifdef word
|
||||
# undef word
|
||||
# endif
|
||||
# ifdef byte
|
||||
# undef byte
|
||||
# endif
|
||||
|
||||
# endif /* MSDOS */
|
||||
|
||||
# ifdef __minix
|
||||
/* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
|
||||
extern char *strtok_r(char *s, const char *delim, char **last);
|
||||
extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp);
|
||||
# endif
|
||||
|
||||
# define DIR_CHAR "/"
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* resolver specialty compile-time defines */
|
||||
/* CURLRES_* defines to use in the host*.c sources */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* MSVC threads support requires a multi-threaded runtime library.
|
||||
* _beginthreadex() is not available in single-threaded ones.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_MT)
|
||||
# undef USE_THREADS_POSIX
|
||||
# undef USE_THREADS_WIN32
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mutually exclusive CURLRES_* definitions.
|
||||
*/
|
||||
|
||||
#if defined(USE_IPV6) && defined(HAVE_GETADDRINFO)
|
||||
# define CURLRES_IPV6
|
||||
#elif defined(USE_IPV6) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||
/* assume on Windows that IPv6 without getaddrinfo is a broken build */
|
||||
# error "Unexpected build: IPv6 is enabled but getaddrinfo was not found."
|
||||
#else
|
||||
# define CURLRES_IPV4
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARES
|
||||
# define CURLRES_ASYNCH
|
||||
# define CURLRES_ARES
|
||||
/* now undef the stock libc functions just to avoid them being used */
|
||||
# undef HAVE_GETADDRINFO
|
||||
# undef HAVE_FREEADDRINFO
|
||||
#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
# define CURLRES_ASYNCH
|
||||
# define CURLRES_THREADED
|
||||
#else
|
||||
# define CURLRES_SYNCH
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && \
|
||||
!defined(USE_WIN32_IDN) && !defined(USE_APPLE_IDN)
|
||||
/* The lib and header are present */
|
||||
#define USE_LIBIDN2
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBIDN2) && (defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN))
|
||||
#error "libidn2 cannot be enabled with WinIDN or AppleIDN, choose one."
|
||||
#endif
|
||||
|
||||
#define LIBIDN_REQUIRED_VERSION "0.4.1"
|
||||
|
||||
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \
|
||||
defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_BEARSSL) || defined(USE_RUSTLS)
|
||||
#define USE_SSL /* SSL support has been enabled */
|
||||
#endif
|
||||
|
||||
/* Single point where USE_SPNEGO definition might be defined */
|
||||
#if !defined(CURL_DISABLE_NEGOTIATE_AUTH) && \
|
||||
(defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
|
||||
#define USE_SPNEGO
|
||||
#endif
|
||||
|
||||
/* Single point where USE_KERBEROS5 definition might be defined */
|
||||
#if !defined(CURL_DISABLE_KERBEROS_AUTH) && \
|
||||
(defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
|
||||
#define USE_KERBEROS5
|
||||
#endif
|
||||
|
||||
/* Single point where USE_NTLM definition might be defined */
|
||||
#if !defined(CURL_DISABLE_NTLM)
|
||||
# if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \
|
||||
defined(USE_GNUTLS) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
|
||||
(defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT))
|
||||
# define USE_CURL_NTLM_CORE
|
||||
# endif
|
||||
# if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI)
|
||||
# define USE_NTLM
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CURL_WANTS_CA_BUNDLE_ENV
|
||||
#error "No longer supported. Set CURLOPT_CAINFO at runtime instead."
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) || defined(USE_WOLFSSH)
|
||||
#define USE_SSH
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Provide a mechanism to silence picky compilers, such as gcc 4.6+.
|
||||
* Parameters should of course normally not be unused, but for example when
|
||||
* we have multiple implementations of the same interface it may happen.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) && ((__GNUC__ >= 3) || \
|
||||
((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
|
||||
# define UNUSED_PARAM __attribute__((__unused__))
|
||||
# define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
# define UNUSED_PARAM __attribute__((__unused__))
|
||||
# if (__VER__ >= 9040001)
|
||||
# define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||
# else
|
||||
# define WARN_UNUSED_RESULT
|
||||
# endif
|
||||
#else
|
||||
# define UNUSED_PARAM /* NOTHING */
|
||||
# define WARN_UNUSED_RESULT
|
||||
#endif
|
||||
|
||||
/* noreturn attribute */
|
||||
|
||||
#if !defined(CURL_NORETURN)
|
||||
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) || \
|
||||
defined(__IAR_SYSTEMS_ICC__)
|
||||
# define CURL_NORETURN __attribute__((__noreturn__))
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# define CURL_NORETURN __declspec(noreturn)
|
||||
#else
|
||||
# define CURL_NORETURN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* fallthrough attribute */
|
||||
|
||||
#if !defined(FALLTHROUGH)
|
||||
#if (defined(__GNUC__) && __GNUC__ >= 7) || \
|
||||
(defined(__clang__) && __clang_major__ >= 10)
|
||||
# define FALLTHROUGH() __attribute__((fallthrough))
|
||||
#else
|
||||
# define FALLTHROUGH() do {} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include macros and defines that should only be processed once.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CURL_SETUP_ONCE_H
|
||||
#include "curl_setup_once.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definition of our NOP statement Object-like macro
|
||||
*/
|
||||
|
||||
#ifndef Curl_nop_stmt
|
||||
# define Curl_nop_stmt do { } while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ensure that Winsock and lwIP TCP/IP stacks are not mixed.
|
||||
*/
|
||||
|
||||
#if defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)
|
||||
# if defined(SOCKET) || defined(USE_WINSOCK)
|
||||
# error "WinSock and lwIP TCP/IP stack definitions shall not coexist!"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* shutdown() flags for systems that don't define them
|
||||
*/
|
||||
|
||||
#ifndef SHUT_RD
|
||||
#define SHUT_RD 0x00
|
||||
#endif
|
||||
|
||||
#ifndef SHUT_WR
|
||||
#define SHUT_WR 0x01
|
||||
#endif
|
||||
|
||||
#ifndef SHUT_RDWR
|
||||
#define SHUT_RDWR 0x02
|
||||
#endif
|
||||
|
||||
/* Define S_ISREG if not defined by system headers, e.g. MSVC */
|
||||
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
/* Define S_ISDIR if not defined by system headers, e.g. MSVC */
|
||||
#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
/* In Windows the default file mode is text but an application can override it.
|
||||
Therefore we specify it explicitly. https://github.com/curl/curl/pull/258
|
||||
*/
|
||||
#if defined(_WIN32) || defined(MSDOS)
|
||||
#define FOPEN_READTEXT "rt"
|
||||
#define FOPEN_WRITETEXT "wt"
|
||||
#define FOPEN_APPENDTEXT "at"
|
||||
#elif defined(__CYGWIN__)
|
||||
/* Cygwin has specific behavior we need to address when WIN32 is not defined.
|
||||
https://cygwin.com/cygwin-ug-net/using-textbinary.html
|
||||
For write we want our output to have line endings of LF and be compatible with
|
||||
other Cygwin utilities. For read we want to handle input that may have line
|
||||
endings either CRLF or LF so 't' is appropriate.
|
||||
*/
|
||||
#define FOPEN_READTEXT "rt"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#define FOPEN_APPENDTEXT "a"
|
||||
#else
|
||||
#define FOPEN_READTEXT "r"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#define FOPEN_APPENDTEXT "a"
|
||||
#endif
|
||||
|
||||
/* for systems that don't detect this in configure */
|
||||
#ifndef CURL_SA_FAMILY_T
|
||||
# if defined(HAVE_SA_FAMILY_T)
|
||||
# define CURL_SA_FAMILY_T sa_family_t
|
||||
# elif defined(HAVE_ADDRESS_FAMILY)
|
||||
# define CURL_SA_FAMILY_T ADDRESS_FAMILY
|
||||
# else
|
||||
/* use a sensible default */
|
||||
# define CURL_SA_FAMILY_T unsigned short
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some convenience macros to get the larger/smaller value out of two given.
|
||||
We prefix with CURL to prevent name collisions. */
|
||||
#define CURLMAX(x,y) ((x)>(y)?(x):(y))
|
||||
#define CURLMIN(x,y) ((x)<(y)?(x):(y))
|
||||
|
||||
/* A convenience macro to provide both the string literal and the length of
|
||||
the string literal in one go, useful for functions that take "string,len"
|
||||
as their argument */
|
||||
#define STRCONST(x) x,sizeof(x)-1
|
||||
|
||||
/* Some versions of the Android SDK is missing the declaration */
|
||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
|
||||
struct passwd;
|
||||
int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
size_t buflen, struct passwd **result);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define UNITTEST
|
||||
#else
|
||||
#define UNITTEST static
|
||||
#endif
|
||||
|
||||
/* Hyper supports HTTP2 also, but Curl's integration with Hyper does not */
|
||||
#if defined(USE_NGHTTP2)
|
||||
#define USE_HTTP2
|
||||
#endif
|
||||
|
||||
#if (defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || \
|
||||
(defined(USE_OPENSSL_QUIC) && defined(USE_NGHTTP3)) || \
|
||||
defined(USE_QUICHE) || defined(USE_MSH3)
|
||||
|
||||
#ifdef CURL_WITH_MULTI_SSL
|
||||
#error "Multi-SSL combined with QUIC is not supported"
|
||||
#endif
|
||||
|
||||
#define USE_HTTP3
|
||||
#endif
|
||||
|
||||
/* Certain Windows implementations are not aligned with what curl expects,
|
||||
so always use the local one on this platform. E.g. the mingw-w64
|
||||
implementation can return wrong results for non-ASCII inputs. */
|
||||
#if defined(HAVE_BASENAME) && defined(_WIN32)
|
||||
#undef HAVE_BASENAME
|
||||
#endif
|
||||
|
||||
#if defined(USE_UNIX_SOCKETS) && defined(_WIN32)
|
||||
# if !defined(UNIX_PATH_MAX)
|
||||
/* Replicating logic present in afunix.h
|
||||
(distributed with newer Windows 10 SDK versions only) */
|
||||
# define UNIX_PATH_MAX 108
|
||||
/* !checksrc! disable TYPEDEFSTRUCT 1 */
|
||||
typedef struct sockaddr_un {
|
||||
ADDRESS_FAMILY sun_family;
|
||||
char sun_path[UNIX_PATH_MAX];
|
||||
} SOCKADDR_UN, *PSOCKADDR_UN;
|
||||
# define WIN32_SOCKADDR_UN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* OpenSSLv3 marks DES, MD5 and ENGINE functions deprecated but we have no
|
||||
replacements (yet) so tell the compiler to not warn for them. */
|
||||
#ifdef USE_OPENSSL
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#if defined(inline)
|
||||
/* 'inline' is defined as macro and assumed to be correct */
|
||||
/* No need for 'inline' replacement */
|
||||
#elif defined(__cplusplus)
|
||||
/* The code is compiled with C++ compiler.
|
||||
C++ always supports 'inline'. */
|
||||
/* No need for 'inline' replacement */
|
||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901
|
||||
/* C99 (and later) supports 'inline' keyword */
|
||||
/* No need for 'inline' replacement */
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 3
|
||||
/* GCC supports '__inline__' as an extension */
|
||||
# define inline __inline__
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
/* MSC supports '__inline' from VS 2005 (or even earlier) */
|
||||
# define inline __inline
|
||||
#else
|
||||
/* Probably 'inline' is not supported by compiler.
|
||||
Define to the empty string to be on the safe side. */
|
||||
# define inline /* empty */
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
403
third_party/curl/lib/curl_setup_once.h
vendored
Normal file
403
third_party/curl/lib/curl_setup_once.h
vendored
Normal file
@ -0,0 +1,403 @@
|
||||
#ifndef HEADER_CURL_SETUP_ONCE_H
|
||||
#define HEADER_CURL_SETUP_ONCE_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
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Inclusion of common header files.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_WOLFSSL
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SCHANNEL
|
||||
/* Must set this before <schannel.h> is included directly or indirectly by
|
||||
another Windows header. */
|
||||
#define SCHANNEL_USE_BLACKLISTS 1
|
||||
#endif
|
||||
|
||||
#ifdef __hpux
|
||||
#if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
|
||||
#ifdef _APP32_64BIT_OFF_T
|
||||
#define OLD_APP32_64BIT_OFF_T _APP32_64BIT_OFF_T
|
||||
#undef _APP32_64BIT_OFF_T
|
||||
#else
|
||||
#undef OLD_APP32_64BIT_OFF_T
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "functypes.h"
|
||||
|
||||
#ifdef __hpux
|
||||
#if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
|
||||
#ifdef OLD_APP32_64BIT_OFF_T
|
||||
#define _APP32_64BIT_OFF_T OLD_APP32_64BIT_OFF_T
|
||||
#undef OLD_APP32_64BIT_OFF_T
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definition of timeval struct for platforms that don't have it.
|
||||
*/
|
||||
|
||||
#ifdef __GLIBC__
|
||||
#if !defined(_POSIX_C_SOURCE) && !defined(_POSIX_SOURCE)
|
||||
#ifndef HAVE_STRUCT_TIMEVAL
|
||||
struct timeval {
|
||||
long tv_sec;
|
||||
long tv_usec;
|
||||
};
|
||||
#endif
|
||||
#endif // _POSIX_C_SOURCE
|
||||
#endif // __GLIBC__
|
||||
|
||||
/*
|
||||
* If we have the MSG_NOSIGNAL define, make sure we use
|
||||
* it as the fourth argument of function send()
|
||||
*/
|
||||
|
||||
#ifdef HAVE_MSG_NOSIGNAL
|
||||
#define SEND_4TH_ARG MSG_NOSIGNAL
|
||||
#else
|
||||
#define SEND_4TH_ARG 0
|
||||
#endif
|
||||
|
||||
#if defined(__minix)
|
||||
/* Minix doesn't support recv on TCP sockets */
|
||||
#define sread(x, y, z) \
|
||||
(ssize_t) read((RECV_TYPE_ARG1)(x), (RECV_TYPE_ARG2)(y), (RECV_TYPE_ARG3)(z))
|
||||
|
||||
#elif defined(HAVE_RECV)
|
||||
/*
|
||||
* The definitions for the return type and arguments types
|
||||
* of functions recv() and send() belong and come from the
|
||||
* configuration file. Do not define them in any other place.
|
||||
*
|
||||
* HAVE_RECV is defined if you have a function named recv()
|
||||
* which is used to read incoming data from sockets. If your
|
||||
* function has another name then don't define HAVE_RECV.
|
||||
*
|
||||
* If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
|
||||
* RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
|
||||
* be defined.
|
||||
*
|
||||
* HAVE_SEND is defined if you have a function named send()
|
||||
* which is used to write outgoing data on a connected socket.
|
||||
* If yours has another name then don't define HAVE_SEND.
|
||||
*
|
||||
* If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
|
||||
* SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
|
||||
* SEND_TYPE_RETV must also be defined.
|
||||
*/
|
||||
|
||||
#define sread(x, y, z) \
|
||||
(ssize_t) recv((RECV_TYPE_ARG1)(x), (RECV_TYPE_ARG2)(y), \
|
||||
(RECV_TYPE_ARG3)(z), (RECV_TYPE_ARG4)(0))
|
||||
#else /* HAVE_RECV */
|
||||
#ifndef sread
|
||||
#error "Missing definition of macro sread!"
|
||||
#endif
|
||||
#endif /* HAVE_RECV */
|
||||
|
||||
#if defined(__minix)
|
||||
/* Minix doesn't support send on TCP sockets */
|
||||
#define swrite(x, y, z) \
|
||||
(ssize_t) write((SEND_TYPE_ARG1)(x), (SEND_TYPE_ARG2)(y), (SEND_TYPE_ARG3)(z))
|
||||
|
||||
#elif defined(HAVE_SEND)
|
||||
#define swrite(x, y, z) \
|
||||
(ssize_t) send((SEND_TYPE_ARG1)(x), (SEND_QUAL_ARG2 SEND_TYPE_ARG2)(y), \
|
||||
(SEND_TYPE_ARG3)(z), (SEND_TYPE_ARG4)(SEND_4TH_ARG))
|
||||
#else /* HAVE_SEND */
|
||||
#ifndef swrite
|
||||
#error "Missing definition of macro swrite!"
|
||||
#endif
|
||||
#endif /* HAVE_SEND */
|
||||
|
||||
/*
|
||||
* Function-like macro definition used to close a socket.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CLOSESOCKET)
|
||||
#define sclose(x) closesocket((x))
|
||||
#elif defined(HAVE_CLOSESOCKET_CAMEL)
|
||||
#define sclose(x) CloseSocket((x))
|
||||
#elif defined(HAVE_CLOSE_S)
|
||||
#define sclose(x) close_s((x))
|
||||
#elif defined(USE_LWIPSOCK)
|
||||
#define sclose(x) lwip_close((x))
|
||||
#else
|
||||
#define sclose(x) close((x))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Stack-independent version of fcntl() on sockets:
|
||||
*/
|
||||
#if defined(USE_LWIPSOCK)
|
||||
#define sfcntl lwip_fcntl
|
||||
#else
|
||||
#define sfcntl fcntl
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 'bool' stuff compatible with HP-UX headers.
|
||||
*/
|
||||
|
||||
#if defined(__hpux) && !defined(HAVE_BOOL_T)
|
||||
typedef int bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
#define HAVE_BOOL_T
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 'bool' exists on platforms with <stdbool.h>, i.e. C99 platforms.
|
||||
* On non-C99 platforms there's no bool, so define an enum for that.
|
||||
* On C99 platforms 'false' and 'true' also exist. Enum uses a
|
||||
* global namespace though, so use bool_false and bool_true.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_BOOL_T
|
||||
typedef enum { bool_false = 0, bool_true = 1 } bool;
|
||||
|
||||
/*
|
||||
* Use a define to let 'true' and 'false' use those enums. There
|
||||
* are currently no use of true and false in libcurl proper, but
|
||||
* there are some in the examples. This will cater for any later
|
||||
* code happening to use true and false.
|
||||
*/
|
||||
#define false bool_false
|
||||
#define true bool_true
|
||||
#define HAVE_BOOL_T
|
||||
#endif
|
||||
|
||||
/* the type we use for storing a single boolean bit */
|
||||
#ifdef _MSC_VER
|
||||
typedef bool bit;
|
||||
#define BIT(x) bool x
|
||||
#else
|
||||
typedef unsigned int bit;
|
||||
#define BIT(x) bit x : 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Redefine TRUE and FALSE too, to catch current use. With this
|
||||
* change, 'bool found = 1' will give a warning on MIPSPro, but
|
||||
* 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro,
|
||||
* AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too.
|
||||
*/
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE true
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
#include "curl_ctype.h"
|
||||
|
||||
/*
|
||||
* Macro used to include code only in debug builds.
|
||||
*/
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define DEBUGF(x) x
|
||||
#else
|
||||
#define DEBUGF(x) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro used to include assertion code only in debug builds.
|
||||
*/
|
||||
|
||||
#undef DEBUGASSERT
|
||||
#if defined(DEBUGBUILD)
|
||||
#define DEBUGASSERT(x) assert(x)
|
||||
#else
|
||||
#define DEBUGASSERT(x) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno
|
||||
* (or equivalent) on this platform to hide platform details to code using it.
|
||||
*/
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
#define SOCKERRNO ((int)WSAGetLastError())
|
||||
#define SET_SOCKERRNO(x) (WSASetLastError((int)(x)))
|
||||
#else
|
||||
#define SOCKERRNO (errno)
|
||||
#define SET_SOCKERRNO(x) (errno = (x))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Portable error number symbolic names defined to Winsock error codes.
|
||||
*/
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
#undef EBADF /* override definition in errno.h */
|
||||
#define EBADF WSAEBADF
|
||||
#undef EINTR /* override definition in errno.h */
|
||||
#define EINTR WSAEINTR
|
||||
#undef EINVAL /* override definition in errno.h */
|
||||
#define EINVAL WSAEINVAL
|
||||
#undef EWOULDBLOCK /* override definition in errno.h */
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#undef EINPROGRESS /* override definition in errno.h */
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#undef EALREADY /* override definition in errno.h */
|
||||
#define EALREADY WSAEALREADY
|
||||
#undef ENOTSOCK /* override definition in errno.h */
|
||||
#define ENOTSOCK WSAENOTSOCK
|
||||
#undef EDESTADDRREQ /* override definition in errno.h */
|
||||
#define EDESTADDRREQ WSAEDESTADDRREQ
|
||||
#undef EMSGSIZE /* override definition in errno.h */
|
||||
#define EMSGSIZE WSAEMSGSIZE
|
||||
#undef EPROTOTYPE /* override definition in errno.h */
|
||||
#define EPROTOTYPE WSAEPROTOTYPE
|
||||
#undef ENOPROTOOPT /* override definition in errno.h */
|
||||
#define ENOPROTOOPT WSAENOPROTOOPT
|
||||
#undef EPROTONOSUPPORT /* override definition in errno.h */
|
||||
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
|
||||
#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
|
||||
#undef EOPNOTSUPP /* override definition in errno.h */
|
||||
#define EOPNOTSUPP WSAEOPNOTSUPP
|
||||
#define EPFNOSUPPORT WSAEPFNOSUPPORT
|
||||
#undef EAFNOSUPPORT /* override definition in errno.h */
|
||||
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||
#undef EADDRINUSE /* override definition in errno.h */
|
||||
#define EADDRINUSE WSAEADDRINUSE
|
||||
#undef EADDRNOTAVAIL /* override definition in errno.h */
|
||||
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
|
||||
#undef ENETDOWN /* override definition in errno.h */
|
||||
#define ENETDOWN WSAENETDOWN
|
||||
#undef ENETUNREACH /* override definition in errno.h */
|
||||
#define ENETUNREACH WSAENETUNREACH
|
||||
#undef ENETRESET /* override definition in errno.h */
|
||||
#define ENETRESET WSAENETRESET
|
||||
#undef ECONNABORTED /* override definition in errno.h */
|
||||
#define ECONNABORTED WSAECONNABORTED
|
||||
#undef ECONNRESET /* override definition in errno.h */
|
||||
#define ECONNRESET WSAECONNRESET
|
||||
#undef ENOBUFS /* override definition in errno.h */
|
||||
#define ENOBUFS WSAENOBUFS
|
||||
#undef EISCONN /* override definition in errno.h */
|
||||
#define EISCONN WSAEISCONN
|
||||
#undef ENOTCONN /* override definition in errno.h */
|
||||
#define ENOTCONN WSAENOTCONN
|
||||
#define ESHUTDOWN WSAESHUTDOWN
|
||||
#define ETOOMANYREFS WSAETOOMANYREFS
|
||||
#undef ETIMEDOUT /* override definition in errno.h */
|
||||
#define ETIMEDOUT WSAETIMEDOUT
|
||||
#undef ECONNREFUSED /* override definition in errno.h */
|
||||
#define ECONNREFUSED WSAECONNREFUSED
|
||||
#undef ELOOP /* override definition in errno.h */
|
||||
#define ELOOP WSAELOOP
|
||||
#ifndef ENAMETOOLONG /* possible previous definition in errno.h */
|
||||
#define ENAMETOOLONG WSAENAMETOOLONG
|
||||
#endif
|
||||
#define EHOSTDOWN WSAEHOSTDOWN
|
||||
#undef EHOSTUNREACH /* override definition in errno.h */
|
||||
#define EHOSTUNREACH WSAEHOSTUNREACH
|
||||
#ifndef ENOTEMPTY /* possible previous definition in errno.h */
|
||||
#define ENOTEMPTY WSAENOTEMPTY
|
||||
#endif
|
||||
#define EPROCLIM WSAEPROCLIM
|
||||
#define EUSERS WSAEUSERS
|
||||
#define EDQUOT WSAEDQUOT
|
||||
#define ESTALE WSAESTALE
|
||||
#define EREMOTE WSAEREMOTE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro argv_item_t hides platform details to code using it.
|
||||
*/
|
||||
|
||||
#ifdef __VMS
|
||||
#define argv_item_t __char_ptr32
|
||||
#elif defined(_UNICODE)
|
||||
#define argv_item_t wchar_t *
|
||||
#else
|
||||
#define argv_item_t char *
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We use this ZERO_NULL to avoid picky compiler warnings,
|
||||
* when assigning a NULL pointer to a function pointer var.
|
||||
*/
|
||||
|
||||
#define ZERO_NULL 0
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_ONCE_H */
|
50
third_party/curl/lib/curl_sha256.h
vendored
Normal file
50
third_party/curl/lib/curl_sha256.h
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef HEADER_CURL_SHA256_H
|
||||
#define HEADER_CURL_SHA256_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Florin Petriuc, <petriuc.florin@gmail.com>
|
||||
* 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 !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) \
|
||||
|| defined(USE_LIBSSH2)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_hmac.h"
|
||||
|
||||
extern const struct HMAC_params Curl_HMAC_SHA256[1];
|
||||
|
||||
#ifdef USE_WOLFSSL
|
||||
/* SHA256_DIGEST_LENGTH is an enum value in wolfSSL. Need to import it from
|
||||
* sha.h */
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/openssl/sha.h>
|
||||
#else
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#endif
|
||||
|
||||
CURLcode Curl_sha256it(unsigned char *outbuffer, const unsigned char *input,
|
||||
const size_t len);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SHA256_H */
|
850
third_party/curl/lib/curl_sha512_256.c
vendored
Normal file
850
third_party/curl/lib/curl_sha512_256.c
vendored
Normal file
@ -0,0 +1,850 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Evgeny Grin (Karlson2k), <k2k@narod.ru>.
|
||||
*
|
||||
* 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_DIGEST_AUTH) && !defined(CURL_DISABLE_SHA512_256)
|
||||
|
||||
#include "curl_sha512_256.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The recommended order of the TLS backends:
|
||||
* * OpenSSL
|
||||
* * GnuTLS
|
||||
* * wolfSSL
|
||||
* * Schannel SSPI
|
||||
* * SecureTransport (Darwin)
|
||||
* * mbedTLS
|
||||
* * BearSSL
|
||||
* * rustls
|
||||
* Skip the backend if it does not support the required algorithm */
|
||||
|
||||
#if defined(USE_OPENSSL)
|
||||
# include <openssl/opensslv.h>
|
||||
# if (!defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
defined(OPENSSL_VERSION_NUMBER) && \
|
||||
(OPENSSL_VERSION_NUMBER >= 0x10101000L)) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
(LIBRESSL_VERSION_NUMBER >= 0x3080000fL))
|
||||
# include <openssl/opensslconf.h>
|
||||
# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
|
||||
# include <openssl/evp.h>
|
||||
# define USE_OPENSSL_SHA512_256 1
|
||||
# define HAS_SHA512_256_IMPLEMENTATION 1
|
||||
# ifdef __NetBSD__
|
||||
/* Some NetBSD versions has a bug in SHA-512/256.
|
||||
* See https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039
|
||||
* The problematic versions:
|
||||
* - NetBSD before 9.4
|
||||
* - NetBSD 9 all development versions (9.99.x)
|
||||
* - NetBSD 10 development versions (10.99.x) before 10.99.11
|
||||
* The bug was fixed in NetBSD 9.4 release, NetBSD 10.0 release,
|
||||
* NetBSD 10.99.11 development.
|
||||
* It is safe to apply the workaround even if the bug is not present, as
|
||||
* the workaround just reduces performance slightly. */
|
||||
# include <sys/param.h>
|
||||
# if __NetBSD_Version__ < 904000000 || \
|
||||
(__NetBSD_Version__ >= 999000000 && \
|
||||
__NetBSD_Version__ < 1000000000) || \
|
||||
(__NetBSD_Version__ >= 1099000000 && \
|
||||
__NetBSD_Version__ < 1099001100)
|
||||
# define NEED_NETBSD_SHA512_256_WORKAROUND 1
|
||||
# include <string.h>
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
|
||||
#if !defined(HAS_SHA512_256_IMPLEMENTATION) && defined(USE_GNUTLS)
|
||||
# include <nettle/sha.h>
|
||||
# if defined(SHA512_256_DIGEST_SIZE)
|
||||
# define USE_GNUTLS_SHA512_256 1
|
||||
# define HAS_SHA512_256_IMPLEMENTATION 1
|
||||
# endif
|
||||
#endif /* ! HAS_SHA512_256_IMPLEMENTATION && USE_GNUTLS */
|
||||
|
||||
#if defined(USE_OPENSSL_SHA512_256)
|
||||
|
||||
/* OpenSSL does not provide macros for SHA-512/256 sizes */
|
||||
|
||||
/**
|
||||
* Size of the SHA-512/256 single processing block in bytes.
|
||||
*/
|
||||
#define SHA512_256_BLOCK_SIZE 128
|
||||
|
||||
/**
|
||||
* Size of the SHA-512/256 resulting digest in bytes.
|
||||
* This is the final digest size, not intermediate hash.
|
||||
*/
|
||||
#define SHA512_256_DIGEST_SIZE SHA512_256_DIGEST_LENGTH
|
||||
|
||||
/**
|
||||
* Context type used for SHA-512/256 calculations
|
||||
*/
|
||||
typedef EVP_MD_CTX *Curl_sha512_256_ctx;
|
||||
|
||||
/**
|
||||
* Initialise structure for SHA-512/256 calculation.
|
||||
*
|
||||
* @param context the calculation context
|
||||
* @return CURLE_OK if succeed,
|
||||
* error code otherwise
|
||||
*/
|
||||
static CURLcode
|
||||
Curl_sha512_256_init(void *context)
|
||||
{
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
*ctx = EVP_MD_CTX_create();
|
||||
if(!*ctx)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(EVP_DigestInit_ex(*ctx, EVP_sha512_256(), NULL)) {
|
||||
/* Check whether the header and this file use the same numbers */
|
||||
DEBUGASSERT(EVP_MD_CTX_size(*ctx) == SHA512_256_DIGEST_SIZE);
|
||||
/* Check whether the block size is correct */
|
||||
DEBUGASSERT(EVP_MD_CTX_block_size(*ctx) == SHA512_256_BLOCK_SIZE);
|
||||
|
||||
return CURLE_OK; /* Success */
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
EVP_MD_CTX_destroy(*ctx);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process portion of bytes.
|
||||
*
|
||||
* @param context the calculation context
|
||||
* @param data bytes to add to hash
|
||||
* @return CURLE_OK if succeed,
|
||||
* error code otherwise
|
||||
*/
|
||||
static CURLcode
|
||||
Curl_sha512_256_update(void *context,
|
||||
const unsigned char *data,
|
||||
size_t length)
|
||||
{
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
if(!EVP_DigestUpdate(*ctx, data, length))
|
||||
return CURLE_SSL_CIPHER;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finalise SHA-512/256 calculation, return digest.
|
||||
*
|
||||
* @param context the calculation context
|
||||
* @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes
|
||||
* @return CURLE_OK if succeed,
|
||||
* error code otherwise
|
||||
*/
|
||||
static CURLcode
|
||||
Curl_sha512_256_finish(unsigned char *digest,
|
||||
void *context)
|
||||
{
|
||||
CURLcode ret;
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
#ifdef NEED_NETBSD_SHA512_256_WORKAROUND
|
||||
/* Use a larger buffer to work around a bug in NetBSD:
|
||||
https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039 */
|
||||
unsigned char tmp_digest[SHA512_256_DIGEST_SIZE * 2];
|
||||
ret = EVP_DigestFinal_ex(*ctx,
|
||||
tmp_digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER;
|
||||
if(ret == CURLE_OK)
|
||||
memcpy(digest, tmp_digest, SHA512_256_DIGEST_SIZE);
|
||||
explicit_memset(tmp_digest, 0, sizeof(tmp_digest));
|
||||
#else /* ! NEED_NETBSD_SHA512_256_WORKAROUND */
|
||||
ret = EVP_DigestFinal_ex(*ctx, digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER;
|
||||
#endif /* ! NEED_NETBSD_SHA512_256_WORKAROUND */
|
||||
|
||||
EVP_MD_CTX_destroy(*ctx);
|
||||
*ctx = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(USE_GNUTLS_SHA512_256)
|
||||
|
||||
/**
|
||||
* Context type used for SHA-512/256 calculations
|
||||
*/
|
||||
typedef struct sha512_256_ctx Curl_sha512_256_ctx;
|
||||
|
||||
/**
|
||||
* Initialise structure for SHA-512/256 calculation.
|
||||
*
|
||||
* @param context the calculation context
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode
|
||||
Curl_sha512_256_init(void *context)
|
||||
{
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
/* Check whether the header and this file use the same numbers */
|
||||
DEBUGASSERT(SHA512_256_DIGEST_LENGTH == SHA512_256_DIGEST_SIZE);
|
||||
|
||||
sha512_256_init(ctx);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process portion of bytes.
|
||||
*
|
||||
* @param context the calculation context
|
||||
* @param data bytes to add to hash
|
||||
* @param length number of bytes in @a data
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode
|
||||
Curl_sha512_256_update(void *context,
|
||||
const unsigned char *data,
|
||||
size_t length)
|
||||
{
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
DEBUGASSERT((data != NULL) || (length == 0));
|
||||
|
||||
sha512_256_update(ctx, length, (const uint8_t *)data);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finalise SHA-512/256 calculation, return digest.
|
||||
*
|
||||
* @param context the calculation context
|
||||
* @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode
|
||||
Curl_sha512_256_finish(unsigned char *digest,
|
||||
void *context)
|
||||
{
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
sha512_256_digest(ctx, (size_t)SHA512_256_DIGEST_SIZE, (uint8_t *)digest);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#else /* No system or TLS backend SHA-512/256 implementation available */
|
||||
|
||||
/* Use local implementation */
|
||||
#define HAS_SHA512_256_IMPLEMENTATION 1
|
||||
|
||||
/* ** This implementation of SHA-512/256 hash calculation was originally ** *
|
||||
* ** written by Evgeny Grin (Karlson2k) for GNU libmicrohttpd. ** *
|
||||
* ** The author ported the code to libcurl. The ported code is provided ** *
|
||||
* ** under curl license. ** *
|
||||
* ** This is a minimal version with minimal optimisations. Performance ** *
|
||||
* ** can be significantly improved. Big-endian store and load macros ** *
|
||||
* ** are obvious targets for optimisation. ** */
|
||||
|
||||
#ifdef __GNUC__
|
||||
# if defined(__has_attribute) && defined(__STDC_VERSION__)
|
||||
# if __has_attribute(always_inline) && __STDC_VERSION__ >= 199901
|
||||
# define MHDX_INLINE inline __attribute__((always_inline))
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(MHDX_INLINE) && \
|
||||
defined(_MSC_VER) && !defined(__GNUC__) && !defined(__clang__)
|
||||
# if _MSC_VER >= 1400
|
||||
# define MHDX_INLINE __forceinline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(MHDX_INLINE)
|
||||
/* Assume that 'inline' keyword works or the
|
||||
* macro was already defined correctly. */
|
||||
# define MHDX_INLINE inline
|
||||
#endif
|
||||
|
||||
/* Bits manipulation macros and functions.
|
||||
Can be moved to other headers to reuse. */
|
||||
|
||||
#define MHDX_GET_64BIT_BE(ptr) \
|
||||
( ((curl_uint64_t)(((const unsigned char*)(ptr))[0]) << 56) | \
|
||||
((curl_uint64_t)(((const unsigned char*)(ptr))[1]) << 48) | \
|
||||
((curl_uint64_t)(((const unsigned char*)(ptr))[2]) << 40) | \
|
||||
((curl_uint64_t)(((const unsigned char*)(ptr))[3]) << 32) | \
|
||||
((curl_uint64_t)(((const unsigned char*)(ptr))[4]) << 24) | \
|
||||
((curl_uint64_t)(((const unsigned char*)(ptr))[5]) << 16) | \
|
||||
((curl_uint64_t)(((const unsigned char*)(ptr))[6]) << 8) | \
|
||||
(curl_uint64_t)(((const unsigned char*)(ptr))[7]) )
|
||||
|
||||
#define MHDX_PUT_64BIT_BE(ptr,val) do { \
|
||||
((unsigned char*)(ptr))[7]=(unsigned char)((curl_uint64_t)(val)); \
|
||||
((unsigned char*)(ptr))[6]=(unsigned char)(((curl_uint64_t)(val)) >> 8); \
|
||||
((unsigned char*)(ptr))[5]=(unsigned char)(((curl_uint64_t)(val)) >> 16); \
|
||||
((unsigned char*)(ptr))[4]=(unsigned char)(((curl_uint64_t)(val)) >> 24); \
|
||||
((unsigned char*)(ptr))[3]=(unsigned char)(((curl_uint64_t)(val)) >> 32); \
|
||||
((unsigned char*)(ptr))[2]=(unsigned char)(((curl_uint64_t)(val)) >> 40); \
|
||||
((unsigned char*)(ptr))[1]=(unsigned char)(((curl_uint64_t)(val)) >> 48); \
|
||||
((unsigned char*)(ptr))[0]=(unsigned char)(((curl_uint64_t)(val)) >> 56); \
|
||||
} while(0)
|
||||
|
||||
/* Defined as a function. The macro version may duplicate the binary code
|
||||
* size as each argument is used twice, so if any calculation is used
|
||||
* as an argument, the calculation could be done twice. */
|
||||
static MHDX_INLINE curl_uint64_t
|
||||
MHDx_rotr64(curl_uint64_t value, unsigned int bits)
|
||||
{
|
||||
bits %= 64;
|
||||
if(0 == bits)
|
||||
return value;
|
||||
/* Defined in a form which modern compiler could optimise. */
|
||||
return (value >> bits) | (value << (64 - bits));
|
||||
}
|
||||
|
||||
/* SHA-512/256 specific data */
|
||||
|
||||
/**
|
||||
* Number of bits in a single SHA-512/256 word.
|
||||
*/
|
||||
#define SHA512_256_WORD_SIZE_BITS 64
|
||||
|
||||
/**
|
||||
* Number of bytes in a single SHA-512/256 word.
|
||||
*/
|
||||
#define SHA512_256_BYTES_IN_WORD (SHA512_256_WORD_SIZE_BITS / 8)
|
||||
|
||||
/**
|
||||
* Hash is kept internally as 8 64-bit words.
|
||||
* This is the intermediate hash size, used during computing the final digest.
|
||||
*/
|
||||
#define SHA512_256_HASH_SIZE_WORDS 8
|
||||
|
||||
/**
|
||||
* Size of the SHA-512/256 resulting digest in words.
|
||||
* This is the final digest size, not intermediate hash.
|
||||
*/
|
||||
#define SHA512_256_DIGEST_SIZE_WORDS (SHA512_256_HASH_SIZE_WORDS / 2)
|
||||
|
||||
/**
|
||||
* Size of the SHA-512/256 resulting digest in bytes
|
||||
* This is the final digest size, not intermediate hash.
|
||||
*/
|
||||
#define SHA512_256_DIGEST_SIZE \
|
||||
(SHA512_256_DIGEST_SIZE_WORDS * SHA512_256_BYTES_IN_WORD)
|
||||
|
||||
/**
|
||||
* Size of the SHA-512/256 single processing block in bits.
|
||||
*/
|
||||
#define SHA512_256_BLOCK_SIZE_BITS 1024
|
||||
|
||||
/**
|
||||
* Size of the SHA-512/256 single processing block in bytes.
|
||||
*/
|
||||
#define SHA512_256_BLOCK_SIZE (SHA512_256_BLOCK_SIZE_BITS / 8)
|
||||
|
||||
/**
|
||||
* Size of the SHA-512/256 single processing block in words.
|
||||
*/
|
||||
#define SHA512_256_BLOCK_SIZE_WORDS \
|
||||
(SHA512_256_BLOCK_SIZE_BITS / SHA512_256_WORD_SIZE_BITS)
|
||||
|
||||
/**
|
||||
* SHA-512/256 calculation context
|
||||
*/
|
||||
struct mhdx_sha512_256ctx
|
||||
{
|
||||
/**
|
||||
* Intermediate hash value. The variable is properly aligned. Smart
|
||||
* compilers may automatically use fast load/store instruction for big
|
||||
* endian data on little endian machine.
|
||||
*/
|
||||
curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS];
|
||||
/**
|
||||
* SHA-512/256 input data buffer. The buffer is properly aligned. Smart
|
||||
* compilers may automatically use fast load/store instruction for big
|
||||
* endian data on little endian machine.
|
||||
*/
|
||||
curl_uint64_t buffer[SHA512_256_BLOCK_SIZE_WORDS];
|
||||
/**
|
||||
* The number of bytes, lower part
|
||||
*/
|
||||
curl_uint64_t count;
|
||||
/**
|
||||
* The number of bits, high part. Unlike lower part, this counts the number
|
||||
* of bits, not bytes.
|
||||
*/
|
||||
curl_uint64_t count_bits_hi;
|
||||
};
|
||||
|
||||
/**
|
||||
* Context type used for SHA-512/256 calculations
|
||||
*/
|
||||
typedef struct mhdx_sha512_256ctx Curl_sha512_256_ctx;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise structure for SHA-512/256 calculation.
|
||||
*
|
||||
* @param context the calculation context
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode
|
||||
MHDx_sha512_256_init(void *context)
|
||||
{
|
||||
struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *) context;
|
||||
|
||||
/* Check whether the header and this file use the same numbers */
|
||||
DEBUGASSERT(SHA512_256_DIGEST_LENGTH == SHA512_256_DIGEST_SIZE);
|
||||
|
||||
DEBUGASSERT(sizeof(curl_uint64_t) == 8);
|
||||
|
||||
/* Initial hash values, see FIPS PUB 180-4 section 5.3.6.2 */
|
||||
/* Values generated by "IV Generation Function" as described in
|
||||
* section 5.3.6 */
|
||||
ctx->H[0] = CURL_UINT64_C(0x22312194FC2BF72C);
|
||||
ctx->H[1] = CURL_UINT64_C(0x9F555FA3C84C64C2);
|
||||
ctx->H[2] = CURL_UINT64_C(0x2393B86B6F53B151);
|
||||
ctx->H[3] = CURL_UINT64_C(0x963877195940EABD);
|
||||
ctx->H[4] = CURL_UINT64_C(0x96283EE2A88EFFE3);
|
||||
ctx->H[5] = CURL_UINT64_C(0xBE5E1E2553863992);
|
||||
ctx->H[6] = CURL_UINT64_C(0x2B0199FC2C85B8AA);
|
||||
ctx->H[7] = CURL_UINT64_C(0x0EB72DDC81C52CA2);
|
||||
|
||||
/* Initialise number of bytes and high part of number of bits. */
|
||||
ctx->count = CURL_UINT64_C(0);
|
||||
ctx->count_bits_hi = CURL_UINT64_C(0);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base of the SHA-512/256 transformation.
|
||||
* Gets a full 128 bytes block of data and updates hash values;
|
||||
* @param H hash values
|
||||
* @param data the data buffer with #SHA512_256_BLOCK_SIZE bytes block
|
||||
*/
|
||||
static void
|
||||
MHDx_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
||||
const void *data)
|
||||
{
|
||||
/* Working variables,
|
||||
see FIPS PUB 180-4 section 6.7, 6.4. */
|
||||
curl_uint64_t a = H[0];
|
||||
curl_uint64_t b = H[1];
|
||||
curl_uint64_t c = H[2];
|
||||
curl_uint64_t d = H[3];
|
||||
curl_uint64_t e = H[4];
|
||||
curl_uint64_t f = H[5];
|
||||
curl_uint64_t g = H[6];
|
||||
curl_uint64_t h = H[7];
|
||||
|
||||
/* Data buffer, used as a cyclic buffer.
|
||||
See FIPS PUB 180-4 section 5.2.2, 6.7, 6.4. */
|
||||
curl_uint64_t W[16];
|
||||
|
||||
/* 'Ch' and 'Maj' macro functions are defined with widely-used optimisation.
|
||||
See FIPS PUB 180-4 formulae 4.8, 4.9. */
|
||||
#define Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) )
|
||||
#define Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
|
||||
|
||||
/* Four 'Sigma' macro functions.
|
||||
See FIPS PUB 180-4 formulae 4.10, 4.11, 4.12, 4.13. */
|
||||
#define SIG0(x) \
|
||||
( MHDx_rotr64((x), 28) ^ MHDx_rotr64((x), 34) ^ MHDx_rotr64((x), 39) )
|
||||
#define SIG1(x) \
|
||||
( MHDx_rotr64((x), 14) ^ MHDx_rotr64((x), 18) ^ MHDx_rotr64((x), 41) )
|
||||
#define sig0(x) \
|
||||
( MHDx_rotr64((x), 1) ^ MHDx_rotr64((x), 8) ^ ((x) >> 7) )
|
||||
#define sig1(x) \
|
||||
( MHDx_rotr64((x), 19) ^ MHDx_rotr64((x), 61) ^ ((x) >> 6) )
|
||||
|
||||
if(1) {
|
||||
unsigned int t;
|
||||
/* K constants array.
|
||||
See FIPS PUB 180-4 section 4.2.3 for K values. */
|
||||
static const curl_uint64_t K[80] = {
|
||||
CURL_UINT64_C(0x428a2f98d728ae22), CURL_UINT64_C(0x7137449123ef65cd),
|
||||
CURL_UINT64_C(0xb5c0fbcfec4d3b2f), CURL_UINT64_C(0xe9b5dba58189dbbc),
|
||||
CURL_UINT64_C(0x3956c25bf348b538), CURL_UINT64_C(0x59f111f1b605d019),
|
||||
CURL_UINT64_C(0x923f82a4af194f9b), CURL_UINT64_C(0xab1c5ed5da6d8118),
|
||||
CURL_UINT64_C(0xd807aa98a3030242), CURL_UINT64_C(0x12835b0145706fbe),
|
||||
CURL_UINT64_C(0x243185be4ee4b28c), CURL_UINT64_C(0x550c7dc3d5ffb4e2),
|
||||
CURL_UINT64_C(0x72be5d74f27b896f), CURL_UINT64_C(0x80deb1fe3b1696b1),
|
||||
CURL_UINT64_C(0x9bdc06a725c71235), CURL_UINT64_C(0xc19bf174cf692694),
|
||||
CURL_UINT64_C(0xe49b69c19ef14ad2), CURL_UINT64_C(0xefbe4786384f25e3),
|
||||
CURL_UINT64_C(0x0fc19dc68b8cd5b5), CURL_UINT64_C(0x240ca1cc77ac9c65),
|
||||
CURL_UINT64_C(0x2de92c6f592b0275), CURL_UINT64_C(0x4a7484aa6ea6e483),
|
||||
CURL_UINT64_C(0x5cb0a9dcbd41fbd4), CURL_UINT64_C(0x76f988da831153b5),
|
||||
CURL_UINT64_C(0x983e5152ee66dfab), CURL_UINT64_C(0xa831c66d2db43210),
|
||||
CURL_UINT64_C(0xb00327c898fb213f), CURL_UINT64_C(0xbf597fc7beef0ee4),
|
||||
CURL_UINT64_C(0xc6e00bf33da88fc2), CURL_UINT64_C(0xd5a79147930aa725),
|
||||
CURL_UINT64_C(0x06ca6351e003826f), CURL_UINT64_C(0x142929670a0e6e70),
|
||||
CURL_UINT64_C(0x27b70a8546d22ffc), CURL_UINT64_C(0x2e1b21385c26c926),
|
||||
CURL_UINT64_C(0x4d2c6dfc5ac42aed), CURL_UINT64_C(0x53380d139d95b3df),
|
||||
CURL_UINT64_C(0x650a73548baf63de), CURL_UINT64_C(0x766a0abb3c77b2a8),
|
||||
CURL_UINT64_C(0x81c2c92e47edaee6), CURL_UINT64_C(0x92722c851482353b),
|
||||
CURL_UINT64_C(0xa2bfe8a14cf10364), CURL_UINT64_C(0xa81a664bbc423001),
|
||||
CURL_UINT64_C(0xc24b8b70d0f89791), CURL_UINT64_C(0xc76c51a30654be30),
|
||||
CURL_UINT64_C(0xd192e819d6ef5218), CURL_UINT64_C(0xd69906245565a910),
|
||||
CURL_UINT64_C(0xf40e35855771202a), CURL_UINT64_C(0x106aa07032bbd1b8),
|
||||
CURL_UINT64_C(0x19a4c116b8d2d0c8), CURL_UINT64_C(0x1e376c085141ab53),
|
||||
CURL_UINT64_C(0x2748774cdf8eeb99), CURL_UINT64_C(0x34b0bcb5e19b48a8),
|
||||
CURL_UINT64_C(0x391c0cb3c5c95a63), CURL_UINT64_C(0x4ed8aa4ae3418acb),
|
||||
CURL_UINT64_C(0x5b9cca4f7763e373), CURL_UINT64_C(0x682e6ff3d6b2b8a3),
|
||||
CURL_UINT64_C(0x748f82ee5defb2fc), CURL_UINT64_C(0x78a5636f43172f60),
|
||||
CURL_UINT64_C(0x84c87814a1f0ab72), CURL_UINT64_C(0x8cc702081a6439ec),
|
||||
CURL_UINT64_C(0x90befffa23631e28), CURL_UINT64_C(0xa4506cebde82bde9),
|
||||
CURL_UINT64_C(0xbef9a3f7b2c67915), CURL_UINT64_C(0xc67178f2e372532b),
|
||||
CURL_UINT64_C(0xca273eceea26619c), CURL_UINT64_C(0xd186b8c721c0c207),
|
||||
CURL_UINT64_C(0xeada7dd6cde0eb1e), CURL_UINT64_C(0xf57d4f7fee6ed178),
|
||||
CURL_UINT64_C(0x06f067aa72176fba), CURL_UINT64_C(0x0a637dc5a2c898a6),
|
||||
CURL_UINT64_C(0x113f9804bef90dae), CURL_UINT64_C(0x1b710b35131c471b),
|
||||
CURL_UINT64_C(0x28db77f523047d84), CURL_UINT64_C(0x32caab7b40c72493),
|
||||
CURL_UINT64_C(0x3c9ebe0a15c9bebc), CURL_UINT64_C(0x431d67c49c100d4c),
|
||||
CURL_UINT64_C(0x4cc5d4becb3e42b6), CURL_UINT64_C(0x597f299cfc657e2a),
|
||||
CURL_UINT64_C(0x5fcb6fab3ad6faec), CURL_UINT64_C(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
/* One step of SHA-512/256 computation,
|
||||
see FIPS PUB 180-4 section 6.4.2 step 3.
|
||||
* Note: this macro updates working variables in-place, without rotation.
|
||||
* Note: the first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in
|
||||
FIPS PUB 180-4 section 6.4.2 step 3.
|
||||
the second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in
|
||||
FIPS PUB 180-4 section 6.4.2 step 3.
|
||||
* Note: 'wt' must be used exactly one time in this macro as macro for
|
||||
'wt' calculation may change other data as well every time when
|
||||
used. */
|
||||
#define SHA2STEP64(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \
|
||||
(vD) += ((vH) += SIG1 ((vE)) + Ch ((vE),(vF),(vG)) + (kt) + (wt)); \
|
||||
(vH) += SIG0 ((vA)) + Maj ((vA),(vB),(vC)); } while (0)
|
||||
|
||||
/* One step of SHA-512/256 computation with working variables rotation,
|
||||
see FIPS PUB 180-4 section 6.4.2 step 3. This macro version reassigns
|
||||
all working variables on each step. */
|
||||
#define SHA2STEP64RV(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \
|
||||
curl_uint64_t tmp_h_ = (vH); \
|
||||
SHA2STEP64((vA),(vB),(vC),(vD),(vE),(vF),(vG),tmp_h_,(kt),(wt)); \
|
||||
(vH) = (vG); \
|
||||
(vG) = (vF); \
|
||||
(vF) = (vE); \
|
||||
(vE) = (vD); \
|
||||
(vD) = (vC); \
|
||||
(vC) = (vB); \
|
||||
(vB) = (vA); \
|
||||
(vA) = tmp_h_; } while(0)
|
||||
|
||||
/* Get value of W(t) from input data buffer for 0 <= t <= 15,
|
||||
See FIPS PUB 180-4 section 6.2.
|
||||
Input data must be read in big-endian bytes order,
|
||||
see FIPS PUB 180-4 section 3.1.2. */
|
||||
#define SHA512_GET_W_FROM_DATA(buf,t) \
|
||||
MHDX_GET_64BIT_BE( \
|
||||
((const unsigned char*) (buf)) + (t) * SHA512_256_BYTES_IN_WORD)
|
||||
|
||||
/* During first 16 steps, before making any calculation on each step, the
|
||||
W element is read from the input data buffer as a big-endian value and
|
||||
stored in the array of W elements. */
|
||||
for(t = 0; t < 16; ++t) {
|
||||
SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t], \
|
||||
W[t] = SHA512_GET_W_FROM_DATA(data, t));
|
||||
}
|
||||
|
||||
/* 'W' generation and assignment for 16 <= t <= 79.
|
||||
See FIPS PUB 180-4 section 6.4.2.
|
||||
As only the last 16 'W' are used in calculations, it is possible to
|
||||
use 16 elements array of W as a cyclic buffer.
|
||||
Note: ((t-16) & 15) have same value as (t & 15) */
|
||||
#define Wgen(w,t) \
|
||||
(curl_uint64_t)( (w)[(t - 16) & 15] + sig1((w)[((t) - 2) & 15]) \
|
||||
+ (w)[((t) - 7) & 15] + sig0((w)[((t) - 15) & 15]) )
|
||||
|
||||
/* During the last 64 steps, before making any calculation on each step,
|
||||
current W element is generated from other W elements of the cyclic
|
||||
buffer and the generated value is stored back in the cyclic buffer. */
|
||||
for(t = 16; t < 80; ++t) {
|
||||
SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t], \
|
||||
W[t & 15] = Wgen(W, t));
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute and store the intermediate hash.
|
||||
See FIPS PUB 180-4 section 6.4.2 step 4. */
|
||||
H[0] += a;
|
||||
H[1] += b;
|
||||
H[2] += c;
|
||||
H[3] += d;
|
||||
H[4] += e;
|
||||
H[5] += f;
|
||||
H[6] += g;
|
||||
H[7] += h;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process portion of bytes.
|
||||
*
|
||||
* @param context the calculation context
|
||||
* @param data bytes to add to hash
|
||||
* @param length number of bytes in @a data
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode
|
||||
MHDx_sha512_256_update(void *context,
|
||||
const unsigned char *data,
|
||||
size_t length)
|
||||
{
|
||||
unsigned int bytes_have; /**< Number of bytes in the context buffer */
|
||||
struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *)context;
|
||||
/* the void pointer here is required to mute Intel compiler warning */
|
||||
void *const ctx_buf = ctx->buffer;
|
||||
|
||||
DEBUGASSERT((data != NULL) || (length == 0));
|
||||
|
||||
if(0 == length)
|
||||
return CURLE_OK; /* Shortcut, do nothing */
|
||||
|
||||
/* Note: (count & (SHA512_256_BLOCK_SIZE-1))
|
||||
equals (count % SHA512_256_BLOCK_SIZE) for this block size. */
|
||||
bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1));
|
||||
ctx->count += length;
|
||||
if(length > ctx->count)
|
||||
ctx->count_bits_hi += 1U << 3; /* Value wrap */
|
||||
ctx->count_bits_hi += ctx->count >> 61;
|
||||
ctx->count &= CURL_UINT64_C(0x1FFFFFFFFFFFFFFF);
|
||||
|
||||
if(0 != bytes_have) {
|
||||
unsigned int bytes_left = SHA512_256_BLOCK_SIZE - bytes_have;
|
||||
if(length >= bytes_left) {
|
||||
/* Combine new data with data in the buffer and process the full
|
||||
block. */
|
||||
memcpy(((unsigned char *) ctx_buf) + bytes_have,
|
||||
data,
|
||||
bytes_left);
|
||||
data += bytes_left;
|
||||
length -= bytes_left;
|
||||
MHDx_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
bytes_have = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while(SHA512_256_BLOCK_SIZE <= length) {
|
||||
/* Process any full blocks of new data directly,
|
||||
without copying to the buffer. */
|
||||
MHDx_sha512_256_transform(ctx->H, data);
|
||||
data += SHA512_256_BLOCK_SIZE;
|
||||
length -= SHA512_256_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if(0 != length) {
|
||||
/* Copy incomplete block of new data (if any)
|
||||
to the buffer. */
|
||||
memcpy(((unsigned char *) ctx_buf) + bytes_have, data, length);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Size of "length" insertion in bits.
|
||||
* See FIPS PUB 180-4 section 5.1.2.
|
||||
*/
|
||||
#define SHA512_256_SIZE_OF_LEN_ADD_BITS 128
|
||||
|
||||
/**
|
||||
* Size of "length" insertion in bytes.
|
||||
*/
|
||||
#define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8)
|
||||
|
||||
/**
|
||||
* Finalise SHA-512/256 calculation, return digest.
|
||||
*
|
||||
* @param context the calculation context
|
||||
* @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode
|
||||
MHDx_sha512_256_finish(unsigned char *digest,
|
||||
void *context)
|
||||
{
|
||||
struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *)context;
|
||||
curl_uint64_t num_bits; /**< Number of processed bits */
|
||||
unsigned int bytes_have; /**< Number of bytes in the context buffer */
|
||||
/* the void pointer here is required to mute Intel compiler warning */
|
||||
void *const ctx_buf = ctx->buffer;
|
||||
|
||||
/* Memorise the number of processed bits.
|
||||
The padding and other data added here during the postprocessing must
|
||||
not change the amount of hashed data. */
|
||||
num_bits = ctx->count << 3;
|
||||
|
||||
/* Note: (count & (SHA512_256_BLOCK_SIZE-1))
|
||||
equals (count % SHA512_256_BLOCK_SIZE) for this block size. */
|
||||
bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1));
|
||||
|
||||
/* Input data must be padded with a single bit "1", then with zeros and
|
||||
the finally the length of data in bits must be added as the final bytes
|
||||
of the last block.
|
||||
See FIPS PUB 180-4 section 5.1.2. */
|
||||
|
||||
/* Data is always processed in form of bytes (not by individual bits),
|
||||
therefore position of the first padding bit in byte is always
|
||||
predefined (0x80). */
|
||||
/* Buffer always have space at least for one byte (as full buffers are
|
||||
processed when formed). */
|
||||
((unsigned char *) ctx_buf)[bytes_have++] = 0x80U;
|
||||
|
||||
if(SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) {
|
||||
/* No space in the current block to put the total length of message.
|
||||
Pad the current block with zeros and process it. */
|
||||
if(bytes_have < SHA512_256_BLOCK_SIZE)
|
||||
memset(((unsigned char *) ctx_buf) + bytes_have, 0,
|
||||
SHA512_256_BLOCK_SIZE - bytes_have);
|
||||
/* Process the full block. */
|
||||
MHDx_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
/* Start the new block. */
|
||||
bytes_have = 0;
|
||||
}
|
||||
|
||||
/* Pad the rest of the buffer with zeros. */
|
||||
memset(((unsigned char *) ctx_buf) + bytes_have, 0,
|
||||
SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have);
|
||||
/* Put high part of number of bits in processed message and then lower
|
||||
part of number of bits as big-endian values.
|
||||
See FIPS PUB 180-4 section 5.1.2. */
|
||||
/* Note: the target location is predefined and buffer is always aligned */
|
||||
MHDX_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
||||
+ SHA512_256_BLOCK_SIZE \
|
||||
- SHA512_256_SIZE_OF_LEN_ADD, \
|
||||
ctx->count_bits_hi);
|
||||
MHDX_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
||||
+ SHA512_256_BLOCK_SIZE \
|
||||
- SHA512_256_SIZE_OF_LEN_ADD \
|
||||
+ SHA512_256_BYTES_IN_WORD, \
|
||||
num_bits);
|
||||
/* Process the full final block. */
|
||||
MHDx_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
|
||||
/* Put in BE mode the leftmost part of the hash as the final digest.
|
||||
See FIPS PUB 180-4 section 6.7. */
|
||||
|
||||
MHDX_PUT_64BIT_BE((digest + 0 * SHA512_256_BYTES_IN_WORD), ctx->H[0]);
|
||||
MHDX_PUT_64BIT_BE((digest + 1 * SHA512_256_BYTES_IN_WORD), ctx->H[1]);
|
||||
MHDX_PUT_64BIT_BE((digest + 2 * SHA512_256_BYTES_IN_WORD), ctx->H[2]);
|
||||
MHDX_PUT_64BIT_BE((digest + 3 * SHA512_256_BYTES_IN_WORD), ctx->H[3]);
|
||||
|
||||
/* Erase potentially sensitive data. */
|
||||
memset(ctx, 0, sizeof(struct mhdx_sha512_256ctx));
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Map to the local implementation */
|
||||
#define Curl_sha512_256_init MHDx_sha512_256_init
|
||||
#define Curl_sha512_256_update MHDx_sha512_256_update
|
||||
#define Curl_sha512_256_finish MHDx_sha512_256_finish
|
||||
|
||||
#endif /* Local SHA-512/256 code */
|
||||
|
||||
|
||||
/**
|
||||
* Compute SHA-512/256 hash for the given data in one function call
|
||||
* @param[out] output the pointer to put the hash
|
||||
* @param[in] input the pointer to the data to process
|
||||
* @param input_size the size of the data pointed by @a input
|
||||
* @return always #CURLE_OK
|
||||
*/
|
||||
CURLcode
|
||||
Curl_sha512_256it(unsigned char *output, const unsigned char *input,
|
||||
size_t input_size)
|
||||
{
|
||||
Curl_sha512_256_ctx ctx;
|
||||
CURLcode res;
|
||||
|
||||
res = Curl_sha512_256_init(&ctx);
|
||||
if(res != CURLE_OK)
|
||||
return res;
|
||||
|
||||
res = Curl_sha512_256_update(&ctx, (const void *) input, input_size);
|
||||
|
||||
if(res != CURLE_OK) {
|
||||
(void) Curl_sha512_256_finish(output, &ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
return Curl_sha512_256_finish(output, &ctx);
|
||||
}
|
||||
|
||||
/* Wrapper function, takes 'unsigned int' as length type, returns void */
|
||||
static void
|
||||
Curl_sha512_256_update_i(void *context,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
/* Hypothetically the function may fail, but assume it does not */
|
||||
(void) Curl_sha512_256_update(context, data, length);
|
||||
}
|
||||
|
||||
/* Wrapper function, returns void */
|
||||
static void
|
||||
Curl_sha512_256_finish_v(unsigned char *result,
|
||||
void *context)
|
||||
{
|
||||
/* Hypothetically the function may fail, but assume it does not */
|
||||
(void) Curl_sha512_256_finish(result, context);
|
||||
}
|
||||
|
||||
/* Wrapper function, takes 'unsigned int' as length type, returns void */
|
||||
|
||||
const struct HMAC_params Curl_HMAC_SHA512_256[] = {
|
||||
{
|
||||
/* Initialize context procedure. */
|
||||
Curl_sha512_256_init,
|
||||
/* Update context with data. */
|
||||
Curl_sha512_256_update_i,
|
||||
/* Get final result procedure. */
|
||||
Curl_sha512_256_finish_v,
|
||||
/* Context structure size. */
|
||||
sizeof(Curl_sha512_256_ctx),
|
||||
/* Maximum key length (bytes). */
|
||||
SHA512_256_BLOCK_SIZE,
|
||||
/* Result length (bytes). */
|
||||
SHA512_256_DIGEST_SIZE
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !CURL_DISABLE_DIGEST_AUTH && !CURL_DISABLE_SHA512_256 */
|
44
third_party/curl/lib/curl_sha512_256.h
vendored
Normal file
44
third_party/curl/lib/curl_sha512_256.h
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef HEADER_CURL_SHA512_256_H
|
||||
#define HEADER_CURL_SHA512_256_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Evgeny Grin (Karlson2k), <k2k@narod.ru>.
|
||||
*
|
||||
* 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 !defined(CURL_DISABLE_DIGEST_AUTH) && !defined(CURL_DISABLE_SHA512_256)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_hmac.h"
|
||||
|
||||
#define CURL_HAVE_SHA512_256
|
||||
|
||||
extern const struct HMAC_params Curl_HMAC_SHA512_256[1];
|
||||
|
||||
#define SHA512_256_DIGEST_LENGTH 32
|
||||
|
||||
CURLcode
|
||||
Curl_sha512_256it(unsigned char *output, const unsigned char *input,
|
||||
size_t input_size);
|
||||
|
||||
#endif /* !CURL_DISABLE_DIGEST_AUTH && !CURL_DISABLE_SHA512_256 */
|
||||
|
||||
#endif /* HEADER_CURL_SHA256_H */
|
239
third_party/curl/lib/curl_sspi.c
vendored
Normal file
239
third_party/curl/lib/curl_sspi.c
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 USE_WINDOWS_SSPI
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_sspi.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "system_win32.h"
|
||||
#include "version_win32.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* We use our own typedef here since some headers might lack these */
|
||||
typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID);
|
||||
|
||||
/* See definition of SECURITY_ENTRYPOINT in sspi.h */
|
||||
#ifdef UNICODE
|
||||
# ifdef _WIN32_WCE
|
||||
# define SECURITYENTRYPOINT L"InitSecurityInterfaceW"
|
||||
# else
|
||||
# define SECURITYENTRYPOINT "InitSecurityInterfaceW"
|
||||
# endif
|
||||
#else
|
||||
# define SECURITYENTRYPOINT "InitSecurityInterfaceA"
|
||||
#endif
|
||||
|
||||
/* Handle of security.dll or secur32.dll, depending on Windows version */
|
||||
HMODULE s_hSecDll = NULL;
|
||||
|
||||
/* Pointer to SSPI dispatch table */
|
||||
PSecurityFunctionTable s_pSecFn = NULL;
|
||||
|
||||
/*
|
||||
* Curl_sspi_global_init()
|
||||
*
|
||||
* This is used to load the Security Service Provider Interface (SSPI)
|
||||
* dynamic link library portably across all Windows versions, without
|
||||
* the need to directly link libcurl, nor the application using it, at
|
||||
* build time.
|
||||
*
|
||||
* Once this function has been executed, Windows SSPI functions can be
|
||||
* called through the Security Service Provider Interface dispatch table.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_sspi_global_init(void)
|
||||
{
|
||||
INITSECURITYINTERFACE_FN pInitSecurityInterface;
|
||||
|
||||
/* If security interface is not yet initialized try to do this */
|
||||
if(!s_hSecDll) {
|
||||
/* Security Service Provider Interface (SSPI) functions are located in
|
||||
* security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP
|
||||
* have both these DLLs (security.dll forwards calls to secur32.dll) */
|
||||
|
||||
/* Load SSPI dll into the address space of the calling process */
|
||||
if(curlx_verify_windows_version(4, 0, 0, PLATFORM_WINNT, VERSION_EQUAL))
|
||||
s_hSecDll = Curl_load_library(TEXT("security.dll"));
|
||||
else
|
||||
s_hSecDll = Curl_load_library(TEXT("secur32.dll"));
|
||||
if(!s_hSecDll)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Get address of the InitSecurityInterfaceA function from the SSPI dll */
|
||||
pInitSecurityInterface =
|
||||
CURLX_FUNCTION_CAST(INITSECURITYINTERFACE_FN,
|
||||
(GetProcAddress(s_hSecDll, SECURITYENTRYPOINT)));
|
||||
if(!pInitSecurityInterface)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Get pointer to Security Service Provider Interface dispatch table */
|
||||
s_pSecFn = pInitSecurityInterface();
|
||||
if(!s_pSecFn)
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sspi_global_cleanup()
|
||||
*
|
||||
* This deinitializes the Security Service Provider Interface from libcurl.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* None.
|
||||
*/
|
||||
void Curl_sspi_global_cleanup(void)
|
||||
{
|
||||
if(s_hSecDll) {
|
||||
FreeLibrary(s_hSecDll);
|
||||
s_hSecDll = NULL;
|
||||
s_pSecFn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_create_sspi_identity()
|
||||
*
|
||||
* This is used to populate a SSPI identity structure based on the supplied
|
||||
* username and password.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* userp [in] - The user name in the format User or Domain\User.
|
||||
* passwdp [in] - The user's password.
|
||||
* identity [in/out] - The identity structure.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity)
|
||||
{
|
||||
xcharp_u useranddomain;
|
||||
xcharp_u user, dup_user;
|
||||
xcharp_u domain, dup_domain;
|
||||
xcharp_u passwd, dup_passwd;
|
||||
size_t domlen = 0;
|
||||
|
||||
domain.const_tchar_ptr = TEXT("");
|
||||
|
||||
/* Initialize the identity */
|
||||
memset(identity, 0, sizeof(*identity));
|
||||
|
||||
useranddomain.tchar_ptr = curlx_convert_UTF8_to_tchar((char *)userp);
|
||||
if(!useranddomain.tchar_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('\\'));
|
||||
if(!user.const_tchar_ptr)
|
||||
user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('/'));
|
||||
|
||||
if(user.tchar_ptr) {
|
||||
domain.tchar_ptr = useranddomain.tchar_ptr;
|
||||
domlen = user.tchar_ptr - useranddomain.tchar_ptr;
|
||||
user.tchar_ptr++;
|
||||
}
|
||||
else {
|
||||
user.tchar_ptr = useranddomain.tchar_ptr;
|
||||
domain.const_tchar_ptr = TEXT("");
|
||||
domlen = 0;
|
||||
}
|
||||
|
||||
/* Setup the identity's user and length */
|
||||
dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
|
||||
if(!dup_user.tchar_ptr) {
|
||||
curlx_unicodefree(useranddomain.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
identity->User = dup_user.tbyte_ptr;
|
||||
identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr));
|
||||
dup_user.tchar_ptr = NULL;
|
||||
|
||||
/* Setup the identity's domain and length */
|
||||
dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1));
|
||||
if(!dup_domain.tchar_ptr) {
|
||||
curlx_unicodefree(useranddomain.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
_tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen);
|
||||
*(dup_domain.tchar_ptr + domlen) = TEXT('\0');
|
||||
identity->Domain = dup_domain.tbyte_ptr;
|
||||
identity->DomainLength = curlx_uztoul(domlen);
|
||||
dup_domain.tchar_ptr = NULL;
|
||||
|
||||
curlx_unicodefree(useranddomain.tchar_ptr);
|
||||
|
||||
/* Setup the identity's password and length */
|
||||
passwd.tchar_ptr = curlx_convert_UTF8_to_tchar((char *)passwdp);
|
||||
if(!passwd.tchar_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
|
||||
if(!dup_passwd.tchar_ptr) {
|
||||
curlx_unicodefree(passwd.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
identity->Password = dup_passwd.tbyte_ptr;
|
||||
identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr));
|
||||
dup_passwd.tchar_ptr = NULL;
|
||||
|
||||
curlx_unicodefree(passwd.tchar_ptr);
|
||||
|
||||
/* Setup the identity's flags */
|
||||
identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sspi_free_identity()
|
||||
*
|
||||
* This is used to free the contents of a SSPI identifier structure.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* identity [in/out] - The identity structure.
|
||||
*/
|
||||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity)
|
||||
{
|
||||
if(identity) {
|
||||
Curl_safefree(identity->User);
|
||||
Curl_safefree(identity->Password);
|
||||
Curl_safefree(identity->Domain);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI */
|
123
third_party/curl/lib/curl_sspi.h
vendored
Normal file
123
third_party/curl/lib/curl_sspi.h
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
#ifndef HEADER_CURL_SSPI_H
|
||||
#define HEADER_CURL_SSPI_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 USE_WINDOWS_SSPI
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* When including the following three headers, it is mandatory to define either
|
||||
* SECURITY_WIN32 or SECURITY_KERNEL, indicating who is compiling the code.
|
||||
*/
|
||||
|
||||
#undef SECURITY_WIN32
|
||||
#undef SECURITY_KERNEL
|
||||
#define SECURITY_WIN32 1
|
||||
#include <security.h>
|
||||
#include <sspi.h>
|
||||
#include <rpc.h>
|
||||
|
||||
CURLcode Curl_sspi_global_init(void);
|
||||
void Curl_sspi_global_cleanup(void);
|
||||
|
||||
/* This is used to populate the domain in a SSPI identity structure */
|
||||
CURLcode Curl_override_sspi_http_realm(const char *chlg,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
|
||||
/* This is used to generate an SSPI identity structure */
|
||||
CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
|
||||
/* This is used to free an SSPI identity structure */
|
||||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
|
||||
/* Forward-declaration of global variables defined in curl_sspi.c */
|
||||
extern HMODULE s_hSecDll;
|
||||
extern PSecurityFunctionTable s_pSecFn;
|
||||
|
||||
/* Provide some definitions missing in old headers */
|
||||
#define SP_NAME_DIGEST "WDigest"
|
||||
#define SP_NAME_NTLM "NTLM"
|
||||
#define SP_NAME_NEGOTIATE "Negotiate"
|
||||
#define SP_NAME_KERBEROS "Kerberos"
|
||||
|
||||
#ifndef ISC_REQ_USE_HTTP_STYLE
|
||||
#define ISC_REQ_USE_HTTP_STYLE 0x01000000
|
||||
#endif
|
||||
|
||||
#ifndef SEC_E_INVALID_PARAMETER
|
||||
# define SEC_E_INVALID_PARAMETER ((HRESULT)0x8009035DL)
|
||||
#endif
|
||||
#ifndef SEC_E_DELEGATION_POLICY
|
||||
# define SEC_E_DELEGATION_POLICY ((HRESULT)0x8009035EL)
|
||||
#endif
|
||||
#ifndef SEC_E_POLICY_NLTM_ONLY
|
||||
# define SEC_E_POLICY_NLTM_ONLY ((HRESULT)0x8009035FL)
|
||||
#endif
|
||||
|
||||
#ifndef SEC_I_SIGNATURE_NEEDED
|
||||
# define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_REVOKED
|
||||
# define CRYPT_E_REVOKED ((HRESULT)0x80092010L)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_NO_REVOCATION_DLL
|
||||
# define CRYPT_E_NO_REVOCATION_DLL ((HRESULT)0x80092011L)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_NO_REVOCATION_CHECK
|
||||
# define CRYPT_E_NO_REVOCATION_CHECK ((HRESULT)0x80092012L)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_REVOCATION_OFFLINE
|
||||
# define CRYPT_E_REVOCATION_OFFLINE ((HRESULT)0x80092013L)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_NOT_IN_REVOCATION_DATABASE
|
||||
# define CRYPT_E_NOT_IN_REVOCATION_DATABASE ((HRESULT)0x80092014L)
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
# define SECFLAG_WINNT_AUTH_IDENTITY \
|
||||
(unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE
|
||||
#else
|
||||
# define SECFLAG_WINNT_AUTH_IDENTITY \
|
||||
(unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definitions required from ntsecapi.h are directly provided below this point
|
||||
* to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h
|
||||
*/
|
||||
#define KERB_WRAP_NO_ENCRYPT 0x80000001
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* HEADER_CURL_SSPI_H */
|
154
third_party/curl/lib/curl_threads.c
vendored
Normal file
154
third_party/curl/lib/curl_threads.c
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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>
|
||||
|
||||
#if defined(USE_THREADS_POSIX)
|
||||
# ifdef HAVE_PTHREAD_H
|
||||
# include <pthread.h>
|
||||
# endif
|
||||
#elif defined(USE_THREADS_WIN32)
|
||||
# include <process.h>
|
||||
#endif
|
||||
|
||||
#include "curl_threads.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(USE_THREADS_POSIX)
|
||||
|
||||
struct Curl_actual_call {
|
||||
unsigned int (*func)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static void *curl_thread_create_thunk(void *arg)
|
||||
{
|
||||
struct Curl_actual_call *ac = arg;
|
||||
unsigned int (*func)(void *) = ac->func;
|
||||
void *real_arg = ac->arg;
|
||||
|
||||
free(ac);
|
||||
|
||||
(*func)(real_arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
curl_thread_t Curl_thread_create(unsigned int (*func) (void *), void *arg)
|
||||
{
|
||||
curl_thread_t t = malloc(sizeof(pthread_t));
|
||||
struct Curl_actual_call *ac = malloc(sizeof(struct Curl_actual_call));
|
||||
if(!(ac && t))
|
||||
goto err;
|
||||
|
||||
ac->func = func;
|
||||
ac->arg = arg;
|
||||
|
||||
if(pthread_create(t, NULL, curl_thread_create_thunk, ac) != 0)
|
||||
goto err;
|
||||
|
||||
return t;
|
||||
|
||||
err:
|
||||
free(t);
|
||||
free(ac);
|
||||
return curl_thread_t_null;
|
||||
}
|
||||
|
||||
void Curl_thread_destroy(curl_thread_t hnd)
|
||||
{
|
||||
if(hnd != curl_thread_t_null) {
|
||||
pthread_detach(*hnd);
|
||||
free(hnd);
|
||||
}
|
||||
}
|
||||
|
||||
int Curl_thread_join(curl_thread_t *hnd)
|
||||
{
|
||||
int ret = (pthread_join(**hnd, NULL) == 0);
|
||||
|
||||
free(*hnd);
|
||||
*hnd = curl_thread_t_null;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(USE_THREADS_WIN32)
|
||||
|
||||
/* !checksrc! disable SPACEBEFOREPAREN 1 */
|
||||
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
|
||||
void *arg)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
typedef HANDLE curl_win_thread_handle_t;
|
||||
#else
|
||||
typedef uintptr_t curl_win_thread_handle_t;
|
||||
#endif
|
||||
curl_thread_t t;
|
||||
curl_win_thread_handle_t thread_handle;
|
||||
#ifdef _WIN32_WCE
|
||||
thread_handle = CreateThread(NULL, 0, func, arg, 0, NULL);
|
||||
#else
|
||||
thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL);
|
||||
#endif
|
||||
t = (curl_thread_t)thread_handle;
|
||||
if((t == 0) || (t == LongToHandle(-1L))) {
|
||||
#ifdef _WIN32_WCE
|
||||
DWORD gle = GetLastError();
|
||||
errno = ((gle == ERROR_ACCESS_DENIED ||
|
||||
gle == ERROR_NOT_ENOUGH_MEMORY) ?
|
||||
EACCES : EINVAL);
|
||||
#endif
|
||||
return curl_thread_t_null;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void Curl_thread_destroy(curl_thread_t hnd)
|
||||
{
|
||||
if(hnd != curl_thread_t_null)
|
||||
CloseHandle(hnd);
|
||||
}
|
||||
|
||||
int Curl_thread_join(curl_thread_t *hnd)
|
||||
{
|
||||
#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_VISTA)
|
||||
int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
|
||||
#else
|
||||
int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
|
||||
#endif
|
||||
|
||||
Curl_thread_destroy(*hnd);
|
||||
|
||||
*hnd = curl_thread_t_null;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* USE_THREADS_* */
|
65
third_party/curl/lib/curl_threads.h
vendored
Normal file
65
third_party/curl/lib/curl_threads.h
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef HEADER_CURL_THREADS_H
|
||||
#define HEADER_CURL_THREADS_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(USE_THREADS_POSIX)
|
||||
# define CURL_STDCALL
|
||||
# define curl_mutex_t pthread_mutex_t
|
||||
# define curl_thread_t pthread_t *
|
||||
# define curl_thread_t_null (pthread_t *)0
|
||||
# define Curl_mutex_init(m) pthread_mutex_init(m, NULL)
|
||||
# define Curl_mutex_acquire(m) pthread_mutex_lock(m)
|
||||
# define Curl_mutex_release(m) pthread_mutex_unlock(m)
|
||||
# define Curl_mutex_destroy(m) pthread_mutex_destroy(m)
|
||||
#elif defined(USE_THREADS_WIN32)
|
||||
# define CURL_STDCALL __stdcall
|
||||
# define curl_mutex_t CRITICAL_SECTION
|
||||
# define curl_thread_t HANDLE
|
||||
# define curl_thread_t_null (HANDLE)0
|
||||
# if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_VISTA)
|
||||
# define Curl_mutex_init(m) InitializeCriticalSection(m)
|
||||
# else
|
||||
# define Curl_mutex_init(m) InitializeCriticalSectionEx(m, 0, 1)
|
||||
# endif
|
||||
# define Curl_mutex_acquire(m) EnterCriticalSection(m)
|
||||
# define Curl_mutex_release(m) LeaveCriticalSection(m)
|
||||
# define Curl_mutex_destroy(m) DeleteCriticalSection(m)
|
||||
#endif
|
||||
|
||||
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
|
||||
/* !checksrc! disable SPACEBEFOREPAREN 1 */
|
||||
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
|
||||
void *arg);
|
||||
|
||||
void Curl_thread_destroy(curl_thread_t hnd);
|
||||
|
||||
int Curl_thread_join(curl_thread_t *hnd);
|
||||
|
||||
#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
|
||||
|
||||
#endif /* HEADER_CURL_THREADS_H */
|
331
third_party/curl/lib/curl_trc.c
vendored
Normal file
331
third_party/curl/lib/curl_trc.c
vendored
Normal file
@ -0,0 +1,331 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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_trc.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 "doh.h"
|
||||
#include "http2.h"
|
||||
#include "http_proxy.h"
|
||||
#include "cf-h1-proxy.h"
|
||||
#include "cf-h2-proxy.h"
|
||||
#include "cf-haproxy.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);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
|
||||
/* Curl_infof() is for info message along the way */
|
||||
#define MAXINFO 2048
|
||||
|
||||
static void trc_infof(struct Curl_easy *data, struct curl_trc_feat *feat,
|
||||
const char * const fmt, va_list ap) CURL_PRINTF(3, 0);
|
||||
|
||||
static void trc_infof(struct Curl_easy *data, struct curl_trc_feat *feat,
|
||||
const char * const fmt, va_list ap)
|
||||
{
|
||||
int len = 0;
|
||||
char buffer[MAXINFO + 2];
|
||||
if(feat)
|
||||
len = msnprintf(buffer, MAXINFO, "[%s] ", feat->name);
|
||||
len += mvsnprintf(buffer + len, MAXINFO - len, fmt, ap);
|
||||
buffer[len++] = '\n';
|
||||
buffer[len] = '\0';
|
||||
Curl_debug(data, CURLINFO_TEXT, buffer, len);
|
||||
}
|
||||
|
||||
void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
||||
if(Curl_trc_is_verbose(data)) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
trc_infof(data, data->state.feat, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
DEBUGASSERT(cf);
|
||||
if(Curl_trc_cf_is_verbose(cf, data)) {
|
||||
va_list ap;
|
||||
int len = 0;
|
||||
char buffer[MAXINFO + 2];
|
||||
if(data->state.feat)
|
||||
len += msnprintf(buffer + len, MAXINFO - len, "[%s] ",
|
||||
data->state.feat->name);
|
||||
if(cf->sockindex)
|
||||
len += msnprintf(buffer + len, MAXINFO - len, "[%s-%d] ",
|
||||
cf->cft->name, cf->sockindex);
|
||||
else
|
||||
len += msnprintf(buffer + len, MAXINFO - len, "[%s] ", 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);
|
||||
}
|
||||
}
|
||||
|
||||
struct curl_trc_feat Curl_trc_feat_read = {
|
||||
"READ",
|
||||
CURL_LOG_LVL_NONE,
|
||||
};
|
||||
struct curl_trc_feat Curl_trc_feat_write = {
|
||||
"WRITE",
|
||||
CURL_LOG_LVL_NONE,
|
||||
};
|
||||
|
||||
void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
||||
if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_read)) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
trc_infof(data, &Curl_trc_feat_read, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
||||
if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_write)) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
trc_infof(data, &Curl_trc_feat_write, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
struct curl_trc_feat Curl_trc_feat_ftp = {
|
||||
"FTP",
|
||||
CURL_LOG_LVL_NONE,
|
||||
};
|
||||
|
||||
void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
||||
if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ftp)) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
trc_infof(data, &Curl_trc_feat_ftp, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#endif /* !CURL_DISABLE_FTP */
|
||||
|
||||
static struct curl_trc_feat *trc_feats[] = {
|
||||
&Curl_trc_feat_read,
|
||||
&Curl_trc_feat_write,
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
&Curl_trc_feat_ftp,
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
&Curl_doh_trc,
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
|
||||
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,
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&Curl_cft_ssl_proxy,
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_PROXY)
|
||||
#if !defined(CURL_DISABLE_HTTP)
|
||||
&Curl_cft_h1_proxy,
|
||||
#ifdef USE_NGHTTP2
|
||||
&Curl_cft_h2_proxy,
|
||||
#endif
|
||||
&Curl_cft_http_proxy,
|
||||
#endif /* !CURL_DISABLE_HTTP */
|
||||
&Curl_cft_haproxy,
|
||||
&Curl_cft_socks_proxy,
|
||||
#endif /* !CURL_DISABLE_PROXY */
|
||||
#ifdef USE_HTTP3
|
||||
&Curl_cft_http3,
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
|
||||
&Curl_cft_http_connect,
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
|
||||
CURLcode Curl_trc_opt(const char *config)
|
||||
{
|
||||
char *token, *tok_buf, *tmp;
|
||||
size_t i;
|
||||
int lvl;
|
||||
|
||||
tmp = strdup(config);
|
||||
if(!tmp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
token = strtok_r(tmp, ", ", &tok_buf);
|
||||
while(token) {
|
||||
switch(*token) {
|
||||
case '-':
|
||||
lvl = CURL_LOG_LVL_NONE;
|
||||
++token;
|
||||
break;
|
||||
case '+':
|
||||
lvl = CURL_LOG_LVL_INFO;
|
||||
++token;
|
||||
break;
|
||||
default:
|
||||
lvl = CURL_LOG_LVL_INFO;
|
||||
break;
|
||||
}
|
||||
for(i = 0; cf_types[i]; ++i) {
|
||||
if(strcasecompare(token, "all")) {
|
||||
cf_types[i]->log_level = lvl;
|
||||
}
|
||||
else if(strcasecompare(token, cf_types[i]->name)) {
|
||||
cf_types[i]->log_level = lvl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(i = 0; trc_feats[i]; ++i) {
|
||||
if(strcasecompare(token, "all")) {
|
||||
trc_feats[i]->log_level = lvl;
|
||||
}
|
||||
else if(strcasecompare(token, trc_feats[i]->name)) {
|
||||
trc_feats[i]->log_level = lvl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
token = strtok_r(NULL, ", ", &tok_buf);
|
||||
}
|
||||
free(tmp);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_trc_init(void)
|
||||
{
|
||||
#ifdef DEBUGBUILD
|
||||
/* WIP: we use the auto-init from an env var only in DEBUG builds for
|
||||
* convenience. */
|
||||
const char *config = getenv("CURL_DEBUG");
|
||||
if(config) {
|
||||
return Curl_trc_opt(config);
|
||||
}
|
||||
#endif /* DEBUGBUILD */
|
||||
return CURLE_OK;
|
||||
}
|
||||
#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */
|
||||
|
||||
CURLcode Curl_trc_init(void)
|
||||
{
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */
|
200
third_party/curl/lib/curl_trc.h
vendored
Normal file
200
third_party/curl/lib/curl_trc.h
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
#ifndef HEADER_CURL_TRC_H
|
||||
#define HEADER_CURL_TRC_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_trc_init(void);
|
||||
|
||||
/**
|
||||
* Configure tracing. May be called several times during global
|
||||
* initialization. Later calls may not take effect.
|
||||
*
|
||||
* Configuration format supported:
|
||||
* - comma-separated list of component names to enable logging on.
|
||||
* E.g. 'http/2,ssl'. Unknown names are ignored. Names are compared
|
||||
* case-insensitive.
|
||||
* - component 'all' applies to all known log components
|
||||
* - prefixing a component with '+' or '-' will en-/disable logging for
|
||||
* that component
|
||||
* Example: 'all,-ssl' would enable logging for all components but the
|
||||
* SSL filters.
|
||||
*
|
||||
* @param config configuration string
|
||||
*/
|
||||
CURLcode Curl_trc_opt(const char *config);
|
||||
|
||||
/* the function used to output verbose information */
|
||||
void Curl_debug(struct Curl_easy *data, curl_infotype type,
|
||||
char *ptr, size_t size);
|
||||
|
||||
/**
|
||||
* Output a failure message on registered callbacks for transfer.
|
||||
*/
|
||||
void Curl_failf(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
|
||||
#define failf Curl_failf
|
||||
|
||||
#define CURL_LOG_LVL_NONE 0
|
||||
#define CURL_LOG_LVL_INFO 1
|
||||
|
||||
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#define CURL_HAVE_C99
|
||||
#endif
|
||||
|
||||
#ifdef CURL_HAVE_C99
|
||||
#define infof(data, ...) \
|
||||
do { if(Curl_trc_is_verbose(data)) \
|
||||
Curl_infof(data, __VA_ARGS__); } while(0)
|
||||
#define CURL_TRC_CF(data, cf, ...) \
|
||||
do { if(Curl_trc_cf_is_verbose(cf, data)) \
|
||||
Curl_trc_cf_infof(data, cf, __VA_ARGS__); } while(0)
|
||||
#define CURL_TRC_WRITE(data, ...) \
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_write)) \
|
||||
Curl_trc_write(data, __VA_ARGS__); } while(0)
|
||||
#define CURL_TRC_READ(data, ...) \
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_read)) \
|
||||
Curl_trc_read(data, __VA_ARGS__); } while(0)
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#define CURL_TRC_FTP(data, ...) \
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ftp)) \
|
||||
Curl_trc_ftp(data, __VA_ARGS__); } while(0)
|
||||
#endif /* !CURL_DISABLE_FTP */
|
||||
|
||||
#else /* CURL_HAVE_C99 */
|
||||
|
||||
#define infof Curl_infof
|
||||
#define CURL_TRC_CF Curl_trc_cf_infof
|
||||
#define CURL_TRC_WRITE Curl_trc_write
|
||||
#define CURL_TRC_READ Curl_trc_read
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#define CURL_TRC_FTP Curl_trc_ftp
|
||||
#endif
|
||||
|
||||
#endif /* !CURL_HAVE_C99 */
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
/* informational messages enabled */
|
||||
|
||||
struct curl_trc_feat {
|
||||
const char *name;
|
||||
int log_level;
|
||||
};
|
||||
extern struct curl_trc_feat Curl_trc_feat_read;
|
||||
extern struct curl_trc_feat Curl_trc_feat_write;
|
||||
|
||||
#define Curl_trc_is_verbose(data) \
|
||||
((data) && (data)->set.verbose && \
|
||||
(!(data)->state.feat || \
|
||||
((data)->state.feat->log_level >= CURL_LOG_LVL_INFO)))
|
||||
#define Curl_trc_cf_is_verbose(cf, data) \
|
||||
(Curl_trc_is_verbose(data) && \
|
||||
(cf) && (cf)->cft->log_level >= CURL_LOG_LVL_INFO)
|
||||
#define Curl_trc_ft_is_verbose(data, ft) \
|
||||
(Curl_trc_is_verbose(data) && \
|
||||
(ft)->log_level >= CURL_LOG_LVL_INFO)
|
||||
|
||||
/**
|
||||
* Output an informational message when transfer's verbose logging is enabled.
|
||||
*/
|
||||
void Curl_infof(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
|
||||
/**
|
||||
* Output an informational message when both transfer's verbose logging
|
||||
* and connection filters verbose logging are enabled.
|
||||
*/
|
||||
void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf,
|
||||
const char *fmt, ...) CURL_PRINTF(3, 4);
|
||||
void Curl_trc_ft_infof(struct Curl_easy *data, struct curl_trc_feat *ft,
|
||||
const char *fmt, ...) CURL_PRINTF(3, 4);
|
||||
void Curl_trc_write(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
void Curl_trc_read(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
extern struct curl_trc_feat Curl_trc_feat_ftp;
|
||||
void Curl_trc_ftp(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
|
||||
|
||||
#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */
|
||||
/* All informational messages are not compiled in for size savings */
|
||||
|
||||
#define Curl_trc_is_verbose(d) (FALSE)
|
||||
#define Curl_trc_cf_is_verbose(x,y) (FALSE)
|
||||
#define Curl_trc_ft_is_verbose(x,y) (FALSE)
|
||||
|
||||
static void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
static void Curl_trc_cf_infof(struct Curl_easy *data,
|
||||
struct Curl_cfilter *cf,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)cf; (void)fmt;
|
||||
}
|
||||
|
||||
struct curl_trc_feat;
|
||||
|
||||
static void Curl_trc_ft_infof(struct Curl_easy *data,
|
||||
struct curl_trc_feat *ft,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)ft; (void)fmt;
|
||||
}
|
||||
|
||||
static void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
static void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
static void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */
|
||||
|
||||
#endif /* HEADER_CURL_TRC_H */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user