mirror of
https://github.com/curl/curl.git
synced 2026-08-05 00:26:15 +03:00
Merge branch 'master' into bagder/smtp-strparse
This commit is contained in:
commit
c549ae1dbf
3462 changed files with 66812 additions and 70349 deletions
|
|
@ -26,7 +26,7 @@ set(LIBCURL_OUTPUT_NAME "${LIB_NAME}" CACHE STRING "Basename of the curl library
|
|||
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ${CURL_DEBUG_MACROS} "BUILDING_LIBCURL")
|
||||
|
||||
configure_file("curl_config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h")
|
||||
configure_file("curl_config-cmake.h.in" "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h")
|
||||
|
||||
# Get CSOURCES, HHEADERS, LIB_RCFILES variables
|
||||
curl_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
|
||||
|
|
@ -44,7 +44,7 @@ if(CURL_BUILD_TESTING)
|
|||
# special libcurlu library just for unittests
|
||||
add_library(curlu STATIC EXCLUDE_FROM_ALL ${HHEADERS} ${CSOURCES})
|
||||
target_compile_definitions(curlu PUBLIC "CURL_STATICLIB" "UNITTESTS")
|
||||
target_link_libraries(curlu PRIVATE ${CURL_LIBS})
|
||||
target_link_libraries(curlu PUBLIC ${CURL_LIBS})
|
||||
# There is plenty of parallelism when building the testdeps target.
|
||||
# Override the curlu batch size with the maximum to optimize performance.
|
||||
set_target_properties(curlu PROPERTIES UNITY_BUILD_BATCH_SIZE 0 C_CLANG_TIDY "")
|
||||
|
|
@ -151,8 +151,7 @@ if(BUILD_STATIC_LIBS)
|
|||
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"
|
||||
INTERFACE_LINK_DIRECTORIES "${CURL_LIBDIRS}")
|
||||
INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")
|
||||
if(CURL_HIDES_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_OPTIONS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
|
|
@ -174,6 +173,27 @@ if(BUILD_STATIC_LIBS)
|
|||
target_include_directories(${LIB_STATIC} INTERFACE
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
|
||||
|
||||
# CMake before CMP0099 (CMake 3.17 2020-03-20) did not propagate libdirs to
|
||||
# targets. It expected libs to have an absolute filename. As a workaround,
|
||||
# manually apply dependency libdirs, for CMake consumers without this policy.
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.17)
|
||||
cmake_policy(GET CMP0099 _has_CMP0099) # https://cmake.org/cmake/help/latest/policy/CMP0099.html
|
||||
endif()
|
||||
if(NOT _has_CMP0099 AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.13 AND CURL_LIBS)
|
||||
set(_curl_libdirs "")
|
||||
foreach(_curl_lib IN LISTS CURL_LIBS)
|
||||
if(TARGET "${_curl_lib}")
|
||||
get_target_property(_curl_libdir "${_curl_lib}" INTERFACE_LINK_DIRECTORIES)
|
||||
if(_curl_libdir)
|
||||
list(APPEND _curl_libdirs "${_curl_libdir}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
if(_curl_libdirs)
|
||||
target_link_directories(${LIB_STATIC} INTERFACE ${_curl_libdirs})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
|
|
@ -304,7 +324,7 @@ 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)
|
||||
if(NOT CURL_DISABLE_INSTALL AND BUILD_STATIC_LIBS)
|
||||
install(TARGETS ${LIB_STATIC}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
|
|
@ -312,7 +332,7 @@ if(CURL_ENABLE_EXPORT_TARGET)
|
|||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if(NOT CURL_DISABLE_INSTALL AND BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${LIB_SHARED}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
|
|
@ -326,3 +346,12 @@ if(CURL_ENABLE_EXPORT_TARGET)
|
|||
NAMESPACE ${PROJECT_NAME}::
|
||||
)
|
||||
endif()
|
||||
|
||||
if(PERL_EXECUTABLE)
|
||||
add_custom_target(curl-optiontable
|
||||
COMMENT "Generating lib/easyoptions.c" VERBATIM USES_TERMINAL
|
||||
COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/optiontable.pl" < "${PROJECT_SOURCE_DIR}/include/curl/curl.h"
|
||||
> "${PROJECT_SOURCE_DIR}/lib/easyoptions.c"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/optiontable.pl" "${PROJECT_SOURCE_DIR}/include/curl/curl.h"
|
||||
)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc
|
|||
# Get CSOURCES, HHEADERS, LIB_RCFILES variables
|
||||
include Makefile.inc
|
||||
|
||||
CMAKE_DIST = CMakeLists.txt curl_config.h.cmake
|
||||
CMAKE_DIST = CMakeLists.txt curl_config-cmake.h.in
|
||||
|
||||
EXTRA_DIST = config-mac.h config-os400.h config-plan9.h config-riscos.h \
|
||||
config-win32.h curl_config.h.in $(LIB_RCFILES) libcurl.def \
|
||||
|
|
@ -63,8 +63,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \
|
|||
# Prevent LIBS from being used for all link targets
|
||||
LIBS = $(BLANK_AT_MAKETIME)
|
||||
|
||||
AM_LDFLAGS =
|
||||
AM_CFLAGS =
|
||||
if DEBUGBUILD
|
||||
AM_CPPFLAGS += -DDEBUGBUILD
|
||||
endif
|
||||
|
|
@ -136,12 +134,11 @@ 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_PC_LIBS_PRIVATE)
|
||||
libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA)
|
||||
libcurl_la_LDFLAGS = $(libcurl_la_LDFLAGS_EXTRA) $(CURL_LDFLAGS_LIB) $(LIBCURL_PC_LIBS_PRIVATE)
|
||||
libcurl_la_CFLAGS = $(libcurl_la_CFLAGS_EXTRA)
|
||||
|
||||
libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS
|
||||
libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_PC_LIBS_PRIVATE)
|
||||
libcurlu_la_CFLAGS = $(AM_CFLAGS)
|
||||
libcurlu_la_LDFLAGS = -static $(LIBCURL_PC_LIBS_PRIVATE)
|
||||
|
||||
CHECKSRC = $(CS_$(V))
|
||||
CS_0 = @echo " RUN " $@;
|
||||
|
|
@ -168,7 +165,7 @@ UNITV_ = $(UNITV_0)
|
|||
|
||||
# UNITPROTOS depends on every C file in the lib/ dir
|
||||
$(UNITPROTOS): $(CSOURCES)
|
||||
$(UNIT_V)(cd $(srcdir) && @PERL@ ../scripts/extract-unit-protos $(CSOURCES) > $(top_builddir)/lib/$(UNITPROTOS))
|
||||
$(UNIT_V)(cd $(srcdir) && @PERL@ ../scripts/extract-unit-protos $(CSOURCES)) > $(top_builddir)/lib/$(UNITPROTOS)
|
||||
|
||||
# disable the tests that are mostly causing false positives
|
||||
TIDYFLAGS := -checks=-clang-analyzer-security.insecureAPI.bzero,-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-optin.performance.Padding,-clang-analyzer-security.ArrayBound,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling -quiet
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ LIB_CURLX_HFILES = \
|
|||
curlx/inet_pton.h \
|
||||
curlx/multibyte.h \
|
||||
curlx/nonblock.h \
|
||||
curlx/snprintf.h \
|
||||
curlx/strerr.h \
|
||||
curlx/strparse.h \
|
||||
curlx/timediff.h \
|
||||
|
|
@ -85,7 +86,6 @@ LIB_VTLS_CFILES = \
|
|||
vtls/hostcheck.c \
|
||||
vtls/keylog.c \
|
||||
vtls/mbedtls.c \
|
||||
vtls/mbedtls_threadlock.c \
|
||||
vtls/openssl.c \
|
||||
vtls/rustls.c \
|
||||
vtls/schannel.c \
|
||||
|
|
@ -103,7 +103,6 @@ LIB_VTLS_HFILES = \
|
|||
vtls/hostcheck.h \
|
||||
vtls/keylog.h \
|
||||
vtls/mbedtls.h \
|
||||
vtls/mbedtls_threadlock.h \
|
||||
vtls/openssl.h \
|
||||
vtls/rustls.h \
|
||||
vtls/schannel.h \
|
||||
|
|
@ -133,10 +132,10 @@ LIB_VQUIC_HFILES = \
|
|||
LIB_VSSH_CFILES = \
|
||||
vssh/libssh.c \
|
||||
vssh/libssh2.c \
|
||||
vssh/curl_path.c
|
||||
vssh/vssh.c
|
||||
|
||||
LIB_VSSH_HFILES = \
|
||||
vssh/curl_path.h \
|
||||
vssh/vssh.h \
|
||||
vssh/ssh.h
|
||||
|
||||
LIB_CFILES = \
|
||||
|
|
@ -172,6 +171,7 @@ LIB_CFILES = \
|
|||
curl_rtmp.c \
|
||||
curl_sasl.c \
|
||||
curl_sha512_256.c \
|
||||
curl_share.c \
|
||||
curl_sspi.c \
|
||||
curl_threads.c \
|
||||
curl_trc.c \
|
||||
|
|
@ -234,14 +234,13 @@ LIB_CFILES = \
|
|||
progress.c \
|
||||
psl.c \
|
||||
rand.c \
|
||||
rename.c \
|
||||
ratelimit.c \
|
||||
request.c \
|
||||
rtsp.c \
|
||||
select.c \
|
||||
sendf.c \
|
||||
setopt.c \
|
||||
sha256.c \
|
||||
share.c \
|
||||
slist.c \
|
||||
smb.c \
|
||||
smtp.c \
|
||||
|
|
@ -249,7 +248,6 @@ LIB_CFILES = \
|
|||
socks.c \
|
||||
socks_gssapi.c \
|
||||
socks_sspi.c \
|
||||
speedcheck.c \
|
||||
splay.c \
|
||||
strcase.c \
|
||||
strdup.c \
|
||||
|
|
@ -299,8 +297,6 @@ LIB_HFILES = \
|
|||
curl_ldap.h \
|
||||
curl_md4.h \
|
||||
curl_md5.h \
|
||||
curl_mem_undef.h \
|
||||
curl_memory.h \
|
||||
curl_memrchr.h \
|
||||
curl_ntlm_core.h \
|
||||
curl_printf.h \
|
||||
|
|
@ -311,6 +307,7 @@ LIB_HFILES = \
|
|||
curl_setup_once.h \
|
||||
curl_sha256.h \
|
||||
curl_sha512_256.h \
|
||||
curl_share.h \
|
||||
curl_sspi.h \
|
||||
curl_threads.h \
|
||||
curl_trc.h \
|
||||
|
|
@ -351,7 +348,6 @@ LIB_HFILES = \
|
|||
imap.h \
|
||||
llist.h \
|
||||
macos.h \
|
||||
memdebug.h \
|
||||
mime.h \
|
||||
mqtt.h \
|
||||
multihandle.h \
|
||||
|
|
@ -366,7 +362,7 @@ LIB_HFILES = \
|
|||
progress.h \
|
||||
psl.h \
|
||||
rand.h \
|
||||
rename.h \
|
||||
ratelimit.h \
|
||||
request.h \
|
||||
rtsp.h \
|
||||
select.h \
|
||||
|
|
@ -375,7 +371,6 @@ LIB_HFILES = \
|
|||
setup-os400.h \
|
||||
setup-vms.h \
|
||||
setup-win32.h \
|
||||
share.h \
|
||||
sigpipe.h \
|
||||
slist.h \
|
||||
smb.h \
|
||||
|
|
@ -383,7 +378,6 @@ LIB_HFILES = \
|
|||
sockaddr.h \
|
||||
socketpair.h \
|
||||
socks.h \
|
||||
speedcheck.h \
|
||||
splay.h \
|
||||
strcase.h \
|
||||
strdup.h \
|
||||
|
|
|
|||
91
lib/altsvc.c
91
lib/altsvc.c
|
|
@ -28,7 +28,6 @@
|
|||
#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_fopen.h"
|
||||
|
|
@ -36,17 +35,12 @@
|
|||
#include "parsedate.h"
|
||||
#include "sendf.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "rename.h"
|
||||
#include "strdup.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "curlx/timeval.h"
|
||||
#include "connect.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAX_ALTSVC_LINE 4095
|
||||
#define MAX_ALTSVC_LINE 4095
|
||||
#define MAX_ALTSVC_DATELEN 256
|
||||
#define MAX_ALTSVC_HOSTLEN 2048
|
||||
#define MAX_ALTSVC_ALPNLEN 10
|
||||
|
|
@ -68,13 +62,7 @@ const char *Curl_alpnid2str(enum alpnid id)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void altsvc_free(struct altsvc *as)
|
||||
{
|
||||
free(as->src.host);
|
||||
free(as->dst.host);
|
||||
free(as);
|
||||
}
|
||||
#define altsvc_free(x) curlx_free(x)
|
||||
|
||||
static struct altsvc *altsvc_createid(const char *srchost,
|
||||
size_t hlen,
|
||||
|
|
@ -85,38 +73,35 @@ static struct altsvc *altsvc_createid(const char *srchost,
|
|||
size_t srcport,
|
||||
size_t dstport)
|
||||
{
|
||||
struct altsvc *as = calloc(1, sizeof(struct altsvc));
|
||||
if(!as)
|
||||
return NULL;
|
||||
DEBUGASSERT(hlen);
|
||||
DEBUGASSERT(dlen);
|
||||
if(!hlen || !dlen)
|
||||
/* bad input */
|
||||
goto error;
|
||||
struct altsvc *as;
|
||||
if((hlen > 2) && srchost[0] == '[') {
|
||||
/* IPv6 address, strip off brackets */
|
||||
srchost++;
|
||||
hlen -= 2;
|
||||
}
|
||||
else if(srchost[hlen - 1] == '.') {
|
||||
else if(hlen && (srchost[hlen - 1] == '.')) {
|
||||
/* strip off trailing dot */
|
||||
hlen--;
|
||||
if(!hlen)
|
||||
goto error;
|
||||
}
|
||||
if((dlen > 2) && dsthost[0] == '[') {
|
||||
/* IPv6 address, strip off brackets */
|
||||
dsthost++;
|
||||
dlen -= 2;
|
||||
}
|
||||
if(!hlen || !dlen)
|
||||
/* bad input */
|
||||
return NULL;
|
||||
/* struct size plus both strings */
|
||||
as = curlx_calloc(1, sizeof(struct altsvc) + (hlen + 1) + (dlen + 1));
|
||||
if(!as)
|
||||
return NULL;
|
||||
as->src.host = (char *)as + sizeof(struct altsvc);
|
||||
memcpy(as->src.host, srchost, hlen);
|
||||
/* the null terminator is already there */
|
||||
|
||||
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->dst.host = (char *)as + sizeof(struct altsvc) + hlen + 1;
|
||||
memcpy(as->dst.host, dsthost, dlen);
|
||||
/* the null terminator is already there */
|
||||
|
||||
as->src.alpnid = srcalpnid;
|
||||
as->dst.alpnid = dstalpnid;
|
||||
|
|
@ -124,9 +109,6 @@ static struct altsvc *altsvc_createid(const char *srchost,
|
|||
as->dst.port = (unsigned short)dstport;
|
||||
|
||||
return as;
|
||||
error:
|
||||
altsvc_free(as);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct altsvc *altsvc_create(struct Curl_str *srchost,
|
||||
|
|
@ -136,10 +118,8 @@ static struct altsvc *altsvc_create(struct Curl_str *srchost,
|
|||
size_t srcport,
|
||||
size_t dstport)
|
||||
{
|
||||
enum alpnid dstalpnid =
|
||||
Curl_alpn2alpnid(curlx_str(dstalpn), curlx_strlen(dstalpn));
|
||||
enum alpnid srcalpnid =
|
||||
Curl_alpn2alpnid(curlx_str(srcalpn), curlx_strlen(srcalpn));
|
||||
enum alpnid dstalpnid = Curl_str2alpnid(dstalpn);
|
||||
enum alpnid srcalpnid = Curl_str2alpnid(srcalpn);
|
||||
if(!srcalpnid || !dstalpnid)
|
||||
return NULL;
|
||||
return altsvc_createid(curlx_str(srchost), curlx_strlen(srchost),
|
||||
|
|
@ -201,6 +181,8 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, const char *line)
|
|||
as->persist = persist ? 1 : 0;
|
||||
Curl_llist_append(&asi->list, as, &as->node);
|
||||
}
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
|
|
@ -221,8 +203,8 @@ static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
|
|||
|
||||
/* we need a private copy of the filename so that the altsvc cache file
|
||||
name survives an easy handle reset */
|
||||
free(asi->filename);
|
||||
asi->filename = strdup(file);
|
||||
curlx_free(asi->filename);
|
||||
asi->filename = curlx_strdup(file);
|
||||
if(!asi->filename)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -257,7 +239,7 @@ static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
|||
const char *dst6_post = "";
|
||||
const char *src6_pre = "";
|
||||
const char *src6_post = "";
|
||||
CURLcode result = Curl_gmtime(as->expires, &stamp);
|
||||
CURLcode result = curlx_gmtime(as->expires, &stamp);
|
||||
if(result)
|
||||
return result;
|
||||
#ifdef USE_IPV6
|
||||
|
|
@ -301,7 +283,7 @@ static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
|||
*/
|
||||
struct altsvcinfo *Curl_altsvc_init(void)
|
||||
{
|
||||
struct altsvcinfo *asi = calloc(1, sizeof(struct altsvcinfo));
|
||||
struct altsvcinfo *asi = curlx_calloc(1, sizeof(struct altsvcinfo));
|
||||
if(!asi)
|
||||
return NULL;
|
||||
Curl_llist_init(&asi->list, NULL);
|
||||
|
|
@ -352,8 +334,8 @@ void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp)
|
|||
n = Curl_node_next(e);
|
||||
altsvc_free(as);
|
||||
}
|
||||
free(altsvc->filename);
|
||||
free(altsvc);
|
||||
curlx_free(altsvc->filename);
|
||||
curlx_free(altsvc);
|
||||
*altsvcp = NULL; /* clear the pointer */
|
||||
}
|
||||
}
|
||||
|
|
@ -395,13 +377,13 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
|
|||
break;
|
||||
}
|
||||
curlx_fclose(out);
|
||||
if(!result && tempstore && Curl_rename(tempstore, file))
|
||||
if(!result && tempstore && curlx_rename(tempstore, file))
|
||||
result = CURLE_WRITE_ERROR;
|
||||
|
||||
if(result && tempstore)
|
||||
unlink(tempstore);
|
||||
}
|
||||
free(tempstore);
|
||||
curlx_free(tempstore);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -545,8 +527,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
|||
do {
|
||||
if(!curlx_str_single(&p, '=')) {
|
||||
/* [protocol]="[host][:port], [protocol]="[host][:port]" */
|
||||
enum alpnid dstalpnid =
|
||||
Curl_alpn2alpnid(curlx_str(&alpn), curlx_strlen(&alpn));
|
||||
enum alpnid dstalpnid = Curl_str2alpnid(&alpn);
|
||||
if(!curlx_str_single(&p, '\"')) {
|
||||
struct Curl_str dsthost;
|
||||
curl_off_t port = 0;
|
||||
|
|
@ -559,7 +540,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* IPv6 host name */
|
||||
/* IPv6 hostname */
|
||||
if(curlx_str_until(&p, &dsthost, MAX_IPADR_LEN, ']') ||
|
||||
curlx_str_single(&p, ']')) {
|
||||
infof(data, "Bad alt-svc IPv6 hostname, ignoring.");
|
||||
|
|
@ -608,6 +589,8 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
|||
(int)curlx_strlen(&dsthost), curlx_str(&dsthost),
|
||||
dstport, Curl_alpnid2str(dstalpnid));
|
||||
}
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -637,7 +620,8 @@ 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 */
|
||||
const int versions, /* one or more bits */
|
||||
bool *psame_destination)
|
||||
{
|
||||
struct Curl_llist_node *e;
|
||||
struct Curl_llist_node *n;
|
||||
|
|
@ -646,6 +630,7 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
|||
DEBUGASSERT(srchost);
|
||||
DEBUGASSERT(dstentry);
|
||||
|
||||
*psame_destination = FALSE;
|
||||
for(e = Curl_llist_head(&asi->list); e; e = n) {
|
||||
struct altsvc *as = Curl_node_elem(e);
|
||||
n = Curl_node_next(e);
|
||||
|
|
@ -661,6 +646,8 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
|||
(versions & (int)as->dst.alpnid)) {
|
||||
/* match */
|
||||
*dstentry = as;
|
||||
*psame_destination = (srcport == as->dst.port) &&
|
||||
hostcompare(srchost, as->dst.host);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
|
||||
#include <curl/curl.h>
|
||||
#include "llist.h"
|
||||
|
||||
struct althost {
|
||||
|
|
@ -65,10 +64,11 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
|||
enum alpnid srcalpnid, const char *srchost,
|
||||
int srcport,
|
||||
struct altsvc **dstentry,
|
||||
const int versions); /* CURLALTSVC_H* bits */
|
||||
const int versions, /* CURLALTSVC_H* bits */
|
||||
bool *psame_destination);
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_altsvc_save(a,b,c)
|
||||
#define Curl_altsvc_save(a, b, c)
|
||||
#define Curl_altsvc_cleanup(x)
|
||||
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
|
||||
#endif /* HEADER_CURL_ALTSVC_H */
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
#ifdef __AMIGA__
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "hostip.h"
|
||||
#include "amigaos.h"
|
||||
|
||||
|
|
@ -42,10 +40,6 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef HAVE_PROTO_BSDSOCKET_H
|
||||
|
||||
#ifdef __amigaos4__
|
||||
|
|
@ -120,12 +114,11 @@ void Curl_amiga_cleanup(void)
|
|||
* Because we need to handle the different cases in hostip4.c at runtime,
|
||||
* 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()
|
||||
* 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 *Curl_ipv4_resolve_r(const char *hostname, int port)
|
||||
{
|
||||
struct Curl_addrinfo *ai = NULL;
|
||||
struct hostent *h;
|
||||
|
|
@ -135,7 +128,7 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
|||
LONG h_errnop = 0;
|
||||
struct hostent *buf;
|
||||
|
||||
buf = calloc(1, CURL_HOSTENT_SIZE);
|
||||
buf = curlx_calloc(1, CURL_HOSTENT_SIZE);
|
||||
if(buf) {
|
||||
h = gethostbyname_r((STRPTR)hostname, buf,
|
||||
(char *)buf + sizeof(struct hostent),
|
||||
|
|
@ -144,12 +137,12 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
|||
if(h) {
|
||||
ai = Curl_he2ai(h, port);
|
||||
}
|
||||
free(buf);
|
||||
curlx_free(buf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef CURLRES_THREADED
|
||||
/* gethostbyname() is not thread safe, so we need to reopen bsdsocket
|
||||
#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);
|
||||
|
|
@ -164,13 +157,13 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
|||
}
|
||||
CloseLibrary(base);
|
||||
}
|
||||
#else
|
||||
#else
|
||||
/* not using threaded resolver - safe to use this as-is */
|
||||
h = gethostbyname(hostname);
|
||||
if(h) {
|
||||
ai = Curl_he2ai(h, port);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
return ai;
|
||||
|
|
@ -223,8 +216,7 @@ CURLcode Curl_amiga_init(void)
|
|||
}
|
||||
|
||||
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG)&errno,
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG)"curl",
|
||||
TAG_DONE)) {
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG)"curl", TAG_DONE)) {
|
||||
CURL_AMIGA_REQUEST("SocketBaseTags ERROR");
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ void Curl_amiga_cleanup(void);
|
|||
|
||||
#else
|
||||
|
||||
#define Curl_amiga_init() CURLE_OK
|
||||
#define Curl_amiga_init() CURLE_OK
|
||||
#define Curl_amiga_cleanup() Curl_nop_stmt
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -43,8 +43,7 @@
|
|||
/*
|
||||
* The telnet options represented as strings
|
||||
*/
|
||||
static const char * const telnetoptions[]=
|
||||
{
|
||||
static const char * const telnetoptions[] = {
|
||||
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD",
|
||||
"NAME", "STATUS", "TIMING MARK", "RCTE",
|
||||
"NAOL", "NAOP", "NAOCRD", "NAOHTS",
|
||||
|
|
@ -79,15 +78,14 @@ static const char * const telnetoptions[]=
|
|||
#define CURL_WILL 251 /* Our side WILL use this option */
|
||||
#define CURL_WONT 252 /* Our side will not use this option */
|
||||
#define CURL_DO 253 /* DO use this option! */
|
||||
#define CURL_DONT 254 /* DON'T use this option! */
|
||||
#define CURL_DONT 254 /* DO NOT 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[]=
|
||||
{
|
||||
static const char * const telnetcmds[] = {
|
||||
"EOF", "SUSP", "ABORT", "EOR", "SE",
|
||||
"NOP", "DMARK", "BRK", "IP", "AO",
|
||||
"AYT", "EC", "EL", "GA", "SB",
|
||||
|
|
@ -103,11 +101,11 @@ static const char * const telnetcmds[]=
|
|||
#define CURL_TELQUAL_INFO 2
|
||||
#define CURL_TELQUAL_NAME 3
|
||||
|
||||
#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
|
||||
((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) )
|
||||
#define CURL_TELCMD_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]
|
||||
#define CURL_TELCMD(x) telnetcmds[(x) - CURL_TELCMD_MINIMUM]
|
||||
#else
|
||||
#define CURL_TELCMD(x) ""
|
||||
#endif
|
||||
|
|
|
|||
129
lib/asyn-ares.c
129
lib/asyn-ares.c
|
|
@ -32,7 +32,6 @@
|
|||
* as defined in asyn.h, nothing else belongs in this file!
|
||||
**********************************************************************/
|
||||
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
|
@ -51,8 +50,6 @@
|
|||
#include "cfilters.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
|
|
@ -88,7 +85,7 @@
|
|||
/* 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
|
||||
This is intended to equal the c-ares default timeout. curl always uses that
|
||||
default value. Unfortunately, c-ares does not expose its default timeout in
|
||||
its API, but it is officially documented as 5 seconds.
|
||||
|
||||
|
|
@ -104,10 +101,6 @@
|
|||
#define HTTPSRR_WORKS
|
||||
#endif
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define CARES_TIMEOUT_PER_ATTEMPT 2000
|
||||
|
||||
static int ares_ver = 0;
|
||||
|
|
@ -144,7 +137,6 @@ void Curl_async_global_cleanup(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void sock_state_cb(void *data, ares_socket_t socket_fd,
|
||||
int readable, int writable)
|
||||
{
|
||||
|
|
@ -185,8 +177,7 @@ static CURLcode async_ares_init(struct Curl_easy *data)
|
|||
status = ares_init_options(&ares->channel, &options, optmask);
|
||||
if(status != ARES_SUCCESS) {
|
||||
ares->channel = NULL;
|
||||
rc = (status == ARES_ENOMEM) ?
|
||||
CURLE_OUT_OF_MEMORY : CURLE_FAILED_INIT;
|
||||
rc = (status == ARES_ENOMEM) ? CURLE_OUT_OF_MEMORY : CURLE_FAILED_INIT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -313,12 +304,13 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
|||
/* Now that we have checked for any last minute results above, see if there
|
||||
are any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
|
||||
expires. */
|
||||
if(ares->num_pending
|
||||
if(ares->num_pending &&
|
||||
/* This is only set to non-zero if the timer was started. */
|
||||
&& (ares->happy_eyeballs_dns_time.tv_sec
|
||||
|| ares->happy_eyeballs_dns_time.tv_usec)
|
||||
&& (curlx_timediff(curlx_now(), ares->happy_eyeballs_dns_time)
|
||||
>= HAPPY_EYEBALLS_DNS_TIMEOUT)) {
|
||||
(ares->happy_eyeballs_dns_time.tv_sec ||
|
||||
ares->happy_eyeballs_dns_time.tv_usec) &&
|
||||
(curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&ares->happy_eyeballs_dns_time) >=
|
||||
HAPPY_EYEBALLS_DNS_TIMEOUT)) {
|
||||
/* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer
|
||||
running. */
|
||||
memset(&ares->happy_eyeballs_dns_time, 0,
|
||||
|
|
@ -343,7 +335,8 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
|||
Curl_dnscache_mk_entry(data, ares->temp_ai,
|
||||
data->state.async.hostname, 0,
|
||||
data->state.async.port, FALSE);
|
||||
ares->temp_ai = NULL; /* temp_ai now owned by entry */
|
||||
if(data->state.async.dns)
|
||||
ares->temp_ai = NULL; /* temp_ai now owned by entry */
|
||||
#ifdef HTTPSRR_WORKS
|
||||
if(data->state.async.dns) {
|
||||
struct Curl_https_rrinfo *lhrr = Curl_httpsrr_dup_move(&ares->hinfo);
|
||||
|
|
@ -394,47 +387,46 @@ CURLcode Curl_async_await(struct Curl_easy *data,
|
|||
{
|
||||
struct async_ares_ctx *ares = &data->state.async.ares;
|
||||
CURLcode result = CURLE_OK;
|
||||
timediff_t timeout;
|
||||
struct curltime now = curlx_now();
|
||||
timediff_t timeout_ms;
|
||||
|
||||
DEBUGASSERT(entry);
|
||||
*entry = NULL; /* clear on entry */
|
||||
|
||||
timeout = Curl_timeleft(data, &now, TRUE);
|
||||
if(timeout < 0) {
|
||||
timeout_ms = Curl_timeleft_ms(data, TRUE);
|
||||
if(timeout_ms < 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 */
|
||||
if(!timeout_ms)
|
||||
timeout_ms = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve */
|
||||
|
||||
/* Wait for the name resolve query to complete. */
|
||||
while(!result) {
|
||||
struct timeval *tvp, tv, store;
|
||||
int itimeout;
|
||||
timediff_t timeout_ms;
|
||||
struct timeval *real_timeout, time_buf, max_timeout;
|
||||
int itimeout_ms;
|
||||
timediff_t call_timeout_ms;
|
||||
|
||||
#if TIMEDIFF_T_MAX > INT_MAX
|
||||
itimeout = (timeout > INT_MAX) ? INT_MAX : (int)timeout;
|
||||
itimeout_ms = (timeout_ms > INT_MAX) ? INT_MAX : (int)timeout_ms;
|
||||
#else
|
||||
itimeout = (int)timeout;
|
||||
itimeout_ms = (int)timeout_ms;
|
||||
#endif
|
||||
|
||||
store.tv_sec = itimeout/1000;
|
||||
store.tv_usec = (itimeout%1000)*1000;
|
||||
max_timeout.tv_sec = itimeout_ms / 1000;
|
||||
max_timeout.tv_usec = (itimeout_ms % 1000) * 1000;
|
||||
|
||||
tvp = ares_timeout(ares->channel, &store, &tv);
|
||||
real_timeout = ares_timeout(ares->channel, &max_timeout, &time_buf);
|
||||
|
||||
/* 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);
|
||||
if(!real_timeout->tv_sec)
|
||||
call_timeout_ms = (timediff_t)(real_timeout->tv_usec / 1000);
|
||||
else
|
||||
timeout_ms = 1000;
|
||||
call_timeout_ms = 1000;
|
||||
|
||||
if(Curl_ares_perform(ares->channel, timeout_ms) < 0)
|
||||
if(Curl_ares_perform(ares->channel, call_timeout_ms) < 0)
|
||||
return CURLE_UNRECOVERABLE_POLL;
|
||||
|
||||
result = Curl_async_is_resolved(data, entry);
|
||||
|
|
@ -444,17 +436,16 @@ CURLcode Curl_async_await(struct Curl_easy *data,
|
|||
if(Curl_pgrsUpdate(data))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else {
|
||||
struct curltime now2 = curlx_now();
|
||||
timediff_t timediff = curlx_timediff(now2, now); /* spent time */
|
||||
if(timediff <= 0)
|
||||
timeout -= 1; /* always deduct at least 1 */
|
||||
else if(timediff > timeout)
|
||||
timeout = -1;
|
||||
struct curltime now = curlx_now(); /* update in loop */
|
||||
timediff_t elapsed_ms = curlx_ptimediff_ms(&now, Curl_pgrs_now(data));
|
||||
if(elapsed_ms <= 0)
|
||||
timeout_ms -= 1; /* always deduct at least 1 */
|
||||
else if(elapsed_ms > timeout_ms)
|
||||
timeout_ms = -1;
|
||||
else
|
||||
timeout -= timediff;
|
||||
now = now2; /* for next loop */
|
||||
timeout_ms -= elapsed_ms;
|
||||
}
|
||||
if(timeout < 0)
|
||||
if(timeout_ms < 0)
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
|
|
@ -521,7 +512,7 @@ static void async_ares_hostbyname_cb(void *user_data,
|
|||
if(ARES_SUCCESS == status) {
|
||||
ares->ares_status = status; /* one success overrules any error */
|
||||
async_addr_concat(&ares->temp_ai,
|
||||
Curl_he2ai(hostent, data->state.async.port));
|
||||
Curl_he2ai(hostent, data->state.async.port));
|
||||
}
|
||||
else if(ares->ares_status != ARES_SUCCESS) {
|
||||
/* no success so far, remember last error */
|
||||
|
|
@ -566,7 +557,7 @@ static void async_ares_hostbyname_cb(void *user_data,
|
|||
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
|
||||
request came back quickly, that need not be the case. It might be that
|
||||
this completing request did not 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
|
||||
|
|
@ -588,9 +579,8 @@ static void async_ares_hostbyname_cb(void *user_data,
|
|||
timeout to prevent it. After all, we do not even know where in the
|
||||
c-ares retry cycle each request is.
|
||||
*/
|
||||
ares->happy_eyeballs_dns_time = curlx_now();
|
||||
Curl_expire(data, HAPPY_EYEBALLS_DNS_TIMEOUT,
|
||||
EXPIRE_HAPPY_EYEBALLS_DNS);
|
||||
ares->happy_eyeballs_dns_time = *Curl_pgrs_now(data);
|
||||
Curl_expire(data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -632,7 +622,7 @@ async_ares_node2addr(struct ares_addrinfo_node *node)
|
|||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
ca = malloc(sizeof(struct Curl_addrinfo) + ss_size);
|
||||
ca = curlx_malloc(sizeof(struct Curl_addrinfo) + ss_size);
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
|
|
@ -718,30 +708,33 @@ static void async_ares_rr_done(void *user_data, ares_status_t status,
|
|||
/*
|
||||
* Curl_async_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.
|
||||
* Starts a name resolve for the given hostname and port number.
|
||||
*/
|
||||
struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int ip_version,
|
||||
int *waitp)
|
||||
CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname,
|
||||
int port, int ip_version)
|
||||
{
|
||||
struct async_ares_ctx *ares = &data->state.async.ares;
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
#ifdef USE_HTTPSRR
|
||||
char *rrname = NULL;
|
||||
#endif
|
||||
|
||||
if(async_ares_init_lazy(data))
|
||||
return NULL;
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
data->state.async.done = FALSE; /* not done */
|
||||
data->state.async.dns = NULL; /* clear */
|
||||
data->state.async.port = port;
|
||||
data->state.async.ip_version = ip_version;
|
||||
data->state.async.hostname = strdup(hostname);
|
||||
data->state.async.hostname = curlx_strdup(hostname);
|
||||
if(!data->state.async.hostname)
|
||||
return NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#ifdef USE_HTTPSRR
|
||||
if(port != 443) {
|
||||
rrname = curl_maprintf("_%d_.https.%s", port, hostname);
|
||||
if(!rrname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* initial status - failed */
|
||||
ares->ares_status = ARES_ENOTFOUND;
|
||||
|
|
@ -814,18 +807,20 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
|||
#endif
|
||||
#ifdef USE_HTTPSRR
|
||||
{
|
||||
CURL_TRC_DNS(data, "asyn-ares: fire off query for HTTPSRR");
|
||||
CURL_TRC_DNS(data, "asyn-ares: fire off query for HTTPSRR: %s",
|
||||
rrname ? rrname : data->state.async.hostname);
|
||||
memset(&ares->hinfo, 0, sizeof(ares->hinfo));
|
||||
ares->hinfo.port = -1;
|
||||
ares->hinfo.rrname = rrname;
|
||||
ares->num_pending++; /* one more */
|
||||
ares_query_dnsrec(ares->channel, data->state.async.hostname,
|
||||
ares_query_dnsrec(ares->channel,
|
||||
rrname ? rrname : data->state.async.hostname,
|
||||
ARES_CLASS_IN, ARES_REC_TYPE_HTTPS,
|
||||
async_ares_rr_done, data, NULL);
|
||||
}
|
||||
#endif
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
|
||||
return NULL; /* no struct yet */
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Set what DNS server are is to use. This is called in 2 situations:
|
||||
|
|
|
|||
|
|
@ -48,21 +48,15 @@
|
|||
#include "asyn.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "multiif.h"
|
||||
#include "select.h"
|
||||
#include "share.h"
|
||||
#include "url.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for builds using asynchronous name resolves
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_ASYNCH
|
||||
|
||||
|
||||
#ifdef USE_ARES
|
||||
|
||||
#if ARES_VERSION < 0x010600
|
||||
|
|
@ -77,8 +71,6 @@
|
|||
*
|
||||
* Returns: sockets-in-use-bitmap
|
||||
*/
|
||||
|
||||
|
||||
CURLcode Curl_ares_pollset(struct Curl_easy *data,
|
||||
ares_channel channel,
|
||||
struct easy_pollset *ps)
|
||||
|
|
@ -127,8 +119,7 @@ CURLcode Curl_ares_pollset(struct Curl_easy *data,
|
|||
*
|
||||
* return number of sockets it worked on, or -1 on error
|
||||
*/
|
||||
int Curl_ares_perform(ares_channel channel,
|
||||
timediff_t timeout_ms)
|
||||
int Curl_ares_perform(ares_channel channel, timediff_t timeout_ms)
|
||||
{
|
||||
int nfds;
|
||||
int bitmask;
|
||||
|
|
@ -147,11 +138,11 @@ int Curl_ares_perform(ares_channel channel,
|
|||
pfd[i].revents = 0;
|
||||
if(ARES_GETSOCK_READABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLRDNORM|POLLIN;
|
||||
pfd[i].events |= POLLRDNORM | POLLIN;
|
||||
}
|
||||
if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLWRNORM|POLLOUT;
|
||||
pfd[i].events |= POLLWRNORM | POLLOUT;
|
||||
}
|
||||
if(pfd[i].events)
|
||||
num++;
|
||||
|
|
@ -175,9 +166,9 @@ int Curl_ares_perform(ares_channel channel,
|
|||
/* move through the descriptors and ask for processing on them */
|
||||
for(i = 0; i < num; i++)
|
||||
ares_process_fd(channel,
|
||||
(pfd[i].revents & (POLLRDNORM|POLLIN)) ?
|
||||
(pfd[i].revents & (POLLRDNORM | POLLIN)) ?
|
||||
pfd[i].fd : ARES_SOCKET_BAD,
|
||||
(pfd[i].revents & (POLLWRNORM|POLLOUT)) ?
|
||||
(pfd[i].revents & (POLLWRNORM | POLLOUT)) ?
|
||||
pfd[i].fd : ARES_SOCKET_BAD);
|
||||
}
|
||||
return nfds;
|
||||
|
|
|
|||
|
|
@ -45,24 +45,23 @@
|
|||
#endif
|
||||
|
||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||
# include <pthread.h>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
# define RESOLVER_ENOMEM EAI_MEMORY /* = WSA_NOT_ENOUGH_MEMORY on Windows */
|
||||
#define RESOLVER_ENOMEM EAI_MEMORY /* = WSA_NOT_ENOUGH_MEMORY on Windows */
|
||||
#else
|
||||
# define RESOLVER_ENOMEM SOCKENOMEM
|
||||
#define RESOLVER_ENOMEM SOCKENOMEM
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "cfilters.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "curl_threads.h"
|
||||
#include "progress.h"
|
||||
#include "select.h"
|
||||
|
||||
#ifdef USE_ARES
|
||||
|
|
@ -72,10 +71,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Curl_async_global_init()
|
||||
|
|
@ -136,7 +131,7 @@ static void addr_ctx_unlink(struct async_thrdd_addr_ctx **paddr_ctx,
|
|||
|
||||
if(destroy) {
|
||||
Curl_mutex_destroy(&addr_ctx->mutx);
|
||||
free(addr_ctx->hostname);
|
||||
curlx_free(addr_ctx->hostname);
|
||||
if(addr_ctx->res)
|
||||
Curl_freeaddrinfo(addr_ctx->res);
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
|
|
@ -145,7 +140,7 @@ static void addr_ctx_unlink(struct async_thrdd_addr_ctx **paddr_ctx,
|
|||
#endif
|
||||
wakeup_close(addr_ctx->sock_pair[0]);
|
||||
#endif
|
||||
free(addr_ctx);
|
||||
curlx_free(addr_ctx);
|
||||
}
|
||||
*paddr_ctx = NULL;
|
||||
}
|
||||
|
|
@ -156,7 +151,7 @@ addr_ctx_create(struct Curl_easy *data,
|
|||
const char *hostname, int port,
|
||||
const struct addrinfo *hints)
|
||||
{
|
||||
struct async_thrdd_addr_ctx *addr_ctx = calloc(1, sizeof(*addr_ctx));
|
||||
struct async_thrdd_addr_ctx *addr_ctx = curlx_calloc(1, sizeof(*addr_ctx));
|
||||
if(!addr_ctx)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -186,7 +181,7 @@ addr_ctx_create(struct Curl_easy *data,
|
|||
/* Copying hostname string because original can be destroyed by parent
|
||||
* thread during gethostbyname execution.
|
||||
*/
|
||||
addr_ctx->hostname = strdup(hostname);
|
||||
addr_ctx->hostname = curlx_strdup(hostname);
|
||||
if(!addr_ctx->hostname)
|
||||
goto err_exit;
|
||||
|
||||
|
|
@ -249,7 +244,6 @@ static CURL_THREAD_RETURN_T CURL_STDCALL getaddrinfo_thread(void *arg)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
addr_ctx_unlink(&addr_ctx, NULL);
|
||||
|
|
@ -361,30 +355,40 @@ static void async_thrdd_rr_done(void *user_data, ares_status_t status,
|
|||
thrdd->rr.result = Curl_httpsrr_from_ares(data, dnsrec, &thrdd->rr.hinfo);
|
||||
}
|
||||
|
||||
static CURLcode async_rr_start(struct Curl_easy *data)
|
||||
static CURLcode async_rr_start(struct Curl_easy *data, int port)
|
||||
{
|
||||
struct async_thrdd_ctx *thrdd = &data->state.async.thrdd;
|
||||
int status;
|
||||
char *rrname = NULL;
|
||||
|
||||
DEBUGASSERT(!thrdd->rr.channel);
|
||||
if(port != 443) {
|
||||
rrname = curl_maprintf("_%d_.https.%s", port, data->conn->host.name);
|
||||
if(!rrname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
status = ares_init_options(&thrdd->rr.channel, NULL, 0);
|
||||
if(status != ARES_SUCCESS) {
|
||||
thrdd->rr.channel = NULL;
|
||||
curlx_free(rrname);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#ifdef CURLDEBUG
|
||||
if(getenv("CURL_DNS_SERVER")) {
|
||||
const char *servers = getenv("CURL_DNS_SERVER");
|
||||
status = ares_set_servers_ports_csv(thrdd->rr.channel, servers);
|
||||
if(status)
|
||||
if(status) {
|
||||
curlx_free(rrname);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&thrdd->rr.hinfo, 0, sizeof(thrdd->rr.hinfo));
|
||||
thrdd->rr.hinfo.port = -1;
|
||||
thrdd->rr.hinfo.rrname = rrname;
|
||||
ares_query_dnsrec(thrdd->rr.channel,
|
||||
data->conn->host.name, ARES_CLASS_IN,
|
||||
rrname ? rrname : data->conn->host.name, ARES_CLASS_IN,
|
||||
ARES_REC_TYPE_HTTPS,
|
||||
async_thrdd_rr_done, data, NULL);
|
||||
CURL_TRC_DNS(data, "Issued HTTPS-RR request for %s", data->conn->host.name);
|
||||
|
|
@ -425,8 +429,8 @@ static bool async_thrdd_init(struct Curl_easy *data,
|
|||
data->state.async.done = FALSE;
|
||||
data->state.async.port = port;
|
||||
data->state.async.ip_version = ip_version;
|
||||
free(data->state.async.hostname);
|
||||
data->state.async.hostname = strdup(hostname);
|
||||
curlx_free(data->state.async.hostname);
|
||||
data->state.async.hostname = curlx_strdup(hostname);
|
||||
if(!data->state.async.hostname)
|
||||
goto err_exit;
|
||||
|
||||
|
|
@ -437,7 +441,7 @@ static bool async_thrdd_init(struct Curl_easy *data,
|
|||
|
||||
/* passing addr_ctx to the thread adds a reference */
|
||||
addr_ctx->ref_count = 2;
|
||||
addr_ctx->start = curlx_now();
|
||||
addr_ctx->start = *Curl_pgrs_now(data);
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
addr_ctx->thread_hnd = Curl_thread_create(getaddrinfo_thread, addr_ctx);
|
||||
|
|
@ -454,7 +458,7 @@ static bool async_thrdd_init(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
if(async_rr_start(data))
|
||||
if(async_rr_start(data, port))
|
||||
infof(data, "Failed HTTPS RR operation");
|
||||
#endif
|
||||
CURL_TRC_DNS(data, "resolve thread started for of %s:%d", hostname, port);
|
||||
|
|
@ -463,7 +467,7 @@ static bool async_thrdd_init(struct Curl_easy *data,
|
|||
err_exit:
|
||||
CURL_TRC_DNS(data, "resolve thread failed init: %d", err);
|
||||
async_thrdd_destroy(data);
|
||||
CURL_SETERRNO(err);
|
||||
errno = err;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -480,8 +484,8 @@ static void async_thrdd_shutdown(struct Curl_easy *data)
|
|||
|
||||
Curl_mutex_acquire(&addr_ctx->mutx);
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
if(!addr_ctx->do_abort)
|
||||
Curl_multi_will_close(data, addr_ctx->sock_pair[0]);
|
||||
if(!addr_ctx->do_abort)
|
||||
Curl_multi_will_close(data, addr_ctx->sock_pair[0]);
|
||||
#endif
|
||||
addr_ctx->do_abort = TRUE;
|
||||
done = addr_ctx->thrd_done;
|
||||
|
|
@ -650,8 +654,8 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
|||
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 = curlx_timediff(curlx_now(),
|
||||
data->progress.t_startsingle);
|
||||
timediff_t elapsed = curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&data->progress.t_startsingle);
|
||||
if(elapsed < 0)
|
||||
elapsed = 0;
|
||||
|
||||
|
|
@ -659,7 +663,7 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
|||
/* Start at 1ms poll interval */
|
||||
thrdd->addr->poll_interval = 1;
|
||||
else if(elapsed >= thrdd->addr->interval_end)
|
||||
/* Back-off exponentially if last interval expired */
|
||||
/* Back-off exponentially if last interval expired */
|
||||
thrdd->addr->poll_interval *= 2;
|
||||
|
||||
if(thrdd->addr->poll_interval > 250)
|
||||
|
|
@ -697,15 +701,16 @@ CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps)
|
|||
|
||||
if(!thrd_done) {
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
/* return read fd to client for polling the DNS resolution status */
|
||||
/* return read fd to client for polling the DNS resolution status */
|
||||
result = Curl_pollset_add_in(data, ps, thrdd->addr->sock_pair[0]);
|
||||
#else
|
||||
timediff_t milli;
|
||||
timediff_t ms = curlx_timediff(curlx_now(), thrdd->addr->start);
|
||||
timediff_t ms =
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data), &thrdd->addr->start);
|
||||
if(ms < 3)
|
||||
milli = 0;
|
||||
else if(ms <= 50)
|
||||
milli = ms/3;
|
||||
milli = ms / 3;
|
||||
else if(ms <= 250)
|
||||
milli = 50;
|
||||
else
|
||||
|
|
@ -720,24 +725,18 @@ CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps)
|
|||
/*
|
||||
* Curl_async_getaddrinfo() - for platforms without getaddrinfo
|
||||
*/
|
||||
struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int ip_version,
|
||||
int *waitp)
|
||||
CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname,
|
||||
int port, int ip_version)
|
||||
{
|
||||
(void)ip_version;
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
/* fire up a new resolver thread! */
|
||||
if(async_thrdd_init(data, hostname, port, ip_version, NULL)) {
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
return NULL;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
failf(data, "getaddrinfo() thread failed");
|
||||
|
||||
return NULL;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
#else /* !HAVE_GETADDRINFO */
|
||||
|
|
@ -745,15 +744,11 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
|||
/*
|
||||
* Curl_async_getaddrinfo() - for getaddrinfo
|
||||
*/
|
||||
struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int ip_version,
|
||||
int *waitp)
|
||||
CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname,
|
||||
int port, int ip_version)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
int pf = PF_INET;
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
CURL_TRC_DNS(data, "init threaded resolve of %s:%d", hostname, port);
|
||||
#ifdef CURLRES_IPV6
|
||||
|
|
@ -775,14 +770,11 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
|||
SOCK_STREAM : SOCK_DGRAM;
|
||||
|
||||
/* fire up a new resolver thread! */
|
||||
if(async_thrdd_init(data, hostname, port, ip_version, &hints)) {
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
return NULL;
|
||||
}
|
||||
if(async_thrdd_init(data, hostname, port, ip_version, &hints))
|
||||
return CURLE_OK;
|
||||
|
||||
failf(data, "getaddrinfo() thread failed to start");
|
||||
return NULL;
|
||||
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
|
|
|
|||
29
lib/asyn.h
29
lib/asyn.h
|
|
@ -118,11 +118,8 @@ CURLcode Curl_async_await(struct Curl_easy *data,
|
|||
* Each resolver backend must of course make sure to return data in the
|
||||
* correct format to comply with this.
|
||||
*/
|
||||
struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int ip_version,
|
||||
int *waitp);
|
||||
CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname,
|
||||
int port, int ip_version);
|
||||
|
||||
#ifdef USE_ARES
|
||||
/* common functions for c-ares and threaded resolver with HTTPSRR */
|
||||
|
|
@ -132,19 +129,18 @@ CURLcode Curl_ares_pollset(struct Curl_easy *data,
|
|||
ares_channel channel,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
int Curl_ares_perform(ares_channel channel,
|
||||
timediff_t timeout_ms);
|
||||
int Curl_ares_perform(ares_channel channel, timediff_t timeout_ms);
|
||||
#endif
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
/* async resolving implementation using c-ares alone */
|
||||
struct async_ares_ctx {
|
||||
ares_channel channel;
|
||||
int num_pending; /* number of outstanding c-ares requests */
|
||||
int num_pending; /* number of outstanding c-ares requests */
|
||||
struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
|
||||
parts */
|
||||
int ares_status; /* ARES_SUCCESS, ARES_ENOTFOUND, etc. */
|
||||
CURLcode result; /* CURLE_OK or error handling response */
|
||||
int ares_status; /* ARES_SUCCESS, ARES_ENOTFOUND, etc. */
|
||||
CURLcode result; /* CURLE_OK or error handling response */
|
||||
#ifndef HAVE_CARES_GETADDRINFO
|
||||
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
|
||||
#endif
|
||||
|
|
@ -226,11 +222,11 @@ struct doh_probes;
|
|||
#else /* CURLRES_ASYNCH */
|
||||
|
||||
/* convert these functions if an asynch resolver is not used */
|
||||
#define Curl_async_get_impl(x,y) (*(y) = NULL, CURLE_OK)
|
||||
#define Curl_async_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_async_await(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_async_global_init() CURLE_OK
|
||||
#define Curl_async_global_cleanup() Curl_nop_stmt
|
||||
#define Curl_async_get_impl(x, y) (*(y) = NULL, CURLE_OK)
|
||||
#define Curl_async_is_resolved(x, y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_async_await(x, y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_async_global_init() CURLE_OK
|
||||
#define Curl_async_global_cleanup() Curl_nop_stmt
|
||||
|
||||
#endif /* !CURLRES_ASYNCH */
|
||||
|
||||
|
|
@ -270,9 +266,8 @@ void Curl_async_shutdown(struct Curl_easy *data);
|
|||
void Curl_async_destroy(struct Curl_easy *data);
|
||||
#else /* !USE_CURL_ASYNC */
|
||||
#define Curl_async_shutdown(x) Curl_nop_stmt
|
||||
#define Curl_async_destroy(x) Curl_nop_stmt
|
||||
#define Curl_async_destroy(x) Curl_nop_stmt
|
||||
#endif /* USE_CURL_ASYNC */
|
||||
|
||||
|
||||
/********** end of generic resolver interface functions *****************/
|
||||
#endif /* HEADER_CURL_ASYN_H */
|
||||
|
|
|
|||
47
lib/bufq.c
47
lib/bufq.c
|
|
@ -25,10 +25,6 @@
|
|||
#include "curl_setup.h"
|
||||
#include "bufq.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static bool chunk_is_empty(const struct buf_chunk *chunk)
|
||||
{
|
||||
return chunk->r_offset >= chunk->w_offset;
|
||||
|
|
@ -51,9 +47,9 @@ static void chunk_reset(struct buf_chunk *chunk)
|
|||
}
|
||||
|
||||
static size_t chunk_append(struct buf_chunk *chunk,
|
||||
const unsigned char *buf, size_t len)
|
||||
const uint8_t *buf, size_t len)
|
||||
{
|
||||
unsigned char *p = &chunk->x.data[chunk->w_offset];
|
||||
uint8_t *p = &chunk->x.data[chunk->w_offset];
|
||||
size_t n = chunk->dlen - chunk->w_offset;
|
||||
DEBUGASSERT(chunk->dlen >= chunk->w_offset);
|
||||
if(n) {
|
||||
|
|
@ -65,9 +61,9 @@ static size_t chunk_append(struct buf_chunk *chunk,
|
|||
}
|
||||
|
||||
static size_t chunk_read(struct buf_chunk *chunk,
|
||||
unsigned char *buf, size_t len)
|
||||
uint8_t *buf, size_t len)
|
||||
{
|
||||
unsigned char *p = &chunk->x.data[chunk->r_offset];
|
||||
uint8_t *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) {
|
||||
|
|
@ -89,7 +85,7 @@ static CURLcode chunk_slurpn(struct buf_chunk *chunk, size_t max_len,
|
|||
Curl_bufq_reader *reader,
|
||||
void *reader_ctx, size_t *pnread)
|
||||
{
|
||||
unsigned char *p = &chunk->x.data[chunk->w_offset];
|
||||
uint8_t *p = &chunk->x.data[chunk->w_offset];
|
||||
size_t n = chunk->dlen - chunk->w_offset; /* free amount */
|
||||
CURLcode result;
|
||||
|
||||
|
|
@ -108,7 +104,7 @@ static CURLcode chunk_slurpn(struct buf_chunk *chunk, size_t max_len,
|
|||
}
|
||||
|
||||
static void chunk_peek(const struct buf_chunk *chunk,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
const uint8_t **pbuf, size_t *plen)
|
||||
{
|
||||
DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
|
||||
*pbuf = &chunk->x.data[chunk->r_offset];
|
||||
|
|
@ -116,7 +112,7 @@ static void chunk_peek(const struct buf_chunk *chunk,
|
|||
}
|
||||
|
||||
static void chunk_peek_at(const struct buf_chunk *chunk, size_t offset,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
const uint8_t **pbuf, size_t *plen)
|
||||
{
|
||||
offset += chunk->r_offset;
|
||||
DEBUGASSERT(chunk->w_offset >= offset);
|
||||
|
|
@ -143,11 +139,10 @@ static void chunk_list_free(struct buf_chunk **anchor)
|
|||
while(*anchor) {
|
||||
chunk = *anchor;
|
||||
*anchor = chunk->next;
|
||||
free(chunk);
|
||||
curlx_free(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Curl_bufcp_init(struct bufc_pool *pool,
|
||||
size_t chunk_size, size_t spare_max)
|
||||
{
|
||||
|
|
@ -178,7 +173,7 @@ static CURLcode bufcp_take(struct bufc_pool *pool,
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
chunk = calloc(1, sizeof(*chunk) + pool->chunk_size);
|
||||
chunk = curlx_calloc(1, sizeof(*chunk) + pool->chunk_size);
|
||||
if(!chunk) {
|
||||
*pchunk = NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
|
@ -192,7 +187,7 @@ static void bufcp_put(struct bufc_pool *pool,
|
|||
struct buf_chunk *chunk)
|
||||
{
|
||||
if(pool->spare_count >= pool->spare_max) {
|
||||
free(chunk);
|
||||
curlx_free(chunk);
|
||||
}
|
||||
else {
|
||||
chunk_reset(chunk);
|
||||
|
|
@ -311,7 +306,7 @@ static struct buf_chunk *get_spare(struct bufq *q)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
chunk = calloc(1, sizeof(*chunk) + q->chunk_size);
|
||||
chunk = curlx_calloc(1, sizeof(*chunk) + q->chunk_size);
|
||||
if(!chunk)
|
||||
return NULL;
|
||||
chunk->dlen = q->chunk_size;
|
||||
|
|
@ -334,11 +329,11 @@ static void prune_head(struct bufq *q)
|
|||
--q->chunk_count;
|
||||
}
|
||||
else if((q->chunk_count > q->max_chunks) ||
|
||||
(q->opts & BUFQ_OPT_NO_SPARES)) {
|
||||
(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);
|
||||
curlx_free(chunk);
|
||||
--q->chunk_count;
|
||||
}
|
||||
else {
|
||||
|
|
@ -370,7 +365,7 @@ static struct buf_chunk *get_non_full_tail(struct bufq *q)
|
|||
}
|
||||
|
||||
CURLcode Curl_bufq_write(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct buf_chunk *tail;
|
||||
|
|
@ -400,10 +395,10 @@ CURLcode Curl_bufq_cwrite(struct bufq *q,
|
|||
const char *buf, size_t len,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
return Curl_bufq_write(q, (const unsigned char *)buf, len, pnwritten);
|
||||
return Curl_bufq_write(q, (const uint8_t *)buf, len, pnwritten);
|
||||
}
|
||||
|
||||
CURLcode Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
|
||||
CURLcode Curl_bufq_read(struct bufq *q, uint8_t *buf, size_t len,
|
||||
size_t *pnread)
|
||||
{
|
||||
*pnread = 0;
|
||||
|
|
@ -422,11 +417,11 @@ CURLcode Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
|
|||
CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
|
||||
size_t *pnread)
|
||||
{
|
||||
return Curl_bufq_read(q, (unsigned char *)buf, len, pnread);
|
||||
return Curl_bufq_read(q, (uint8_t *)buf, len, pnread);
|
||||
}
|
||||
|
||||
bool Curl_bufq_peek(struct bufq *q,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
const uint8_t **pbuf, size_t *plen)
|
||||
{
|
||||
if(q->head && chunk_is_empty(q->head)) {
|
||||
prune_head(q);
|
||||
|
|
@ -441,7 +436,7 @@ bool Curl_bufq_peek(struct bufq *q,
|
|||
}
|
||||
|
||||
bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
const uint8_t **pbuf, size_t *plen)
|
||||
{
|
||||
struct buf_chunk *c = q->head;
|
||||
size_t clen;
|
||||
|
|
@ -477,7 +472,7 @@ void Curl_bufq_skip(struct bufq *q, size_t amount)
|
|||
CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
|
||||
void *writer_ctx, size_t *pwritten)
|
||||
{
|
||||
const unsigned char *buf;
|
||||
const uint8_t *buf;
|
||||
size_t blen;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
|
|
@ -507,7 +502,7 @@ CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
|
|||
}
|
||||
|
||||
CURLcode Curl_bufq_write_pass(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
Curl_bufq_writer *writer, void *writer_ctx,
|
||||
size_t *pwritten)
|
||||
{
|
||||
|
|
|
|||
18
lib/bufq.h
18
lib/bufq.h
|
|
@ -25,8 +25,6 @@
|
|||
***************************************************************************/
|
||||
#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
|
||||
|
|
@ -38,7 +36,7 @@ struct buf_chunk {
|
|||
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 */
|
||||
uint8_t data[1]; /* the buffer for `dlen` bytes */
|
||||
void *dummy; /* alignment */
|
||||
} x;
|
||||
};
|
||||
|
|
@ -166,7 +164,7 @@ bool Curl_bufq_is_full(const struct bufq *q);
|
|||
* CURLE_AGAIN is returned if the buffer queue is full.
|
||||
*/
|
||||
CURLcode Curl_bufq_write(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
size_t *pnwritten);
|
||||
|
||||
CURLcode Curl_bufq_cwrite(struct bufq *q,
|
||||
|
|
@ -177,7 +175,7 @@ CURLcode Curl_bufq_cwrite(struct bufq *q,
|
|||
* Read buf from the start of the buffer queue. The buf is copied
|
||||
* and the amount of copied bytes is returned.
|
||||
*/
|
||||
CURLcode Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
|
||||
CURLcode Curl_bufq_read(struct bufq *q, uint8_t *buf, size_t len,
|
||||
size_t *pnread);
|
||||
|
||||
CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
|
||||
|
|
@ -193,10 +191,10 @@ CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
|
|||
* is modified, see `Curl_bufq_skip()``
|
||||
*/
|
||||
bool Curl_bufq_peek(struct bufq *q,
|
||||
const unsigned char **pbuf, size_t *plen);
|
||||
const uint8_t **pbuf, size_t *plen);
|
||||
|
||||
bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
|
||||
const unsigned char **pbuf, size_t *plen);
|
||||
const uint8_t **pbuf, size_t *plen);
|
||||
|
||||
/**
|
||||
* Tell the buffer queue to discard `amount` buf bytes at the head
|
||||
|
|
@ -206,7 +204,7 @@ bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
|
|||
void Curl_bufq_skip(struct bufq *q, size_t amount);
|
||||
|
||||
typedef CURLcode Curl_bufq_writer(void *writer_ctx,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
size_t *pwritten);
|
||||
/**
|
||||
* Passes the chunks in the buffer queue to the writer and returns
|
||||
|
|
@ -221,7 +219,7 @@ CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
|
|||
void *writer_ctx, size_t *pwritten);
|
||||
|
||||
typedef CURLcode Curl_bufq_reader(void *reader_ctx,
|
||||
unsigned char *buf, size_t len,
|
||||
uint8_t *buf, size_t len,
|
||||
size_t *pnread);
|
||||
|
||||
/**
|
||||
|
|
@ -253,7 +251,7 @@ CURLcode Curl_bufq_sipn(struct bufq *q, size_t max_len,
|
|||
* amount buffered, chunk size, etc.
|
||||
*/
|
||||
CURLcode Curl_bufq_write_pass(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
Curl_bufq_writer *writer, void *writer_ctx,
|
||||
size_t *pwritten);
|
||||
|
||||
|
|
|
|||
21
lib/bufref.c
21
lib/bufref.c
|
|
@ -27,9 +27,6 @@
|
|||
#include "bufref.h"
|
||||
#include "strdup.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define SIGNATURE 0x5c48e9b2 /* Random pattern. */
|
||||
#endif
|
||||
|
|
@ -79,7 +76,7 @@ void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
|
|||
DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH);
|
||||
|
||||
Curl_bufref_free(br);
|
||||
br->ptr = (const unsigned char *) ptr;
|
||||
br->ptr = (const unsigned char *)ptr;
|
||||
br->len = len;
|
||||
br->dtor = dtor;
|
||||
}
|
||||
|
|
@ -87,7 +84,7 @@ void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
|
|||
/*
|
||||
* Get a pointer to the referenced buffer.
|
||||
*/
|
||||
const unsigned char *Curl_bufref_ptr(const struct bufref *br)
|
||||
const unsigned char *Curl_bufref_uptr(const struct bufref *br)
|
||||
{
|
||||
DEBUGASSERT(br);
|
||||
DEBUGASSERT(br->signature == SIGNATURE);
|
||||
|
|
@ -96,6 +93,18 @@ const unsigned char *Curl_bufref_ptr(const struct bufref *br)
|
|||
return br->ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a pointer to the referenced string.
|
||||
*/
|
||||
const char *Curl_bufref_ptr(const struct bufref *br)
|
||||
{
|
||||
DEBUGASSERT(br);
|
||||
DEBUGASSERT(br->signature == SIGNATURE);
|
||||
DEBUGASSERT(br->ptr || !br->len);
|
||||
|
||||
return (const char *)br->ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the length of the referenced buffer data.
|
||||
*/
|
||||
|
|
@ -108,7 +117,7 @@ size_t Curl_bufref_len(const struct bufref *br)
|
|||
return br->len;
|
||||
}
|
||||
|
||||
CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len)
|
||||
CURLcode Curl_bufref_memdup0(struct bufref *br, const void *ptr, size_t len)
|
||||
{
|
||||
unsigned char *cpy = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,13 +36,16 @@ struct bufref {
|
|||
#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);
|
||||
const char *Curl_bufref_ptr(const struct bufref *br);
|
||||
const unsigned char *Curl_bufref_uptr(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);
|
||||
CURLcode Curl_bufref_memdup0(struct bufref *br, const void *ptr, size_t len);
|
||||
void Curl_bufref_free(struct bufref *br);
|
||||
|
||||
/* return a strdup() version of the buffer */
|
||||
#define Curl_bufref_dup(x) curlx_strdup(Curl_bufref_ptr(x))
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "curlx/dynbuf.h"
|
||||
#include "sendf.h"
|
||||
|
|
@ -43,21 +42,16 @@
|
|||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "transfer.h"
|
||||
#include "multiif.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
H1_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
H1_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||
H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */
|
||||
H1_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||
H1_TUNNEL_ESTABLISHED,
|
||||
H1_TUNNEL_FAILED
|
||||
H1_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
H1_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||
H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */
|
||||
H1_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||
H1_TUNNEL_ESTABLISHED,
|
||||
H1_TUNNEL_FAILED
|
||||
} h1_tunnel_state;
|
||||
|
||||
/* struct for HTTP CONNECT tunneling */
|
||||
|
|
@ -78,7 +72,6 @@ struct h1_tunnel_state {
|
|||
BIT(close_connection);
|
||||
};
|
||||
|
||||
|
||||
static bool tunnel_is_established(struct h1_tunnel_state *ts)
|
||||
{
|
||||
return ts && (ts->tunnel_state == H1_TUNNEL_ESTABLISHED);
|
||||
|
|
@ -116,7 +109,7 @@ static CURLcode tunnel_init(struct Curl_cfilter *cf,
|
|||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
|
||||
ts = calloc(1, sizeof(*ts));
|
||||
ts = curlx_calloc(1, sizeof(*ts));
|
||||
if(!ts)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -126,8 +119,7 @@ static CURLcode tunnel_init(struct Curl_cfilter *cf,
|
|||
curlx_dyn_init(&ts->request_data, DYN_HTTP_REQUEST);
|
||||
Curl_httpchunk_init(data, &ts->ch, TRUE);
|
||||
|
||||
*pts = ts;
|
||||
connkeep(cf->conn, "HTTP proxy CONNECT");
|
||||
*pts = ts;
|
||||
return tunnel_reinit(cf, data, ts);
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +167,7 @@ static void h1_tunnel_go_state(struct Curl_cfilter *cf,
|
|||
curlx_dyn_reset(&ts->rcvbuf);
|
||||
curlx_dyn_reset(&ts->request_data);
|
||||
/* restore the protocol pointer */
|
||||
data->info.httpcode = 0; /* clear it as it might've been used for the
|
||||
data->info.httpcode = 0; /* clear it as it might have been used for the
|
||||
proxy */
|
||||
/* If a proxy-authorization header was used for the proxy, then we should
|
||||
make sure that it is not accidentally used for the document request
|
||||
|
|
@ -195,7 +187,7 @@ static void tunnel_free(struct Curl_cfilter *cf,
|
|||
curlx_dyn_free(&ts->rcvbuf);
|
||||
curlx_dyn_free(&ts->request_data);
|
||||
Curl_httpchunk_free(data, &ts->ch);
|
||||
free(ts);
|
||||
curlx_free(ts);
|
||||
cf->ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -214,9 +206,9 @@ static CURLcode start_CONNECT(struct Curl_cfilter *cf,
|
|||
int http_minor;
|
||||
CURLcode result;
|
||||
|
||||
/* This only happens if we have looped here due to authentication
|
||||
reasons, and we do not really use the newly cloned URL here
|
||||
then. Just free() it. */
|
||||
/* This only happens if we have looped here due to authentication
|
||||
reasons, and we do not really use the newly cloned URL here
|
||||
then. Just free it. */
|
||||
Curl_safefree(data->req.newurl);
|
||||
|
||||
result = Curl_http_proxy_create_CONNECT(&req, cf, data, 1);
|
||||
|
|
@ -247,7 +239,7 @@ static CURLcode send_CONNECT(struct Curl_cfilter *cf,
|
|||
struct h1_tunnel_state *ts,
|
||||
bool *done)
|
||||
{
|
||||
char *buf = curlx_dyn_ptr(&ts->request_data);
|
||||
uint8_t *buf = curlx_dyn_uptr(&ts->request_data);
|
||||
size_t request_len = curlx_dyn_len(&ts->request_data);
|
||||
size_t blen = request_len;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
|
@ -268,7 +260,7 @@ static CURLcode send_CONNECT(struct Curl_cfilter *cf,
|
|||
|
||||
DEBUGASSERT(blen >= nwritten);
|
||||
ts->nsent += nwritten;
|
||||
Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)nwritten);
|
||||
Curl_debug(data, CURLINFO_HEADER_OUT, (char *)buf, nwritten);
|
||||
|
||||
out:
|
||||
if(result)
|
||||
|
|
@ -286,10 +278,8 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
|||
struct SingleRequest *k = &data->req;
|
||||
(void)cf;
|
||||
|
||||
if((checkprefix("WWW-Authenticate:", header) &&
|
||||
(401 == k->httpcode)) ||
|
||||
(checkprefix("Proxy-authenticate:", header) &&
|
||||
(407 == k->httpcode))) {
|
||||
if((checkprefix("WWW-Authenticate:", header) && (401 == k->httpcode)) ||
|
||||
(checkprefix("Proxy-authenticate:", header) && (407 == k->httpcode))) {
|
||||
|
||||
bool proxy = (k->httpcode == 407);
|
||||
char *auth = Curl_copy_header_value(header);
|
||||
|
|
@ -299,13 +289,13 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
|||
CURL_TRC_CF(data, cf, "CONNECT: fwd auth header '%s'", header);
|
||||
result = Curl_http_input_auth(data, proxy, auth);
|
||||
|
||||
free(auth);
|
||||
curlx_free(auth);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else if(checkprefix("Content-Length:", header)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
if(k->httpcode / 100 == 2) {
|
||||
/* A client MUST ignore any Content-Length or Transfer-Encoding
|
||||
header fields received in a successful response to CONNECT.
|
||||
"Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
|
||||
|
|
@ -324,7 +314,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
|||
STRCONST("Connection:"), STRCONST("close")))
|
||||
ts->close_connection = TRUE;
|
||||
else if(checkprefix("Transfer-Encoding:", header)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
if(k->httpcode / 100 == 2) {
|
||||
/* A client MUST ignore any Content-Length or Transfer-Encoding
|
||||
header fields received in a successful response to CONNECT.
|
||||
"Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
|
||||
|
|
@ -350,7 +340,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
|||
ISDIGIT(header[9]) && ISDIGIT(header[10]) && ISDIGIT(header[11]) &&
|
||||
!ISDIGIT(header[12])) {
|
||||
/* store the HTTP code from the proxy */
|
||||
data->info.httpproxycode = k->httpcode = (header[9] - '0') * 100 +
|
||||
data->info.httpproxycode = k->httpcode = (header[9] - '0') * 100 +
|
||||
(header[10] - '0') * 10 + (header[11] - '0');
|
||||
}
|
||||
return result;
|
||||
|
|
@ -384,8 +374,8 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
|||
/* socket buffer drained, return */
|
||||
return CURLE_OK;
|
||||
|
||||
if(Curl_pgrsUpdate(data))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
if(!result)
|
||||
result = Curl_pgrsUpdate(data);
|
||||
|
||||
if(result) {
|
||||
ts->keepon = KEEPON_DONE;
|
||||
|
|
@ -498,8 +488,8 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
|||
ts->keepon = KEEPON_DONE;
|
||||
}
|
||||
|
||||
DEBUGASSERT(ts->keepon == KEEPON_IGNORE
|
||||
|| ts->keepon == KEEPON_DONE);
|
||||
DEBUGASSERT(ts->keepon == KEEPON_IGNORE ||
|
||||
ts->keepon == KEEPON_DONE);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -513,7 +503,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
|||
if(error)
|
||||
result = CURLE_RECV_ERROR;
|
||||
*done = (ts->keepon == KEEPON_DONE);
|
||||
if(!result && *done && data->info.httpproxycode/100 != 2) {
|
||||
if(!result && *done && data->info.httpproxycode / 100 != 2) {
|
||||
/* Deal with the possibly already received authenticate
|
||||
headers. 'newurl' is set to a new URL if we must loop. */
|
||||
result = Curl_http_auth_act(data);
|
||||
|
|
@ -535,10 +525,8 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
|||
return CURLE_RECV_ERROR; /* Need a cfilter close and new bootstrap */
|
||||
|
||||
do {
|
||||
timediff_t check;
|
||||
|
||||
check = Curl_timeleft(data, NULL, TRUE);
|
||||
if(check <= 0) {
|
||||
if(Curl_timeleft_ms(data, TRUE) < 0) {
|
||||
failf(data, "Proxy CONNECT aborted due to timeout");
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
goto out;
|
||||
|
|
@ -567,10 +555,8 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
|||
/* read what is there */
|
||||
CURL_TRC_CF(data, cf, "CONNECT receive");
|
||||
result = recv_CONNECT_resp(cf, data, ts, &done);
|
||||
if(Curl_pgrsUpdate(data)) {
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
goto out;
|
||||
}
|
||||
if(!result)
|
||||
result = Curl_pgrsUpdate(data);
|
||||
/* error or not complete yet. return for more multi-multi */
|
||||
if(result || !done)
|
||||
goto out;
|
||||
|
|
@ -595,7 +581,6 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
|||
CURL_TRC_CF(data, cf, "CONNECT need to close+open");
|
||||
infof(data, "Connect me again please");
|
||||
Curl_conn_cf_close(cf, data);
|
||||
connkeep(conn, "HTTP proxy CONNECT");
|
||||
result = Curl_conn_cf_connect(cf->next, data, &done);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -613,11 +598,9 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
|||
} while(data->req.newurl);
|
||||
|
||||
DEBUGASSERT(ts->tunnel_state == H1_TUNNEL_RESPONSE);
|
||||
if(data->info.httpproxycode/100 != 2) {
|
||||
if(data->info.httpproxycode / 100 != 2) {
|
||||
/* a non-2xx response and we have no next URL to try. */
|
||||
Curl_safefree(data->req.newurl);
|
||||
/* failure, close this connection to avoid reuse */
|
||||
streamclose(conn, "proxy CONNECT failure");
|
||||
h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
|
||||
failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
|
|
@ -673,8 +656,7 @@ out:
|
|||
/* The real request will follow the CONNECT, reset request partially */
|
||||
Curl_req_soft_reset(&data->req, data);
|
||||
Curl_client_reset(data);
|
||||
Curl_pgrsSetUploadCounter(data, 0);
|
||||
Curl_pgrsSetDownloadCounter(data, 0);
|
||||
Curl_pgrsReset(data);
|
||||
|
||||
tunnel_free(cf, data);
|
||||
}
|
||||
|
|
@ -729,10 +711,9 @@ static void cf_h1_proxy_close(struct Curl_cfilter *cf,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
struct Curl_cftype Curl_cft_h1_proxy = {
|
||||
"H1-PROXY",
|
||||
CF_TYPE_IP_CONNECT|CF_TYPE_PROXY,
|
||||
CF_TYPE_IP_CONNECT | CF_TYPE_PROXY,
|
||||
0,
|
||||
cf_h1_proxy_destroy,
|
||||
cf_h1_proxy_connect,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf,
|
|||
|
||||
extern struct Curl_cftype Curl_cft_h1_proxy;
|
||||
|
||||
|
||||
#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */
|
||||
|
||||
#endif /* HEADER_CURL_H1_PROXY_H */
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
defined(USE_NGHTTP2)
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "cfilters.h"
|
||||
|
|
@ -42,18 +43,15 @@
|
|||
#include "multiif.h"
|
||||
#include "sendf.h"
|
||||
#include "select.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "cf-h2-proxy.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define PROXY_H2_CHUNK_SIZE (16*1024)
|
||||
#define PROXY_H2_CHUNK_SIZE (16 * 1024)
|
||||
|
||||
#define PROXY_HTTP2_HUGE_WINDOW_SIZE (100 * 1024 * 1024)
|
||||
#define H2_TUNNEL_WINDOW_SIZE (10 * 1024 * 1024)
|
||||
|
||||
#define PROXY_H2_NW_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE)
|
||||
#define PROXY_H2_NW_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE)
|
||||
#define PROXY_H2_NW_SEND_CHUNKS 1
|
||||
|
||||
#define H2_TUNNEL_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE)
|
||||
|
|
@ -61,11 +59,11 @@
|
|||
|
||||
|
||||
typedef enum {
|
||||
H2_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
H2_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||
H2_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||
H2_TUNNEL_ESTABLISHED,
|
||||
H2_TUNNEL_FAILED
|
||||
H2_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
H2_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||
H2_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||
H2_TUNNEL_ESTABLISHED,
|
||||
H2_TUNNEL_FAILED
|
||||
} h2_tunnel_state;
|
||||
|
||||
struct tunnel_stream {
|
||||
|
|
@ -87,7 +85,6 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
|
|||
const char *hostname;
|
||||
int port;
|
||||
bool ipv6_ip;
|
||||
CURLcode result;
|
||||
|
||||
ts->state = H2_TUNNEL_INIT;
|
||||
ts->stream_id = -1;
|
||||
|
|
@ -95,13 +92,11 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
|
|||
BUFQ_OPT_SOFT_LIMIT);
|
||||
Curl_bufq_init(&ts->sendbuf, PROXY_H2_CHUNK_SIZE, H2_TUNNEL_SEND_CHUNKS);
|
||||
|
||||
result = Curl_http_proxy_get_destination(cf, &hostname, &port, &ipv6_ip);
|
||||
if(result)
|
||||
return result;
|
||||
Curl_http_proxy_get_destination(cf, &hostname, &port, &ipv6_ip);
|
||||
|
||||
ts->authority = /* host:port with IPv6 support */
|
||||
curl_maprintf("%s%s%s:%d", ipv6_ip ? "[":"", hostname,
|
||||
ipv6_ip ? "]" : "", port);
|
||||
/* host:port with IPv6 support */
|
||||
ts->authority = curl_maprintf("%s%s%s:%d", ipv6_ip ? "[" : "", hostname,
|
||||
ipv6_ip ? "]" : "", port);
|
||||
if(!ts->authority)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -190,8 +185,7 @@ struct cf_h2_proxy_ctx {
|
|||
|
||||
/* How to access `call_data` from a cf_h2 filter */
|
||||
#undef CF_CTX_CALL_DATA
|
||||
#define CF_CTX_CALL_DATA(cf) \
|
||||
((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
|
||||
#define CF_CTX_CALL_DATA(cf) ((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
|
||||
|
||||
static void cf_h2_proxy_ctx_clear(struct cf_h2_proxy_ctx *ctx)
|
||||
{
|
||||
|
|
@ -211,7 +205,7 @@ static void cf_h2_proxy_ctx_free(struct cf_h2_proxy_ctx *ctx)
|
|||
{
|
||||
if(ctx) {
|
||||
cf_h2_proxy_ctx_clear(ctx);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +221,7 @@ static void drain_tunnel(struct Curl_cfilter *cf,
|
|||
}
|
||||
|
||||
static CURLcode proxy_h2_nw_out_writer(void *writer_ctx,
|
||||
const unsigned char *buf, size_t buflen,
|
||||
const uint8_t *buf, size_t buflen,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct Curl_cfilter *cf = writer_ctx;
|
||||
|
|
@ -235,7 +229,7 @@ static CURLcode proxy_h2_nw_out_writer(void *writer_ctx,
|
|||
if(cf) {
|
||||
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
||||
CURLcode result;
|
||||
result = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen,
|
||||
result = Curl_conn_cf_send(cf->next, data, buf, buflen,
|
||||
FALSE, pnwritten);
|
||||
CURL_TRC_CF(data, cf, "[0] nw_out_writer(len=%zu) -> %d, %zu",
|
||||
buflen, result, *pnwritten);
|
||||
|
|
@ -249,8 +243,8 @@ static int proxy_h2_client_new(struct Curl_cfilter *cf,
|
|||
{
|
||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||
nghttp2_option *o;
|
||||
nghttp2_mem mem = {NULL, Curl_nghttp2_malloc, Curl_nghttp2_free,
|
||||
Curl_nghttp2_calloc, Curl_nghttp2_realloc};
|
||||
nghttp2_mem mem = { NULL, Curl_nghttp2_malloc, Curl_nghttp2_free,
|
||||
Curl_nghttp2_calloc, Curl_nghttp2_realloc };
|
||||
|
||||
int rc = nghttp2_option_new(&o);
|
||||
if(rc)
|
||||
|
|
@ -314,7 +308,7 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
|
|||
|
||||
rc = nghttp2_session_callbacks_new(&cbs);
|
||||
if(rc) {
|
||||
failf(data, "Couldn't initialize nghttp2 callbacks");
|
||||
failf(data, "Could not initialize nghttp2 callbacks");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -334,7 +328,7 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
|
|||
/* The nghttp2 session is not yet setup, do it */
|
||||
rc = proxy_h2_client_new(cf, cbs);
|
||||
if(rc) {
|
||||
failf(data, "Couldn't initialize nghttp2");
|
||||
failf(data, "Could not initialize nghttp2");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +359,6 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
|
|||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* all set, traffic will be send on connect */
|
||||
result = CURLE_OK;
|
||||
|
||||
|
|
@ -412,32 +405,30 @@ static CURLcode proxy_h2_nw_out_flush(struct Curl_cfilter *cf,
|
|||
* This function returns 0 if it succeeds, or -1 and error code will
|
||||
* be assigned to *err.
|
||||
*/
|
||||
static int proxy_h2_process_pending_input(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
CURLcode *err)
|
||||
static CURLcode proxy_h2_process_pending_input(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||
const unsigned char *buf;
|
||||
size_t blen;
|
||||
size_t blen, nread;
|
||||
ssize_t rv;
|
||||
|
||||
while(Curl_bufq_peek(&ctx->inbufq, &buf, &blen)) {
|
||||
|
||||
rv = nghttp2_session_mem_recv(ctx->h2, (const uint8_t *)buf, blen);
|
||||
CURL_TRC_CF(data, cf, "[0] %zu bytes to nghttp2 -> %zd", blen, rv);
|
||||
if(rv < 0) {
|
||||
if(!curlx_sztouz(rv, &nread)) {
|
||||
failf(data,
|
||||
"process_pending_input: nghttp2_session_mem_recv() returned "
|
||||
"%zd:%s", rv, nghttp2_strerror((int)rv));
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
else if(!rv) {
|
||||
else if(!nread) {
|
||||
/* nghttp2 does not want to process more, but has no error. This
|
||||
* probably cannot happen, but be safe. */
|
||||
break;
|
||||
}
|
||||
Curl_bufq_skip(&ctx->inbufq, (size_t)rv);
|
||||
Curl_bufq_skip(&ctx->inbufq, nread);
|
||||
if(Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||
CURL_TRC_CF(data, cf, "[0] all data in connection buffer processed");
|
||||
break;
|
||||
|
|
@ -447,8 +438,7 @@ static int proxy_h2_process_pending_input(struct Curl_cfilter *cf,
|
|||
"in connection buffer", Curl_bufq_len(&ctx->inbufq));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
|
||||
|
|
@ -462,14 +452,15 @@ static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
|
|||
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||
CURL_TRC_CF(data, cf, "[0] process %zu bytes in connection buffer",
|
||||
Curl_bufq_len(&ctx->inbufq));
|
||||
if(proxy_h2_process_pending_input(cf, data, &result) < 0)
|
||||
result = proxy_h2_process_pending_input(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Receive data from the "lower" filters, e.g. network until
|
||||
* it is time to stop or we have enough data for this stream */
|
||||
while(!ctx->conn_closed && /* not closed the connection */
|
||||
!ctx->tunnel.closed && /* nor the tunnel */
|
||||
while(!ctx->conn_closed && /* not closed the connection */
|
||||
!ctx->tunnel.closed && /* nor the tunnel */
|
||||
Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */
|
||||
!Curl_bufq_is_full(&ctx->tunnel.recvbuf)) {
|
||||
|
||||
|
|
@ -488,14 +479,11 @@ static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
|
|||
break;
|
||||
}
|
||||
|
||||
if(proxy_h2_process_pending_input(cf, data, &result))
|
||||
result = proxy_h2_process_pending_input(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||
connclose(cf->conn, "GOAWAY received");
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
|
@ -554,70 +542,70 @@ static int proxy_h2_fr_print(const nghttp2_frame *frame,
|
|||
char *buffer, size_t blen)
|
||||
{
|
||||
switch(frame->hd.type) {
|
||||
case NGHTTP2_DATA: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[DATA, len=%d, eos=%d, padlen=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM),
|
||||
(int)frame->data.padlen);
|
||||
case NGHTTP2_DATA: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[DATA, len=%d, eos=%d, padlen=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM),
|
||||
(int)frame->data.padlen);
|
||||
}
|
||||
case NGHTTP2_HEADERS: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[HEADERS, len=%d, hend=%d, eos=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
|
||||
}
|
||||
case NGHTTP2_PRIORITY: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PRIORITY, len=%d, flags=%d]",
|
||||
(int)frame->hd.length, frame->hd.flags);
|
||||
}
|
||||
case NGHTTP2_RST_STREAM: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[RST_STREAM, len=%d, flags=%d, error=%u]",
|
||||
(int)frame->hd.length, frame->hd.flags,
|
||||
frame->rst_stream.error_code);
|
||||
}
|
||||
case NGHTTP2_SETTINGS: {
|
||||
if(frame->hd.flags & NGHTTP2_FLAG_ACK) {
|
||||
return curl_msnprintf(buffer, blen, "FRAME[SETTINGS, ack=1]");
|
||||
}
|
||||
case NGHTTP2_HEADERS: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[HEADERS, len=%d, hend=%d, eos=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
|
||||
}
|
||||
case NGHTTP2_PRIORITY: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PRIORITY, len=%d, flags=%d]",
|
||||
(int)frame->hd.length, frame->hd.flags);
|
||||
}
|
||||
case NGHTTP2_RST_STREAM: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[RST_STREAM, len=%d, flags=%d, error=%u]",
|
||||
(int)frame->hd.length, frame->hd.flags,
|
||||
frame->rst_stream.error_code);
|
||||
}
|
||||
case NGHTTP2_SETTINGS: {
|
||||
if(frame->hd.flags & NGHTTP2_FLAG_ACK) {
|
||||
return curl_msnprintf(buffer, blen, "FRAME[SETTINGS, ack=1]");
|
||||
}
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
|
||||
}
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PUSH_PROMISE, len=%d, hend=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
|
||||
case NGHTTP2_PING:
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PING, len=%d, ack=%d]",
|
||||
(int)frame->hd.length,
|
||||
frame->hd.flags & NGHTTP2_FLAG_ACK);
|
||||
case NGHTTP2_GOAWAY: {
|
||||
char scratch[128];
|
||||
size_t s_len = CURL_ARRAYSIZE(scratch);
|
||||
size_t len = (frame->goaway.opaque_data_len < s_len) ?
|
||||
frame->goaway.opaque_data_len : s_len-1;
|
||||
if(len)
|
||||
memcpy(scratch, frame->goaway.opaque_data, len);
|
||||
scratch[len] = '\0';
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[GOAWAY, error=%d, reason='%s', "
|
||||
"last_stream=%d]", frame->goaway.error_code,
|
||||
scratch, frame->goaway.last_stream_id);
|
||||
}
|
||||
case NGHTTP2_WINDOW_UPDATE: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[WINDOW_UPDATE, incr=%d]",
|
||||
frame->window_update.window_size_increment);
|
||||
}
|
||||
default:
|
||||
return curl_msnprintf(buffer, blen, "FRAME[%d, len=%d, flags=%d]",
|
||||
frame->hd.type, (int)frame->hd.length,
|
||||
frame->hd.flags);
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
|
||||
}
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PUSH_PROMISE, len=%d, hend=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
|
||||
case NGHTTP2_PING:
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PING, len=%d, ack=%d]",
|
||||
(int)frame->hd.length,
|
||||
frame->hd.flags & NGHTTP2_FLAG_ACK);
|
||||
case NGHTTP2_GOAWAY: {
|
||||
char scratch[128];
|
||||
size_t s_len = CURL_ARRAYSIZE(scratch);
|
||||
size_t len = (frame->goaway.opaque_data_len < s_len) ?
|
||||
frame->goaway.opaque_data_len : s_len-1;
|
||||
if(len)
|
||||
memcpy(scratch, frame->goaway.opaque_data, len);
|
||||
scratch[len] = '\0';
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[GOAWAY, error=%d, reason='%s', "
|
||||
"last_stream=%d]", frame->goaway.error_code,
|
||||
scratch, frame->goaway.last_stream_id);
|
||||
}
|
||||
case NGHTTP2_WINDOW_UPDATE: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[WINDOW_UPDATE, incr=%d]",
|
||||
frame->window_update.window_size_increment);
|
||||
}
|
||||
default:
|
||||
return curl_msnprintf(buffer, blen, "FRAME[%d, len=%d, flags=%d]",
|
||||
frame->hd.type, (int)frame->hd.length,
|
||||
frame->hd.flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -633,7 +621,7 @@ static int proxy_h2_on_frame_send(nghttp2_session *session,
|
|||
if(data && Curl_trc_cf_is_verbose(cf, data)) {
|
||||
char buffer[256];
|
||||
int len;
|
||||
len = proxy_h2_fr_print(frame, buffer, sizeof(buffer)-1);
|
||||
len = proxy_h2_fr_print(frame, buffer, sizeof(buffer) - 1);
|
||||
buffer[len] = 0;
|
||||
CURL_TRC_CF(data, cf, "[%d] -> %s", frame->hd.stream_id, buffer);
|
||||
}
|
||||
|
|
@ -656,9 +644,9 @@ static int proxy_h2_on_frame_recv(nghttp2_session *session,
|
|||
if(Curl_trc_cf_is_verbose(cf, data)) {
|
||||
char buffer[256];
|
||||
int len;
|
||||
len = proxy_h2_fr_print(frame, buffer, sizeof(buffer)-1);
|
||||
len = proxy_h2_fr_print(frame, buffer, sizeof(buffer) - 1);
|
||||
buffer[len] = 0;
|
||||
CURL_TRC_CF(data, cf, "[%d] <- %s",frame->hd.stream_id, buffer);
|
||||
CURL_TRC_CF(data, cf, "[%d] <- %s", frame->hd.stream_id, buffer);
|
||||
}
|
||||
#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
|
|
@ -851,7 +839,7 @@ static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
|
|||
#endif
|
||||
}
|
||||
/* tunnel.recbuf has soft limit, any success MUST add all data */
|
||||
DEBUGASSERT((size_t)nwritten == len);
|
||||
DEBUGASSERT(nwritten == len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -927,7 +915,7 @@ static CURLcode proxy_h2_submit(int32_t *pstream_id,
|
|||
result = CURLE_OK;
|
||||
|
||||
out:
|
||||
free(nva);
|
||||
curlx_free(nva);
|
||||
Curl_dynhds_free(&h2_headers);
|
||||
*pstream_id = stream_id;
|
||||
return result;
|
||||
|
|
@ -974,7 +962,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
|
|||
(void)cf;
|
||||
|
||||
DEBUGASSERT(ts->resp);
|
||||
if(ts->resp->status/100 == 2) {
|
||||
if(ts->resp->status / 100 == 2) {
|
||||
infof(data, "CONNECT tunnel established, response %d", ts->resp->status);
|
||||
h2_tunnel_go_state(cf, ts, H2_TUNNEL_ESTABLISHED, data);
|
||||
return CURLE_OK;
|
||||
|
|
@ -1077,7 +1065,6 @@ static CURLcode cf_h2_proxy_connect(struct Curl_cfilter *cf,
|
|||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct cf_call_data save;
|
||||
timediff_t check;
|
||||
struct tunnel_stream *ts = &ctx->tunnel;
|
||||
|
||||
if(cf->connected) {
|
||||
|
|
@ -1102,8 +1089,7 @@ static CURLcode cf_h2_proxy_connect(struct Curl_cfilter *cf,
|
|||
}
|
||||
DEBUGASSERT(ts->authority);
|
||||
|
||||
check = Curl_timeleft(data, NULL, TRUE);
|
||||
if(check <= 0) {
|
||||
if(Curl_timeleft_ms(data, TRUE) < 0) {
|
||||
failf(data, "Proxy CONNECT aborted due to timeout");
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
goto out;
|
||||
|
|
@ -1234,7 +1220,7 @@ static CURLcode cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
|
|||
c_exhaust = !nghttp2_session_get_remote_window_size(ctx->h2);
|
||||
s_exhaust = ctx->tunnel.stream_id >= 0 &&
|
||||
!nghttp2_session_get_stream_remote_window_size(
|
||||
ctx->h2, ctx->tunnel.stream_id);
|
||||
ctx->h2, ctx->tunnel.stream_id);
|
||||
want_recv = (want_recv || c_exhaust || s_exhaust);
|
||||
want_send = (!s_exhaust && want_send) ||
|
||||
(!c_exhaust && nghttp2_session_want_write(ctx->h2)) ||
|
||||
|
|
@ -1271,7 +1257,7 @@ static CURLcode h2_handle_tunnel_close(struct Curl_cfilter *cf,
|
|||
if(ctx->tunnel.error == NGHTTP2_REFUSED_STREAM) {
|
||||
CURL_TRC_CF(data, cf, "[%d] REFUSED_STREAM, try again on a new "
|
||||
"connection", ctx->tunnel.stream_id);
|
||||
connclose(cf->conn, "REFUSED_STREAM"); /* do not use this anymore */
|
||||
failf(data, "proxy server refused HTTP/2 stream");
|
||||
return CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */
|
||||
}
|
||||
else if(ctx->tunnel.error != NGHTTP2_NO_ERROR) {
|
||||
|
|
@ -1366,7 +1352,7 @@ out:
|
|||
|
||||
static CURLcode cf_h2_proxy_send(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||
|
|
@ -1428,7 +1414,7 @@ out:
|
|||
"h2 windows %d-%d (stream-conn), buffers %zu-%zu (stream-conn)",
|
||||
ctx->tunnel.stream_id, len, result, *pnwritten,
|
||||
nghttp2_session_get_stream_remote_window_size(
|
||||
ctx->h2, ctx->tunnel.stream_id),
|
||||
ctx->h2, ctx->tunnel.stream_id),
|
||||
nghttp2_session_get_remote_window_size(ctx->h2),
|
||||
Curl_bufq_len(&ctx->tunnel.sendbuf),
|
||||
Curl_bufq_len(&ctx->outbufq));
|
||||
|
|
@ -1489,7 +1475,7 @@ static bool proxy_h2_connisalive(struct Curl_cfilter *cf,
|
|||
*input_pending = FALSE;
|
||||
result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread);
|
||||
if(!result) {
|
||||
if(proxy_h2_process_pending_input(cf, data, &result) < 0)
|
||||
if(proxy_h2_process_pending_input(cf, data))
|
||||
/* immediate error, considered dead */
|
||||
alive = FALSE;
|
||||
else {
|
||||
|
|
@ -1580,7 +1566,7 @@ static CURLcode cf_h2_proxy_cntrl(struct Curl_cfilter *cf,
|
|||
|
||||
struct Curl_cftype Curl_cft_h2_proxy = {
|
||||
"H2-PROXY",
|
||||
CF_TYPE_IP_CONNECT|CF_TYPE_PROXY,
|
||||
CF_TYPE_IP_CONNECT | CF_TYPE_PROXY,
|
||||
CURL_LOG_LVL_NONE,
|
||||
cf_h2_proxy_destroy,
|
||||
cf_h2_proxy_connect,
|
||||
|
|
@ -1604,7 +1590,7 @@ CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf,
|
|||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
(void)data;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx)
|
||||
goto out;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,23 +26,17 @@
|
|||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "cfilters.h"
|
||||
#include "cf-haproxy.h"
|
||||
#include "curl_trc.h"
|
||||
#include "multiif.h"
|
||||
#include "select.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#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_INIT, /* init/default/no tunnel state */
|
||||
HAPROXY_SEND, /* data_out being sent */
|
||||
HAPROXY_DONE /* all work done */
|
||||
} haproxy_state;
|
||||
|
||||
struct cf_haproxy_ctx {
|
||||
|
|
@ -61,11 +55,11 @@ static void cf_haproxy_ctx_free(struct cf_haproxy_ctx *ctx)
|
|||
{
|
||||
if(ctx) {
|
||||
curlx_dyn_free(&ctx->data_out);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
|
||||
static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_haproxy_ctx *ctx = cf->ctx;
|
||||
|
|
@ -133,7 +127,7 @@ static CURLcode cf_haproxy_connect(struct Curl_cfilter *cf,
|
|||
if(len > 0) {
|
||||
size_t nwritten;
|
||||
result = Curl_conn_cf_send(cf->next, data,
|
||||
curlx_dyn_ptr(&ctx->data_out), len, FALSE,
|
||||
curlx_dyn_uptr(&ctx->data_out), len, FALSE,
|
||||
&nwritten);
|
||||
if(result) {
|
||||
if(result != CURLE_AGAIN)
|
||||
|
|
@ -217,7 +211,7 @@ static CURLcode cf_haproxy_create(struct Curl_cfilter **pcf,
|
|||
CURLcode result;
|
||||
|
||||
(void)data;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#ifndef CURL_DISABLE_HTTP
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "curl_trc.h"
|
||||
#include "cfilters.h"
|
||||
#include "connect.h"
|
||||
|
|
@ -35,13 +34,10 @@
|
|||
#include "multiif.h"
|
||||
#include "cf-https-connect.h"
|
||||
#include "http2.h"
|
||||
#include "progress.h"
|
||||
#include "select.h"
|
||||
#include "vquic/vquic.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef enum {
|
||||
CF_HC_INIT,
|
||||
CF_HC_CONNECT,
|
||||
|
|
@ -55,7 +51,7 @@ struct cf_hc_baller {
|
|||
CURLcode result;
|
||||
struct curltime started;
|
||||
int reply_ms;
|
||||
unsigned char transport;
|
||||
uint8_t transport;
|
||||
enum alpnid alpn_id;
|
||||
BIT(shutdown);
|
||||
};
|
||||
|
|
@ -124,7 +120,7 @@ struct cf_hc_ctx {
|
|||
|
||||
static void cf_hc_baller_assign(struct cf_hc_baller *b,
|
||||
enum alpnid alpn_id,
|
||||
unsigned char def_transport)
|
||||
uint8_t def_transport)
|
||||
{
|
||||
b->alpn_id = alpn_id;
|
||||
b->transport = def_transport;
|
||||
|
|
@ -148,12 +144,12 @@ static void cf_hc_baller_assign(struct cf_hc_baller *b,
|
|||
static void cf_hc_baller_init(struct cf_hc_baller *b,
|
||||
struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
struct Curl_cfilter *save = cf->next;
|
||||
|
||||
cf->next = NULL;
|
||||
b->started = curlx_now();
|
||||
b->started = *Curl_pgrs_now(data);
|
||||
switch(b->alpn_id) {
|
||||
case ALPN_h3:
|
||||
transport = TRNSPRT_QUIC;
|
||||
|
|
@ -215,12 +211,13 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
|
|||
reply_ms = cf_hc_baller_reply_ms(winner, data);
|
||||
if(reply_ms >= 0)
|
||||
CURL_TRC_CF(data, cf, "connect+handshake %s: %dms, 1st data: %dms",
|
||||
winner->name, (int)curlx_timediff(curlx_now(),
|
||||
winner->started), reply_ms);
|
||||
winner->name,
|
||||
(int)curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&winner->started), reply_ms);
|
||||
else
|
||||
CURL_TRC_CF(data, cf, "deferred handshake %s: %dms",
|
||||
winner->name, (int)curlx_timediff(curlx_now(),
|
||||
winner->started));
|
||||
winner->name, (int)curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&winner->started));
|
||||
|
||||
/* install the winning filter below this one. */
|
||||
cf->next = winner->cf;
|
||||
|
|
@ -247,7 +244,6 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
static bool time_to_start_next(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
size_t idx, struct curltime now)
|
||||
|
|
@ -269,7 +265,7 @@ static bool time_to_start_next(struct Curl_cfilter *cf,
|
|||
ctx->ballers[idx].name);
|
||||
return TRUE;
|
||||
}
|
||||
elapsed_ms = curlx_timediff(now, ctx->started);
|
||||
elapsed_ms = curlx_ptimediff_ms(&now, &ctx->started);
|
||||
if(elapsed_ms >= ctx->hard_eyeballs_timeout_ms) {
|
||||
CURL_TRC_CF(data, cf, "hard timeout of %" FMT_TIMEDIFF_T "ms reached, "
|
||||
"starting %s",
|
||||
|
|
@ -297,7 +293,6 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
|
|||
bool *done)
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
struct curltime now;
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t i, failed_ballers;
|
||||
|
||||
|
|
@ -307,14 +302,13 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
|
|||
}
|
||||
|
||||
*done = FALSE;
|
||||
now = curlx_now();
|
||||
switch(ctx->state) {
|
||||
case CF_HC_INIT:
|
||||
DEBUGASSERT(!cf->next);
|
||||
for(i = 0; i < ctx->baller_count; i++)
|
||||
DEBUGASSERT(!ctx->ballers[i].cf);
|
||||
CURL_TRC_CF(data, cf, "connect, init");
|
||||
ctx->started = now;
|
||||
ctx->started = *Curl_pgrs_now(data);
|
||||
cf_hc_baller_init(&ctx->ballers[0], cf, data, ctx->ballers[0].transport);
|
||||
if(ctx->baller_count > 1) {
|
||||
Curl_expire(data, ctx->soft_eyeballs_timeout_ms, EXPIRE_ALPN_EYEBALLS);
|
||||
|
|
@ -333,7 +327,7 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
|
|||
}
|
||||
}
|
||||
|
||||
if(time_to_start_next(cf, data, 1, now)) {
|
||||
if(time_to_start_next(cf, data, 1, *Curl_pgrs_now(data))) {
|
||||
cf_hc_baller_init(&ctx->ballers[1], cf, data, ctx->ballers[1].transport);
|
||||
}
|
||||
|
||||
|
|
@ -474,7 +468,7 @@ static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
|
|||
struct Curl_cfilter *cfb = ctx->ballers[i].cf;
|
||||
memset(&t, 0, sizeof(t));
|
||||
if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
|
||||
if((t.tv_sec || t.tv_usec) && curlx_timediff_us(t, tmax) > 0)
|
||||
if((t.tv_sec || t.tv_usec) && curlx_ptimediff_us(&t, &tmax) > 0)
|
||||
tmax = t;
|
||||
}
|
||||
}
|
||||
|
|
@ -580,27 +574,29 @@ struct Curl_cftype Curl_cft_http_connect = {
|
|||
static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
enum alpnid *alpnids, size_t alpn_count,
|
||||
unsigned char def_transport)
|
||||
uint8_t def_transport)
|
||||
{
|
||||
struct Curl_cfilter *cf = NULL;
|
||||
struct cf_hc_ctx *ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t i;
|
||||
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DEBUGASSERT(alpnids);
|
||||
DEBUGASSERT(alpn_count);
|
||||
DEBUGASSERT(alpn_count <= CURL_ARRAYSIZE(ctx->ballers));
|
||||
if(!alpn_count || (alpn_count > CURL_ARRAYSIZE(ctx->ballers))) {
|
||||
failf(data, "https-connect filter create with unsupported %zu ALPN ids",
|
||||
alpn_count);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
result = CURLE_FAILED_INIT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for(i = 0; i < alpn_count; ++i)
|
||||
cf_hc_baller_assign(&ctx->ballers[i], alpnids[i], def_transport);
|
||||
for(; i < CURL_ARRAYSIZE(ctx->ballers); ++i)
|
||||
|
|
@ -615,7 +611,7 @@ static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
|
|||
|
||||
out:
|
||||
*pcf = result ? NULL : cf;
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -623,7 +619,7 @@ static CURLcode cf_http_connect_add(struct Curl_easy *data,
|
|||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
enum alpnid *alpn_ids, size_t alpn_count,
|
||||
unsigned char def_transport)
|
||||
uint8_t def_transport)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
|
@ -712,6 +708,31 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data,
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Add preferred HTTP version ALPN first */
|
||||
if(data->state.http_neg.preferred &&
|
||||
(alpn_count < CURL_ARRAYSIZE(alpn_ids)) &&
|
||||
(data->state.http_neg.preferred & data->state.http_neg.allowed)) {
|
||||
enum alpnid alpn_pref = ALPN_none;
|
||||
switch(data->state.http_neg.preferred) {
|
||||
case CURL_HTTP_V3x:
|
||||
if(!Curl_conn_may_http3(data, conn, conn->transport_wanted))
|
||||
alpn_pref = ALPN_h3;
|
||||
break;
|
||||
case CURL_HTTP_V2x:
|
||||
alpn_pref = ALPN_h2;
|
||||
break;
|
||||
case CURL_HTTP_V1x:
|
||||
alpn_pref = ALPN_h1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(alpn_pref &&
|
||||
!cf_https_alpns_contain(alpn_pref, alpn_ids, alpn_count)) {
|
||||
alpn_ids[alpn_count++] = alpn_pref;
|
||||
}
|
||||
}
|
||||
|
||||
if((alpn_count < CURL_ARRAYSIZE(alpn_ids)) &&
|
||||
(data->state.http_neg.wanted & CURL_HTTP_V3x) &&
|
||||
!cf_https_alpns_contain(ALPN_h3, alpn_ids, alpn_count)) {
|
||||
|
|
|
|||
|
|
@ -44,6 +44,5 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data,
|
|||
struct connectdata *conn,
|
||||
int sockindex);
|
||||
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP */
|
||||
#endif /* HEADER_CURL_CF_HTTP_H */
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@
|
|||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h> /* <netinet/tcp.h> may need it */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h> /* for sockaddr_un */
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_TCP_H
|
||||
#include <linux/tcp.h>
|
||||
#elif defined(HAVE_NETINET_TCP_H)
|
||||
|
|
@ -60,13 +57,9 @@
|
|||
#include "select.h"
|
||||
#include "vquic/vquic.h" /* for quic cfilters */
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
struct transport_provider {
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
cf_ip_connect_create *cf_create;
|
||||
};
|
||||
|
||||
|
|
@ -87,7 +80,7 @@ struct transport_provider transport_providers[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static cf_ip_connect_create *get_cf_create(int transport)
|
||||
static cf_ip_connect_create *get_cf_create(uint8_t transport)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) {
|
||||
|
|
@ -99,7 +92,7 @@ static cf_ip_connect_create *get_cf_create(int transport)
|
|||
|
||||
#ifdef UNITTESTS
|
||||
/* used by unit2600.c */
|
||||
void Curl_debug_set_transport_provider(int transport,
|
||||
void Curl_debug_set_transport_provider(uint8_t transport,
|
||||
cf_ip_connect_create *cf_create)
|
||||
{
|
||||
size_t i;
|
||||
|
|
@ -112,7 +105,6 @@ void Curl_debug_set_transport_provider(int transport,
|
|||
}
|
||||
#endif /* UNITTESTS */
|
||||
|
||||
|
||||
struct cf_ai_iter {
|
||||
const struct Curl_addrinfo *head;
|
||||
const struct Curl_addrinfo *last;
|
||||
|
|
@ -172,7 +164,7 @@ struct cf_ip_attempt {
|
|||
struct curltime started; /* start of current attempt */
|
||||
CURLcode result;
|
||||
int ai_family;
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
int error;
|
||||
BIT(connected); /* cf has connected */
|
||||
BIT(shutdown); /* cf has shutdown */
|
||||
|
|
@ -186,7 +178,7 @@ static void cf_ip_attempt_free(struct cf_ip_attempt *a,
|
|||
if(a) {
|
||||
if(a->cf)
|
||||
Curl_conn_cf_discard_chain(&a->cf, data);
|
||||
free(a);
|
||||
curlx_free(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +187,7 @@ static CURLcode cf_ip_attempt_new(struct cf_ip_attempt **pa,
|
|||
struct Curl_easy *data,
|
||||
const struct Curl_addrinfo *addr,
|
||||
int ai_family,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
cf_ip_connect_create *cf_create)
|
||||
{
|
||||
struct Curl_cfilter *wcf;
|
||||
|
|
@ -203,7 +195,7 @@ static CURLcode cf_ip_attempt_new(struct cf_ip_attempt **pa,
|
|||
CURLcode result = CURLE_OK;
|
||||
|
||||
*pa = NULL;
|
||||
a = calloc(1, sizeof(*a));
|
||||
a = curlx_calloc(1, sizeof(*a));
|
||||
if(!a)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -237,7 +229,7 @@ static CURLcode cf_ip_attempt_connect(struct cf_ip_attempt *a,
|
|||
bool *connected)
|
||||
{
|
||||
*connected = a->connected;
|
||||
if(!a->result && !*connected) {
|
||||
if(!a->result && !*connected) {
|
||||
/* evaluate again */
|
||||
a->result = Curl_conn_cf_connect(a->cf, data, connected);
|
||||
|
||||
|
|
@ -264,7 +256,7 @@ struct cf_ip_ballers {
|
|||
struct curltime last_attempt_started;
|
||||
timediff_t attempt_delay_ms;
|
||||
int last_attempt_ai_family;
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
};
|
||||
|
||||
static CURLcode cf_ip_attempt_restart(struct cf_ip_attempt *a,
|
||||
|
|
@ -315,7 +307,7 @@ static void cf_ip_ballers_clear(struct Curl_cfilter *cf,
|
|||
static CURLcode cf_ip_ballers_init(struct cf_ip_ballers *bs, int ip_version,
|
||||
const struct Curl_addrinfo *addr_list,
|
||||
cf_ip_connect_create *cf_create,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
timediff_t attempt_delay_ms)
|
||||
{
|
||||
memset(bs, 0, sizeof(*bs));
|
||||
|
|
@ -358,7 +350,6 @@ static CURLcode cf_ip_ballers_run(struct cf_ip_ballers *bs,
|
|||
CURLcode result = CURLE_OK;
|
||||
struct cf_ip_attempt *a = NULL, **panchor;
|
||||
bool do_more;
|
||||
struct curltime now;
|
||||
timediff_t next_expire_ms;
|
||||
int i, inconclusive, ongoing;
|
||||
|
||||
|
|
@ -366,7 +357,6 @@ static CURLcode cf_ip_ballers_run(struct cf_ip_ballers *bs,
|
|||
return CURLE_OK;
|
||||
|
||||
evaluate:
|
||||
now = curlx_now();
|
||||
ongoing = inconclusive = 0;
|
||||
|
||||
/* check if a running baller connects now */
|
||||
|
|
@ -403,7 +393,7 @@ evaluate:
|
|||
/* no attempt connected yet, start another one? */
|
||||
if(!ongoing) {
|
||||
if(!bs->started.tv_sec && !bs->started.tv_usec)
|
||||
bs->started = now;
|
||||
bs->started = *Curl_pgrs_now(data);
|
||||
do_more = TRUE;
|
||||
}
|
||||
else {
|
||||
|
|
@ -413,8 +403,8 @@ evaluate:
|
|||
more_possible = cf_ai_iter_has_more(&bs->ipv6_iter);
|
||||
#endif
|
||||
do_more = more_possible &&
|
||||
(curlx_timediff(now, bs->last_attempt_started) >=
|
||||
bs->attempt_delay_ms);
|
||||
(curlx_ptimediff_ms(Curl_pgrs_now(data), &bs->last_attempt_started) >=
|
||||
bs->attempt_delay_ms);
|
||||
if(do_more)
|
||||
CURL_TRC_CF(data, cf, "happy eyeballs timeout expired, "
|
||||
"start next attempt");
|
||||
|
|
@ -427,9 +417,9 @@ evaluate:
|
|||
int ai_family = 0;
|
||||
#ifdef USE_IPV6
|
||||
if((bs->last_attempt_ai_family == AF_INET) ||
|
||||
!cf_ai_iter_has_more(&bs->addr_iter)) {
|
||||
addr = cf_ai_iter_next(&bs->ipv6_iter);
|
||||
ai_family = bs->ipv6_iter.ai_family;
|
||||
!cf_ai_iter_has_more(&bs->addr_iter)) {
|
||||
addr = cf_ai_iter_next(&bs->ipv6_iter);
|
||||
ai_family = bs->ipv6_iter.ai_family;
|
||||
}
|
||||
#endif
|
||||
if(!addr) {
|
||||
|
|
@ -452,7 +442,7 @@ evaluate:
|
|||
while(*panchor)
|
||||
panchor = &((*panchor)->next);
|
||||
*panchor = a;
|
||||
bs->last_attempt_started = now;
|
||||
bs->last_attempt_started = *Curl_pgrs_now(data);
|
||||
bs->last_attempt_ai_family = ai_family;
|
||||
/* and run everything again */
|
||||
goto evaluate;
|
||||
|
|
@ -460,7 +450,8 @@ evaluate:
|
|||
else if(inconclusive) {
|
||||
/* tried all addresses, no success but some where inconclusive.
|
||||
* Let's restart the inconclusive ones. */
|
||||
timediff_t since_ms = curlx_timediff(now, bs->last_attempt_started);
|
||||
timediff_t since_ms =
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data), &bs->last_attempt_started);
|
||||
timediff_t delay_ms = bs->attempt_delay_ms - since_ms;
|
||||
if(delay_ms <= 0) {
|
||||
CURL_TRC_CF(data, cf, "all attempts inconclusive, restarting one");
|
||||
|
|
@ -473,7 +464,7 @@ evaluate:
|
|||
CURL_TRC_CF(data, cf, "restarted baller %d -> %d", i, result);
|
||||
if(result) /* serious failure */
|
||||
goto out;
|
||||
bs->last_attempt_started = now;
|
||||
bs->last_attempt_started = *Curl_pgrs_now(data);
|
||||
goto evaluate;
|
||||
}
|
||||
DEBUGASSERT(0); /* should not come here */
|
||||
|
|
@ -505,10 +496,11 @@ out:
|
|||
bool more_possible;
|
||||
|
||||
/* when do we need to be called again? */
|
||||
next_expire_ms = Curl_timeleft(data, &now, TRUE);
|
||||
next_expire_ms = Curl_timeleft_ms(data, TRUE);
|
||||
if(next_expire_ms <= 0) {
|
||||
failf(data, "Connection timeout after %" FMT_OFF_T " ms",
|
||||
curlx_timediff(now, data->progress.t_startsingle));
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&data->progress.t_startsingle));
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
|
|
@ -519,7 +511,8 @@ out:
|
|||
#endif
|
||||
if(more_possible) {
|
||||
timediff_t expire_ms, elapsed_ms;
|
||||
elapsed_ms = curlx_timediff(now, bs->last_attempt_started);
|
||||
elapsed_ms =
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data), &bs->last_attempt_started);
|
||||
expire_ms = CURLMAX(bs->attempt_delay_ms - elapsed_ms, 0);
|
||||
next_expire_ms = CURLMIN(next_expire_ms, expire_ms);
|
||||
if(next_expire_ms <= 0) {
|
||||
|
|
@ -595,7 +588,7 @@ static struct curltime cf_ip_ballers_max_time(struct cf_ip_ballers *bs,
|
|||
for(a = bs->running; a; a = a->next) {
|
||||
memset(&t, 0, sizeof(t));
|
||||
if(!a->cf->cft->query(a->cf, data, query, NULL, &t)) {
|
||||
if((t.tv_sec || t.tv_usec) && curlx_timediff_us(t, tmax) > 0)
|
||||
if((t.tv_sec || t.tv_usec) && curlx_ptimediff_us(&t, &tmax) > 0)
|
||||
tmax = t;
|
||||
}
|
||||
}
|
||||
|
|
@ -618,7 +611,6 @@ static int cf_ip_ballers_min_reply_ms(struct cf_ip_ballers *bs,
|
|||
return reply_ms;
|
||||
}
|
||||
|
||||
|
||||
typedef enum {
|
||||
SCFST_INIT,
|
||||
SCFST_WAITING,
|
||||
|
|
@ -626,14 +618,13 @@ typedef enum {
|
|||
} cf_connect_state;
|
||||
|
||||
struct cf_ip_happy_ctx {
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
cf_ip_connect_create *cf_create;
|
||||
cf_connect_state state;
|
||||
struct cf_ip_ballers ballers;
|
||||
struct curltime started;
|
||||
};
|
||||
|
||||
|
||||
static CURLcode is_connected(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
bool *connected)
|
||||
|
|
@ -682,7 +673,8 @@ static CURLcode is_connected(struct Curl_cfilter *cf,
|
|||
proxy_name ? "via " : "",
|
||||
proxy_name ? proxy_name : "",
|
||||
proxy_name ? " " : "",
|
||||
curlx_timediff(curlx_now(), data->progress.t_startsingle),
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&data->progress.t_startsingle),
|
||||
curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
|
|
@ -707,14 +699,14 @@ static CURLcode start_connect(struct Curl_cfilter *cf,
|
|||
if(!dns)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
if(Curl_timeleft(data, NULL, TRUE) < 0) {
|
||||
if(Curl_timeleft_ms(data, TRUE) < 0) {
|
||||
/* a precaution, no need to continue if time already is up */
|
||||
failf(data, "Connection time-out");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
CURL_TRC_CF(data, cf, "init ip ballers for transport %d", ctx->transport);
|
||||
ctx->started = curlx_now();
|
||||
CURL_TRC_CF(data, cf, "init ip ballers for transport %u", ctx->transport);
|
||||
ctx->started = *Curl_pgrs_now(data);
|
||||
return cf_ip_ballers_init(&ctx->ballers, cf->conn->ip_version,
|
||||
dns->addr, ctx->cf_create, ctx->transport,
|
||||
data->set.happy_eyeballs_timeout);
|
||||
|
|
@ -778,50 +770,50 @@ static CURLcode cf_ip_happy_connect(struct Curl_cfilter *cf,
|
|||
*done = FALSE;
|
||||
|
||||
switch(ctx->state) {
|
||||
case SCFST_INIT:
|
||||
DEBUGASSERT(CURL_SOCKET_BAD == Curl_conn_cf_get_socket(cf, data));
|
||||
DEBUGASSERT(!cf->connected);
|
||||
result = start_connect(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
ctx->state = SCFST_WAITING;
|
||||
FALLTHROUGH();
|
||||
case SCFST_WAITING:
|
||||
result = is_connected(cf, data, done);
|
||||
if(!result && *done) {
|
||||
DEBUGASSERT(ctx->ballers.winner);
|
||||
DEBUGASSERT(ctx->ballers.winner->cf);
|
||||
DEBUGASSERT(ctx->ballers.winner->cf->connected);
|
||||
/* we have a winner. Install and activate it.
|
||||
* close/free all others. */
|
||||
ctx->state = SCFST_DONE;
|
||||
cf->connected = TRUE;
|
||||
cf->next = ctx->ballers.winner->cf;
|
||||
ctx->ballers.winner->cf = NULL;
|
||||
cf_ip_happy_ctx_clear(cf, data);
|
||||
Curl_expire_done(data, EXPIRE_HAPPY_EYEBALLS);
|
||||
case SCFST_INIT:
|
||||
DEBUGASSERT(CURL_SOCKET_BAD == Curl_conn_cf_get_socket(cf, data));
|
||||
DEBUGASSERT(!cf->connected);
|
||||
result = start_connect(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
ctx->state = SCFST_WAITING;
|
||||
FALLTHROUGH();
|
||||
case SCFST_WAITING:
|
||||
result = is_connected(cf, data, done);
|
||||
if(!result && *done) {
|
||||
DEBUGASSERT(ctx->ballers.winner);
|
||||
DEBUGASSERT(ctx->ballers.winner->cf);
|
||||
DEBUGASSERT(ctx->ballers.winner->cf->connected);
|
||||
/* we have a winner. Install and activate it.
|
||||
* close/free all others. */
|
||||
ctx->state = SCFST_DONE;
|
||||
cf->connected = TRUE;
|
||||
cf->next = ctx->ballers.winner->cf;
|
||||
ctx->ballers.winner->cf = NULL;
|
||||
cf_ip_happy_ctx_clear(cf, data);
|
||||
Curl_expire_done(data, EXPIRE_HAPPY_EYEBALLS);
|
||||
|
||||
if(cf->conn->handler->protocol & PROTO_FAMILY_SSH)
|
||||
Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */
|
||||
if(cf->conn->handler->protocol & PROTO_FAMILY_SSH)
|
||||
Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
if(Curl_trc_cf_is_verbose(cf, data)) {
|
||||
struct ip_quadruple ipquad;
|
||||
bool is_ipv6;
|
||||
if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) {
|
||||
const char *host;
|
||||
int port;
|
||||
Curl_conn_get_current_host(data, cf->sockindex, &host, &port);
|
||||
CURL_TRC_CF(data, cf, "Connected to %s (%s) port %u",
|
||||
host, ipquad.remote_ip, ipquad.remote_port);
|
||||
}
|
||||
if(Curl_trc_cf_is_verbose(cf, data)) {
|
||||
struct ip_quadruple ipquad;
|
||||
bool is_ipv6;
|
||||
if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) {
|
||||
const char *host;
|
||||
int port;
|
||||
Curl_conn_get_current_host(data, cf->sockindex, &host, &port);
|
||||
CURL_TRC_CF(data, cf, "Connected to %s (%s) port %u",
|
||||
host, ipquad.remote_ip, ipquad.remote_port);
|
||||
}
|
||||
#endif
|
||||
data->info.numconnects++; /* to track the # of connections made */
|
||||
}
|
||||
break;
|
||||
case SCFST_DONE:
|
||||
*done = TRUE;
|
||||
break;
|
||||
#endif
|
||||
data->info.numconnects++; /* to track the # of connections made */
|
||||
}
|
||||
break;
|
||||
case SCFST_DONE:
|
||||
*done = TRUE;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -933,7 +925,7 @@ static CURLcode cf_ip_happy_create(struct Curl_cfilter **pcf,
|
|||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
cf_ip_connect_create *cf_create,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
struct cf_ip_happy_ctx *ctx = NULL;
|
||||
CURLcode result;
|
||||
|
|
@ -941,7 +933,7 @@ static CURLcode cf_ip_happy_create(struct Curl_cfilter **pcf,
|
|||
(void)data;
|
||||
(void)conn;
|
||||
*pcf = NULL;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
|
|
@ -954,14 +946,14 @@ static CURLcode cf_ip_happy_create(struct Curl_cfilter **pcf,
|
|||
out:
|
||||
if(result) {
|
||||
Curl_safefree(*pcf);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
cf_ip_connect_create *cf_create;
|
||||
struct Curl_cfilter *cf;
|
||||
|
|
@ -971,7 +963,7 @@ CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at,
|
|||
DEBUGASSERT(cf_at);
|
||||
cf_create = get_cf_create(transport);
|
||||
if(!cf_create) {
|
||||
CURL_TRC_CF(data, cf_at, "unsupported transport type %d", transport);
|
||||
CURL_TRC_CF(data, cf_at, "unsupported transport type %u", transport);
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
result = cf_ip_happy_create(&cf, data, cf_at->conn, cf_create, transport);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "curl_setup.h"
|
||||
|
||||
#include "curlx/nonblock.h" /* for curlx_nonblock() */
|
||||
#include "sockaddr.h"
|
||||
|
||||
/**
|
||||
* Create a cfilter for making an "ip" connection to the
|
||||
|
|
@ -43,16 +42,16 @@ typedef CURLcode cf_ip_connect_create(struct Curl_cfilter **pcf,
|
|||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
extern struct Curl_cftype Curl_cft_ip_happy;
|
||||
|
||||
#ifdef UNITTESTS
|
||||
void Curl_debug_set_transport_provider(int transport,
|
||||
void Curl_debug_set_transport_provider(uint8_t transport,
|
||||
cf_ip_connect_create *cf_create);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
538
lib/cf-socket.c
538
lib/cf-socket.c
File diff suppressed because it is too large
Load diff
|
|
@ -26,7 +26,7 @@
|
|||
#include "curl_setup.h"
|
||||
|
||||
#include "curlx/nonblock.h" /* for curlx_nonblock() */
|
||||
#include "sockaddr.h"
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
|
||||
struct Curl_addrinfo;
|
||||
struct Curl_cfilter;
|
||||
|
|
@ -52,12 +52,12 @@ struct Curl_sockaddr_ex {
|
|||
struct Curl_sockaddr_storage buf;
|
||||
} addr;
|
||||
};
|
||||
#define curl_sa_addr addr.sa
|
||||
#define curl_sa_addr addr.sa
|
||||
#define curl_sa_addrbuf addr.buf
|
||||
|
||||
/*
|
||||
* Parse interface option, and return the interface name and the host part.
|
||||
*/
|
||||
*/
|
||||
CURLcode Curl_parse_interface(const char *input,
|
||||
char **dev, char **iface, char **host);
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ CURLcode Curl_parse_interface(const char *input,
|
|||
CURLcode Curl_socket_open(struct Curl_easy *data,
|
||||
const struct Curl_addrinfo *ai,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
curl_socket_t *sockfd);
|
||||
|
||||
int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn,
|
||||
|
|
@ -103,7 +103,7 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
|
|||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
/**
|
||||
* Creates a cfilter that opens a UDP socket to the given address
|
||||
|
|
@ -116,7 +116,7 @@ CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
|
|||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
/**
|
||||
* Creates a cfilter that opens a UNIX socket to the given address
|
||||
|
|
@ -129,7 +129,7 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
|
|||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
/**
|
||||
* Creates a cfilter that keeps a listening socket.
|
||||
|
|
|
|||
|
|
@ -30,17 +30,11 @@
|
|||
#include "connect.h"
|
||||
#include "url.h"
|
||||
#include "sendf.h"
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "multiif.h"
|
||||
#include "progress.h"
|
||||
#include "select.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static void cf_cntrl_update_info(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
|
|
@ -63,8 +57,8 @@ CURLcode Curl_cf_def_shutdown(struct Curl_cfilter *cf,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void conn_report_connect_stats(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static void conn_report_connect_stats(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
|
|
@ -85,7 +79,7 @@ bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
|
|||
}
|
||||
|
||||
CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
if(cf->next)
|
||||
|
|
@ -143,7 +137,7 @@ void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
|
|||
*/
|
||||
cf->next = NULL;
|
||||
cf->cft->destroy(cf, data);
|
||||
free(cf);
|
||||
curlx_free(cf);
|
||||
cf = cfn;
|
||||
}
|
||||
}
|
||||
|
|
@ -173,7 +167,6 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done)
|
|||
struct Curl_cfilter *cf;
|
||||
CURLcode result = CURLE_OK;
|
||||
timediff_t timeout_ms;
|
||||
struct curltime now;
|
||||
|
||||
DEBUGASSERT(data->conn);
|
||||
|
||||
|
|
@ -191,14 +184,13 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done)
|
|||
}
|
||||
|
||||
*done = FALSE;
|
||||
now = curlx_now();
|
||||
if(!Curl_shutdown_started(data, sockindex)) {
|
||||
CURL_TRC_M(data, "shutdown start on%s connection",
|
||||
sockindex ? " secondary" : "");
|
||||
Curl_shutdown_start(data, sockindex, 0, &now);
|
||||
Curl_shutdown_start(data, sockindex, 0);
|
||||
}
|
||||
else {
|
||||
timeout_ms = Curl_shutdown_timeleft(data->conn, sockindex, &now);
|
||||
timeout_ms = Curl_shutdown_timeleft(data, data->conn, sockindex);
|
||||
if(timeout_ms < 0) {
|
||||
/* info message, since this might be regarded as acceptable */
|
||||
infof(data, "shutdown timeout");
|
||||
|
|
@ -246,7 +238,7 @@ CURLcode Curl_cf_recv(struct Curl_easy *data, int num, char *buf,
|
|||
}
|
||||
|
||||
CURLcode Curl_cf_send(struct Curl_easy *data, int num,
|
||||
const void *mem, size_t len, bool eos,
|
||||
const uint8_t *mem, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
|
|
@ -296,12 +288,11 @@ CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf,
|
|||
}
|
||||
|
||||
static CURLcode cf_bufq_writer(void *writer_ctx,
|
||||
const unsigned char *buf, size_t buflen,
|
||||
const uint8_t *buf, size_t buflen,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct cf_io_ctx *io = writer_ctx;
|
||||
return Curl_conn_cf_send(io->cf, io->data, (const char *)buf,
|
||||
buflen, FALSE, pnwritten);
|
||||
return Curl_conn_cf_send(io->cf, io->data, buf, buflen, FALSE, pnwritten);
|
||||
}
|
||||
|
||||
CURLcode Curl_cf_send_bufq(struct Curl_cfilter *cf,
|
||||
|
|
@ -333,7 +324,7 @@ CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
|
|||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
DEBUGASSERT(cft);
|
||||
cf = calloc(1, sizeof(*cf));
|
||||
cf = curlx_calloc(1, sizeof(*cf));
|
||||
if(!cf)
|
||||
goto out;
|
||||
|
||||
|
|
@ -422,7 +413,7 @@ void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
}
|
||||
|
||||
CURLcode Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
if(cf)
|
||||
|
|
@ -508,17 +499,16 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
|||
* persist information at the connection. E.g. cf-socket sets the
|
||||
* socket and ip related information. */
|
||||
cf_cntrl_update_info(data, data->conn);
|
||||
conn_report_connect_stats(data, data->conn);
|
||||
data->conn->keepalive = curlx_now();
|
||||
conn_report_connect_stats(cf, data);
|
||||
data->conn->keepalive = *Curl_pgrs_now(data);
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
result = cf_verboseconnect(data, cf);
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
else if(result) {
|
||||
CURL_TRC_CF(data, cf, "Curl_conn_connect(), filter returned %d",
|
||||
result);
|
||||
conn_report_connect_stats(data, data->conn);
|
||||
CURL_TRC_CF(data, cf, "Curl_conn_connect(), filter returned %d", result);
|
||||
conn_report_connect_stats(cf, data);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -526,7 +516,7 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
|||
goto out;
|
||||
else {
|
||||
/* check allowed time left */
|
||||
const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
const timediff_t timeout_ms = Curl_timeleft_ms(data, TRUE);
|
||||
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
||||
int rc;
|
||||
|
||||
|
|
@ -583,7 +573,11 @@ bool Curl_conn_is_connected(struct connectdata *conn, int sockindex)
|
|||
if(!CONN_SOCK_IDX_VALID(sockindex))
|
||||
return FALSE;
|
||||
cf = conn->cfilter[sockindex];
|
||||
return cf && cf->connected;
|
||||
if(cf)
|
||||
return cf->connected;
|
||||
else if(conn->handler->flags & PROTOPT_NONETWORK)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex)
|
||||
|
|
@ -658,7 +652,7 @@ bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex)
|
|||
for(; cf; cf = cf->next) {
|
||||
if(cf->cft->flags & CF_TYPE_MULTIPLEX)
|
||||
return TRUE;
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_SSL))
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT | CF_TYPE_SSL))
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
@ -696,7 +690,7 @@ unsigned char Curl_conn_http_version(struct Curl_easy *data,
|
|||
v = (unsigned char)value;
|
||||
break;
|
||||
}
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_SSL))
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT | CF_TYPE_SSL))
|
||||
break;
|
||||
}
|
||||
return (unsigned char)(result ? 0 : v);
|
||||
|
|
@ -808,9 +802,9 @@ void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex,
|
|||
cf = CONN_SOCK_IDX_VALID(sockindex) ? data->conn->cfilter[sockindex] : NULL;
|
||||
/* Find the "lowest" tunneling proxy filter that has not connected yet. */
|
||||
while(cf && !cf->connected) {
|
||||
if((cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_PROXY)) ==
|
||||
(CF_TYPE_IP_CONNECT|CF_TYPE_PROXY))
|
||||
cf_proxy = cf;
|
||||
if((cf->cft->flags & (CF_TYPE_IP_CONNECT | CF_TYPE_PROXY)) ==
|
||||
(CF_TYPE_IP_CONNECT | CF_TYPE_PROXY))
|
||||
cf_proxy = cf;
|
||||
cf = cf->next;
|
||||
}
|
||||
/* cf_proxy (!= NULL) is not connected yet. It is talking
|
||||
|
|
@ -931,19 +925,6 @@ Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex)
|
|||
return cf ? cf_get_remote_addr(cf, data) : NULL;
|
||||
}
|
||||
|
||||
void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
if(conn && CONN_SOCK_IDX_VALID(sockindex)) {
|
||||
struct Curl_cfilter *cf = conn->cfilter[sockindex];
|
||||
if(cf)
|
||||
(void)Curl_conn_cf_cntrl(cf, data, TRUE,
|
||||
CF_CTRL_FORGET_SOCKET, 0, NULL);
|
||||
fake_sclose(conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode cf_cntrl_all(struct connectdata *conn,
|
||||
struct Curl_easy *data,
|
||||
bool ignore_result,
|
||||
|
|
@ -963,8 +944,7 @@ static CURLcode cf_cntrl_all(struct connectdata *conn,
|
|||
|
||||
CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data)
|
||||
{
|
||||
return cf_cntrl_all(data->conn, data, FALSE,
|
||||
CF_CTRL_DATA_SETUP, 0, NULL);
|
||||
return cf_cntrl_all(data->conn, data, FALSE, CF_CTRL_DATA_SETUP, 0, NULL);
|
||||
}
|
||||
|
||||
CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex)
|
||||
|
|
@ -1008,10 +988,9 @@ static void cf_cntrl_update_info(struct Curl_easy *data,
|
|||
/**
|
||||
* Update connection statistics
|
||||
*/
|
||||
static void conn_report_connect_stats(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
static void conn_report_connect_stats(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
|
||||
if(cf) {
|
||||
struct curltime connected;
|
||||
struct curltime appconnected;
|
||||
|
|
@ -1119,8 +1098,7 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
|
|||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
#ifdef DEBUGBUILD
|
||||
if(write_len) {
|
||||
/* Allow debug builds to override this logic to force short sends
|
||||
*/
|
||||
/* Allow debug builds to override this logic to force short sends */
|
||||
const char *p = getenv("CURL_SMALLSENDS");
|
||||
if(p) {
|
||||
curl_off_t altsize;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf,
|
|||
|
||||
typedef CURLcode Curl_cft_send(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data, /* transfer */
|
||||
const void *buf, /* data to write */
|
||||
const uint8_t *buf, /* data to write */
|
||||
size_t len, /* amount to write */
|
||||
bool eos, /* last chunk */
|
||||
size_t *pnwritten); /* how much sent */
|
||||
|
|
@ -116,16 +116,16 @@ typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf,
|
|||
* "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_SETUP 4 /* 0 NULL first fail */
|
||||
/* unused now 5 */
|
||||
#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 */
|
||||
/* data event arg1 arg2 return */
|
||||
#define CF_CTRL_DATA_SETUP 4 /* 0 NULL first fail */
|
||||
/* unused now 5 */
|
||||
#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 */
|
||||
#define CF_CTRL_FLUSH (256+2) /* 0 NULL first fail */
|
||||
#define CF_CTRL_CONN_INFO_UPDATE (256 + 0) /* 0 NULL ignored */
|
||||
#define CF_CTRL_FORGET_SOCKET (256 + 1) /* 0 NULL ignored */
|
||||
#define CF_CTRL_FLUSH (256 + 2) /* 0 NULL first fail */
|
||||
|
||||
/**
|
||||
* Handle event/control for the filter.
|
||||
|
|
@ -135,7 +135,6 @@ 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
|
||||
|
|
@ -210,21 +209,21 @@ typedef CURLcode Curl_cft_query(struct Curl_cfilter *cf,
|
|||
|
||||
/* 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_shutdown *do_shutdown; /* shutdown conn */
|
||||
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_shutdown *do_shutdown; /* shutdown conn */
|
||||
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 */
|
||||
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 */
|
||||
|
|
@ -250,7 +249,7 @@ CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
|||
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
|
||||
const struct Curl_easy *data);
|
||||
CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten);
|
||||
CURLcode Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
char *buf, size_t len, size_t *pnread);
|
||||
|
|
@ -317,13 +316,12 @@ 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 *done);
|
||||
void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data);
|
||||
CURLcode Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten);
|
||||
CURLcode Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
char *buf, size_t len, size_t *pnread);
|
||||
|
|
@ -426,7 +424,7 @@ const char *Curl_conn_get_alpn_negotiated(struct Curl_easy *data,
|
|||
|
||||
/**
|
||||
* Close the filter chain at `sockindex` for connection `data->conn`.
|
||||
* Filters remain in place and may be connected again afterwards.
|
||||
* Filters remain in place and may be connected again afterwards.
|
||||
*/
|
||||
void Curl_conn_close(struct Curl_easy *data, int sockindex);
|
||||
|
||||
|
|
@ -508,12 +506,12 @@ CURLcode Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf,
|
|||
* in `*pnwritten` or on error.
|
||||
*/
|
||||
CURLcode Curl_cf_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten);
|
||||
|
||||
/**
|
||||
* Receive bytes from connection filter `cf` into `bufq`.
|
||||
* Convenience wrappter around `Curl_bufq_sipn()`,
|
||||
* Convenience wrapper around `Curl_bufq_sipn()`,
|
||||
* so users do not have to implement a callback.
|
||||
*/
|
||||
CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf,
|
||||
|
|
@ -622,7 +620,6 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
|
|||
const void *buf, size_t blen, bool eos,
|
||||
size_t *pnwritten);
|
||||
|
||||
|
||||
/**
|
||||
* Types and macros used to keep the current easy handle in filter calls,
|
||||
* allowing for nested invocations. See #10336.
|
||||
|
|
@ -654,7 +651,7 @@ struct cf_call_data {
|
|||
* a member in the cfilter's `ctx`.
|
||||
*
|
||||
* #define CF_CTX_CALL_DATA(cf) -> struct cf_call_data instance
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
|
||||
|
|
@ -688,7 +685,6 @@ struct cf_call_data {
|
|||
|
||||
#endif /* !DEBUGBUILD */
|
||||
|
||||
#define CF_DATA_CURRENT(cf) \
|
||||
((cf)? (CF_CTX_CALL_DATA(cf).data) : NULL)
|
||||
#define CF_DATA_CURRENT(cf) ((cf) ? (CF_CTX_CALL_DATA(cf).data) : NULL)
|
||||
|
||||
#endif /* HEADER_CURL_CFILTERS_H */
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@
|
|||
/* 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
|
||||
* a local wrapper in setup-os400.h) in a thread-safe way: we can then
|
||||
* configure getaddrinfo() as such and get rid of gethostbyname_r() without
|
||||
* loss of threadsafeness. */
|
||||
* loss of thread-safeness. */
|
||||
#undef HAVE_GETHOSTBYNAME_R
|
||||
#undef HAVE_GETHOSTBYNAME_R_3
|
||||
#undef HAVE_GETHOSTBYNAME_R_5
|
||||
|
|
@ -102,9 +102,15 @@
|
|||
/* Define if you have GSS API. */
|
||||
#define HAVE_GSSAPI
|
||||
|
||||
/* Define if you have the <gssapi.h> header file. */
|
||||
#define HAVE_GSSAPI_H
|
||||
|
||||
/* Define if you have the GNU gssapi libraries */
|
||||
#undef HAVE_GSSGNU
|
||||
|
||||
/* Define if you have the `localtime_r' function. */
|
||||
#define HAVE_LOCALTIME_R
|
||||
|
||||
/* Define if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H
|
||||
|
||||
|
|
@ -129,7 +135,6 @@
|
|||
/* 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__
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
#define HAVE_LIBGEN_H 1
|
||||
#define HAVE_LIBZ 1
|
||||
#define HAVE_LOCALE_H 1
|
||||
#define HAVE_LOCALTIME_R 1
|
||||
#define HAVE_LONGLONG 1
|
||||
#define HAVE_NETDB_H 1
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
/* Hand crafted config file for Windows */
|
||||
/* ================================================================ */
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
/* Define some minimum and default build targets for Visual Studio */
|
||||
#ifdef _MSC_VER
|
||||
/* VS2012 default target settings and minimum build target check. */
|
||||
|
|
@ -58,63 +56,45 @@
|
|||
# error VS2012 does not support build targets prior to Windows Vista
|
||||
# endif
|
||||
# endif
|
||||
/* Default target settings and minimum build target check for
|
||||
VS2008 and VS2010 */
|
||||
/* VS2010 default target settings and minimum build target check. */
|
||||
# else
|
||||
# define VS2008_MIN_TARGET 0x0501 /* XP */
|
||||
/* VS2008 default build target is Windows Vista (0x0600).
|
||||
/* VS2010 default build target is Windows 7 (0x0601).
|
||||
We override default target to be Windows XP. */
|
||||
# define VS2008_DEF_TARGET 0x0501 /* XP */
|
||||
# define VS2010_MIN_TARGET 0x0501 /* XP */
|
||||
# define VS2010_DEF_TARGET 0x0501 /* XP */
|
||||
|
||||
# ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT VS2008_DEF_TARGET
|
||||
# define _WIN32_WINNT VS2010_DEF_TARGET
|
||||
# endif
|
||||
# ifndef WINVER
|
||||
# define WINVER VS2008_DEF_TARGET
|
||||
# define WINVER VS2010_DEF_TARGET
|
||||
# endif
|
||||
# if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET)
|
||||
# error VS2008 does not support build targets prior to Windows XP
|
||||
# if (_WIN32_WINNT < VS2010_MIN_TARGET) || (WINVER < VS2010_MIN_TARGET)
|
||||
# error VS2010 does not support build targets prior to Windows XP
|
||||
# endif
|
||||
# endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#endif /* UNDER_CE */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* HEADER FILES */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the <arpa/inet.h> header file. */
|
||||
/* #define HAVE_ARPA_INET_H 1 */
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1 /* exists on __MINGW32CE__ */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define if you have the <io.h> header file. */
|
||||
#define HAVE_IO_H 1 /* exists on __MINGW32CE__ */
|
||||
#define HAVE_IO_H 1
|
||||
|
||||
/* Define if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
#ifndef UNDER_CE
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || defined(__MINGW32__)
|
||||
#define HAVE_STDBOOL_H 1 /* exists on __MINGW32CE__ */
|
||||
#endif
|
||||
#define HAVE_STDBOOL_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(__MINGW32__)
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#define HAVE_STDINT_H 1
|
||||
#endif
|
||||
|
||||
|
|
@ -123,24 +103,12 @@
|
|||
#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/sockio.h> header file. */
|
||||
/* #define HAVE_SYS_SOCKIO_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. */
|
||||
#ifdef __MINGW32__
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
|
@ -159,10 +127,8 @@
|
|||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if bool is an available type. */
|
||||
#ifndef UNDER_CE
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || defined(__MINGW32__)
|
||||
#define HAVE_BOOL_T 1 /* exists on __MINGW32CE__ */
|
||||
#endif
|
||||
#define HAVE_BOOL_T 1
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
|
@ -200,7 +166,6 @@
|
|||
/* Define if you have the select function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
#ifndef UNDER_CE
|
||||
/* Define if you have the setlocale function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
|
|
@ -209,7 +174,6 @@
|
|||
|
||||
/* Define if you have the _setmode function. */
|
||||
#define HAVE__SETMODE 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the socket function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
|
@ -276,9 +240,7 @@
|
|||
#endif
|
||||
|
||||
/* Define to 1 if you have the signal function. */
|
||||
#ifndef UNDER_CE
|
||||
#define HAVE_SIGNAL 1
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* TYPEDEF REPLACEMENTS */
|
||||
|
|
@ -303,9 +265,6 @@
|
|||
/* 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
|
||||
|
||||
|
|
@ -323,15 +282,6 @@
|
|||
/* 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) || defined(__MINGW32__)
|
||||
#define HAVE_LONGLONG 1
|
||||
|
|
@ -347,11 +297,9 @@
|
|||
#endif
|
||||
|
||||
/* Windows XP is required for freeaddrinfo, getaddrinfo */
|
||||
#ifndef UNDER_CE
|
||||
#define HAVE_FREEADDRINFO 1
|
||||
#define HAVE_GETADDRINFO 1
|
||||
#define HAVE_GETADDRINFO_THREADSAFE 1
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* STRUCT RELATED */
|
||||
|
|
@ -370,28 +318,19 @@
|
|||
/* LARGE FILE SUPPORT */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
# define USE_WIN32_LARGE_FILES
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
# ifdef __MINGW32__
|
||||
# ifndef _FILE_OFFSET_BITS
|
||||
# define _FILE_OFFSET_BITS 64
|
||||
# endif
|
||||
# endif
|
||||
#ifdef __MINGW32__
|
||||
# undef _FILE_OFFSET_BITS
|
||||
# define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
/* Define to the size of `off_t', as computed by sizeof. */
|
||||
#if defined(__MINGW32__) && \
|
||||
defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
|
||||
#ifdef __MINGW32__
|
||||
# define SIZEOF_OFF_T 8
|
||||
#else
|
||||
# define SIZEOF_OFF_T 4
|
||||
#endif
|
||||
|
||||
#endif /* UNDER_CE */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* DNS RESOLVER SPECIALTY */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
|
@ -400,9 +339,6 @@
|
|||
* 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)
|
||||
|
|
@ -417,10 +353,7 @@
|
|||
/* LDAP SUPPORT */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#ifdef CURL_HAS_OPENLDAP_LDAPSDK
|
||||
#undef USE_WIN32_LDAP
|
||||
#define HAVE_LDAP_URL_PARSE 1
|
||||
#elif !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE)
|
||||
#ifndef CURL_WINDOWS_UWP
|
||||
#undef HAVE_LDAP_URL_PARSE
|
||||
#define HAVE_LDAP_SSL 1
|
||||
#define USE_WIN32_LDAP 1
|
||||
|
|
@ -432,9 +365,7 @@
|
|||
#endif
|
||||
|
||||
/* Define to use Unix sockets. */
|
||||
#ifndef UNDER_CE
|
||||
#define USE_UNIX_SOCKETS
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* ADDITIONAL DEFINITIONS */
|
||||
|
|
@ -442,52 +373,19 @@
|
|||
|
||||
/* Define cpu-machine-OS */
|
||||
#ifndef CURL_OS
|
||||
# ifdef UNDER_CE
|
||||
# ifdef _M_ARM
|
||||
# define CURL_OS "arm-pc-win32ce"
|
||||
# else
|
||||
# define CURL_OS "i386-pc-win32ce"
|
||||
# endif
|
||||
# else /* !UNDER_CE */
|
||||
# if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */
|
||||
# define CURL_OS "i386-pc-win32"
|
||||
# elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (VS2005+ or gcc) */
|
||||
# define CURL_OS "x86_64-pc-win32"
|
||||
# elif defined(_M_IA64) || defined(__ia64__) /* Itanium */
|
||||
# define CURL_OS "ia64-pc-win32"
|
||||
# elif defined(_M_ARM_NT) || defined(__arm__) /* ARMv7-Thumb2 */
|
||||
# define CURL_OS "thumbv7a-pc-win32"
|
||||
# elif defined(_M_ARM64) || defined(__aarch64__) /* ARM64 (Windows 10) */
|
||||
# define CURL_OS "aarch64-pc-win32"
|
||||
# else
|
||||
# define CURL_OS "unknown-pc-win32"
|
||||
# endif
|
||||
# endif /* UNDER_CE */
|
||||
# if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */
|
||||
# define CURL_OS "i386-pc-win32"
|
||||
# elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (VS2005+ or gcc) */
|
||||
# define CURL_OS "x86_64-pc-win32"
|
||||
# elif defined(_M_IA64) || defined(__ia64__) /* Itanium */
|
||||
# define CURL_OS "ia64-pc-win32"
|
||||
# elif defined(_M_ARM_NT) || defined(__arm__) /* ARMv7-Thumb2 */
|
||||
# define CURL_OS "thumbv7a-pc-win32"
|
||||
# elif defined(_M_ARM64) || defined(__aarch64__) /* ARM64 (Windows 10) */
|
||||
# define CURL_OS "aarch64-pc-win32"
|
||||
# else
|
||||
# define CURL_OS "unknown-pc-win32"
|
||||
# endif
|
||||
#endif /* !CURL_OS */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Windows CE */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#ifdef UNDER_CE
|
||||
|
||||
#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
|
||||
|
||||
#ifndef _MSC_VER
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
extern int stat(const char *path, struct stat *buffer);
|
||||
#endif
|
||||
|
||||
#endif /* UNDER_CE */
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_WIN32_H */
|
||||
|
|
|
|||
122
lib/conncache.c
122
lib/conncache.c
|
|
@ -25,36 +25,26 @@
|
|||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "cfilters.h"
|
||||
#include "progress.h"
|
||||
#include "multiif.h"
|
||||
#include "multi_ev.h"
|
||||
#include "sendf.h"
|
||||
#include "cshutdn.h"
|
||||
#include "conncache.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "share.h"
|
||||
#include "curl_share.h"
|
||||
#include "sigpipe.h"
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "uint-table.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
#define CPOOL_IS_LOCKED(c) ((c) && (c)->locked)
|
||||
|
||||
#define CPOOL_LOCK(c,d) \
|
||||
#define CPOOL_LOCK(c, d) \
|
||||
do { \
|
||||
if((c)) { \
|
||||
if(c) { \
|
||||
if(CURL_SHARE_KEEP_CONNECT((c)->share)) \
|
||||
Curl_share_lock((d), CURL_LOCK_DATA_CONNECT, \
|
||||
CURL_LOCK_ACCESS_SINGLE); \
|
||||
|
|
@ -63,9 +53,9 @@
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
#define CPOOL_UNLOCK(c,d) \
|
||||
#define CPOOL_UNLOCK(c,d) \
|
||||
do { \
|
||||
if((c)) { \
|
||||
if(c) { \
|
||||
DEBUGASSERT((c)->locked); \
|
||||
(c)->locked = FALSE; \
|
||||
if(CURL_SHARE_KEEP_CONNECT((c)->share)) \
|
||||
|
|
@ -73,7 +63,6 @@
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* A list of connections to the same destination. */
|
||||
struct cpool_bundle {
|
||||
struct Curl_llist conns; /* connections in the bundle */
|
||||
|
|
@ -81,7 +70,6 @@ struct cpool_bundle {
|
|||
char dest[1]; /* destination of bundle, allocated to keep dest_len bytes */
|
||||
};
|
||||
|
||||
|
||||
static void cpool_discard_conn(struct cpool *cpool,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
|
|
@ -92,7 +80,7 @@ static struct cpool_bundle *cpool_bundle_create(const char *dest)
|
|||
struct cpool_bundle *bundle;
|
||||
size_t dest_len = strlen(dest) + 1;
|
||||
|
||||
bundle = calloc(1, sizeof(*bundle) + dest_len - 1);
|
||||
bundle = curlx_calloc(1, sizeof(*bundle) + dest_len - 1);
|
||||
if(!bundle)
|
||||
return NULL;
|
||||
Curl_llist_init(&bundle->conns, NULL);
|
||||
|
|
@ -104,7 +92,7 @@ static struct cpool_bundle *cpool_bundle_create(const char *dest)
|
|||
static void cpool_bundle_destroy(struct cpool_bundle *bundle)
|
||||
{
|
||||
DEBUGASSERT(!Curl_llist_count(&bundle->conns));
|
||||
free(bundle);
|
||||
curlx_free(bundle);
|
||||
}
|
||||
|
||||
/* Add a connection to a bundle */
|
||||
|
|
@ -165,7 +153,6 @@ static struct connectdata *cpool_get_first(struct cpool *cpool)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct cpool_bundle *cpool_find_bundle(struct cpool *cpool,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
|
|
@ -173,7 +160,6 @@ static struct cpool_bundle *cpool_find_bundle(struct cpool *cpool,
|
|||
conn->destination, strlen(conn->destination) + 1);
|
||||
}
|
||||
|
||||
|
||||
static void cpool_remove_bundle(struct cpool *cpool,
|
||||
struct cpool_bundle *bundle)
|
||||
{
|
||||
|
|
@ -182,7 +168,6 @@ static void cpool_remove_bundle(struct cpool *cpool,
|
|||
Curl_hash_delete(&cpool->dest2bundle, bundle->dest, bundle->dest_len);
|
||||
}
|
||||
|
||||
|
||||
static void cpool_remove_conn(struct cpool *cpool,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
|
|
@ -220,7 +205,6 @@ void Curl_cpool_destroy(struct cpool *cpool)
|
|||
while(conn) {
|
||||
cpool_remove_conn(cpool, conn);
|
||||
sigpipe_apply(cpool->idata, &pipe_st);
|
||||
connclose(conn, "kill all");
|
||||
cpool_discard_conn(cpool, cpool->idata, conn, FALSE);
|
||||
conn = cpool_get_first(cpool);
|
||||
}
|
||||
|
|
@ -265,8 +249,8 @@ void Curl_cpool_xfer_init(struct Curl_easy *data)
|
|||
}
|
||||
}
|
||||
|
||||
static struct cpool_bundle *
|
||||
cpool_add_bundle(struct cpool *cpool, struct connectdata *conn)
|
||||
static struct cpool_bundle *cpool_add_bundle(struct cpool *cpool,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct cpool_bundle *bundle;
|
||||
|
||||
|
|
@ -283,23 +267,22 @@ cpool_add_bundle(struct cpool *cpool, struct connectdata *conn)
|
|||
}
|
||||
|
||||
static struct connectdata *
|
||||
cpool_bundle_get_oldest_idle(struct cpool_bundle *bundle)
|
||||
cpool_bundle_get_oldest_idle(struct cpool_bundle *bundle,
|
||||
const struct curltime *pnow)
|
||||
{
|
||||
struct Curl_llist_node *curr;
|
||||
timediff_t highscore = -1;
|
||||
timediff_t score;
|
||||
struct curltime now;
|
||||
struct connectdata *oldest_idle = NULL;
|
||||
struct connectdata *conn;
|
||||
|
||||
now = curlx_now();
|
||||
curr = Curl_llist_head(&bundle->conns);
|
||||
while(curr) {
|
||||
conn = Curl_node_elem(curr);
|
||||
|
||||
if(!CONN_INUSE(conn)) {
|
||||
/* Set higher score for the age passed since the connection was used */
|
||||
score = curlx_timediff(now, conn->lastused);
|
||||
score = curlx_ptimediff_ms(pnow, &conn->lastused);
|
||||
|
||||
if(score > highscore) {
|
||||
highscore = score;
|
||||
|
|
@ -311,18 +294,17 @@ cpool_bundle_get_oldest_idle(struct cpool_bundle *bundle)
|
|||
return oldest_idle;
|
||||
}
|
||||
|
||||
static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool)
|
||||
static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool,
|
||||
const struct curltime *pnow)
|
||||
{
|
||||
struct Curl_hash_iterator iter;
|
||||
struct Curl_llist_node *curr;
|
||||
struct Curl_hash_element *he;
|
||||
struct connectdata *oldest_idle = NULL;
|
||||
struct cpool_bundle *bundle;
|
||||
struct curltime now;
|
||||
timediff_t highscore = -1;
|
||||
timediff_t score;
|
||||
|
||||
now = curlx_now();
|
||||
Curl_hash_start_iterate(&cpool->dest2bundle, &iter);
|
||||
|
||||
for(he = Curl_hash_next_element(&iter); he;
|
||||
|
|
@ -336,7 +318,7 @@ static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool)
|
|||
if(CONN_INUSE(conn) || conn->bits.close || conn->connect_only)
|
||||
continue;
|
||||
/* Set higher score for the age passed since the connection was used */
|
||||
score = curlx_timediff(now, conn->lastused);
|
||||
score = curlx_ptimediff_ms(pnow, &conn->lastused);
|
||||
if(score > highscore) {
|
||||
highscore = score;
|
||||
oldest_idle = conn;
|
||||
|
|
@ -346,7 +328,6 @@ static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool)
|
|||
return oldest_idle;
|
||||
}
|
||||
|
||||
|
||||
int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
|
|
@ -375,7 +356,7 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
|||
bundle = cpool_find_bundle(cpool, conn);
|
||||
live = bundle ? Curl_llist_count(&bundle->conns) : 0;
|
||||
shutdowns = Curl_cshutdn_dest_count(data, conn->destination);
|
||||
while((live + shutdowns) >= dest_limit) {
|
||||
while((live + shutdowns) >= dest_limit) {
|
||||
if(shutdowns) {
|
||||
/* close one connection in shutdown right away, if we can */
|
||||
if(!Curl_cshutdn_close_oldest(data, conn->destination))
|
||||
|
|
@ -387,14 +368,15 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
|||
struct connectdata *oldest_idle = NULL;
|
||||
/* The bundle is full. Extract the oldest connection that may
|
||||
* be removed now, if there is one. */
|
||||
oldest_idle = cpool_bundle_get_oldest_idle(bundle);
|
||||
oldest_idle = cpool_bundle_get_oldest_idle(bundle,
|
||||
Curl_pgrs_now(data));
|
||||
if(!oldest_idle)
|
||||
break;
|
||||
/* disconnect the old conn and continue */
|
||||
CURL_TRC_M(data, "Discarding connection #%"
|
||||
FMT_OFF_T " from %zu to reach destination "
|
||||
"limit of %zu", oldest_idle->connection_id,
|
||||
Curl_llist_count(&bundle->conns), dest_limit);
|
||||
CURL_TRC_M(data, "Discarding connection #%" FMT_OFF_T
|
||||
" from %zu to reach destination limit of %zu",
|
||||
oldest_idle->connection_id,
|
||||
Curl_llist_count(&bundle->conns), dest_limit);
|
||||
Curl_conn_terminate(cpool->idata, oldest_idle, FALSE);
|
||||
|
||||
/* in case the bundle was destroyed in disconnect, look it up again */
|
||||
|
|
@ -418,7 +400,8 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
|||
break;
|
||||
}
|
||||
else {
|
||||
struct connectdata *oldest_idle = cpool_get_oldest_idle(cpool);
|
||||
struct connectdata *oldest_idle =
|
||||
cpool_get_oldest_idle(cpool, Curl_pgrs_now(data));
|
||||
if(!oldest_idle)
|
||||
break;
|
||||
/* disconnect the old conn and continue */
|
||||
|
|
@ -531,13 +514,23 @@ static bool cpool_foreach(struct Curl_easy *data,
|
|||
bool Curl_cpool_conn_now_idle(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
unsigned int maxconnects = !data->multi->maxconnects ?
|
||||
(Curl_multi_xfers_running(data->multi) * 4) : data->multi->maxconnects;
|
||||
unsigned int maxconnects;
|
||||
struct connectdata *oldest_idle = NULL;
|
||||
struct cpool *cpool = cpool_get_instance(data);
|
||||
bool kept = TRUE;
|
||||
|
||||
conn->lastused = curlx_now(); /* it was used up until now */
|
||||
if(!data)
|
||||
return kept;
|
||||
|
||||
if(!data->multi->maxconnects) {
|
||||
unsigned int running = Curl_multi_xfers_running(data->multi);
|
||||
maxconnects = (running <= UINT_MAX / 4) ? running * 4 : UINT_MAX;
|
||||
}
|
||||
else {
|
||||
maxconnects = data->multi->maxconnects;
|
||||
}
|
||||
|
||||
conn->lastused = *Curl_pgrs_now(data); /* it was used up until now */
|
||||
if(cpool && maxconnects) {
|
||||
/* may be called form a callback already under lock */
|
||||
bool do_lock = !CPOOL_IS_LOCKED(cpool);
|
||||
|
|
@ -547,7 +540,7 @@ bool Curl_cpool_conn_now_idle(struct Curl_easy *data,
|
|||
infof(data, "Connection pool is full, closing the oldest of %zu/%u",
|
||||
cpool->num_conn, maxconnects);
|
||||
|
||||
oldest_idle = cpool_get_oldest_idle(cpool);
|
||||
oldest_idle = cpool_get_oldest_idle(cpool, Curl_pgrs_now(data));
|
||||
kept = (oldest_idle != conn);
|
||||
if(oldest_idle) {
|
||||
Curl_conn_terminate(data, oldest_idle, FALSE);
|
||||
|
|
@ -619,7 +612,7 @@ static void cpool_discard_conn(struct cpool *cpool,
|
|||
if(CONN_INUSE(conn) && !aborted) {
|
||||
CURL_TRC_M(data, "[CPOOL] not discarding #%" FMT_OFF_T
|
||||
" still in use by %u transfers", conn->connection_id,
|
||||
CONN_ATTACHED(conn));
|
||||
conn->attached_xfers);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -663,7 +656,7 @@ void Curl_conn_terminate(struct Curl_easy *data,
|
|||
* are other users of it */
|
||||
if(CONN_INUSE(conn) && !aborted) {
|
||||
DEBUGASSERT(0); /* does this ever happen? */
|
||||
DEBUGF(infof(data, "Curl_disconnect when inuse: %u", CONN_ATTACHED(conn)));
|
||||
DEBUGF(infof(data, "conn terminate when inuse: %u", conn->attached_xfers));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -699,18 +692,24 @@ void Curl_conn_terminate(struct Curl_easy *data,
|
|||
CPOOL_UNLOCK(cpool, data);
|
||||
}
|
||||
|
||||
|
||||
struct cpool_reaper_ctx {
|
||||
struct curltime now;
|
||||
size_t checked;
|
||||
size_t reaped;
|
||||
};
|
||||
|
||||
static int cpool_reap_dead_cb(struct Curl_easy *data,
|
||||
struct connectdata *conn, void *param)
|
||||
{
|
||||
struct cpool_reaper_ctx *rctx = param;
|
||||
if((!CONN_INUSE(conn) && conn->bits.no_reuse) ||
|
||||
Curl_conn_seems_dead(conn, data, &rctx->now)) {
|
||||
struct cpool_reaper_ctx *reaper = param;
|
||||
bool terminate = !CONN_INUSE(conn) && conn->bits.no_reuse;
|
||||
|
||||
if(!terminate) {
|
||||
reaper->checked++;
|
||||
terminate = Curl_conn_seems_dead(conn, data);
|
||||
}
|
||||
if(terminate) {
|
||||
/* stop the iteration here, pass back the connection that was pruned */
|
||||
reaper->reaped++;
|
||||
Curl_conn_terminate(data, conn, FALSE);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -727,20 +726,20 @@ static int cpool_reap_dead_cb(struct Curl_easy *data,
|
|||
void Curl_cpool_prune_dead(struct Curl_easy *data)
|
||||
{
|
||||
struct cpool *cpool = cpool_get_instance(data);
|
||||
struct cpool_reaper_ctx rctx;
|
||||
struct cpool_reaper_ctx reaper;
|
||||
timediff_t elapsed;
|
||||
|
||||
if(!cpool)
|
||||
return;
|
||||
|
||||
rctx.now = curlx_now();
|
||||
memset(&reaper, 0, sizeof(reaper));
|
||||
CPOOL_LOCK(cpool, data);
|
||||
elapsed = curlx_timediff(rctx.now, cpool->last_cleanup);
|
||||
elapsed = curlx_ptimediff_ms(Curl_pgrs_now(data), &cpool->last_cleanup);
|
||||
|
||||
if(elapsed >= 1000L) {
|
||||
while(cpool_foreach(data, cpool, &rctx, cpool_reap_dead_cb))
|
||||
while(cpool_foreach(data, cpool, &reaper, cpool_reap_dead_cb))
|
||||
;
|
||||
cpool->last_cleanup = rctx.now;
|
||||
cpool->last_cleanup = *Curl_pgrs_now(data);
|
||||
}
|
||||
CPOOL_UNLOCK(cpool, data);
|
||||
}
|
||||
|
|
@ -749,21 +748,20 @@ static int conn_upkeep(struct Curl_easy *data,
|
|||
struct connectdata *conn,
|
||||
void *param)
|
||||
{
|
||||
struct curltime *now = param;
|
||||
Curl_conn_upkeep(data, conn, now);
|
||||
(void)param;
|
||||
Curl_conn_upkeep(data, conn);
|
||||
return 0; /* continue iteration */
|
||||
}
|
||||
|
||||
CURLcode Curl_cpool_upkeep(void *data)
|
||||
CURLcode Curl_cpool_upkeep(struct Curl_easy *data)
|
||||
{
|
||||
struct cpool *cpool = cpool_get_instance(data);
|
||||
struct curltime now = curlx_now();
|
||||
|
||||
if(!cpool)
|
||||
return CURLE_OK;
|
||||
|
||||
CPOOL_LOCK(cpool, data);
|
||||
cpool_foreach(data, cpool, &now, conn_upkeep);
|
||||
cpool_foreach(data, cpool, NULL, conn_upkeep);
|
||||
CPOOL_UNLOCK(cpool, data);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
struct connectdata;
|
||||
|
|
@ -49,7 +48,7 @@ void Curl_conn_terminate(struct Curl_easy *data,
|
|||
bool aborted);
|
||||
|
||||
struct cpool {
|
||||
/* the pooled connections, bundled per destination */
|
||||
/* the pooled connections, bundled per destination */
|
||||
struct Curl_hash dest2bundle;
|
||||
size_t num_conn;
|
||||
curl_off_t next_connection_id;
|
||||
|
|
@ -139,7 +138,7 @@ void Curl_cpool_prune_dead(struct Curl_easy *data);
|
|||
/**
|
||||
* Perform upkeep actions on connections in the transfer's pool.
|
||||
*/
|
||||
CURLcode Curl_cpool_upkeep(void *data);
|
||||
CURLcode Curl_cpool_upkeep(struct Curl_easy *data);
|
||||
|
||||
typedef void Curl_cpool_conn_do_cb(struct connectdata *conn,
|
||||
struct Curl_easy *data,
|
||||
|
|
@ -166,5 +165,4 @@ void Curl_cpool_do_locked(struct Curl_easy *data,
|
|||
/* Close all unused connections, prevent reuse of existing ones. */
|
||||
void Curl_cpool_nw_changed(struct Curl_easy *data);
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_CONNCACHE_H */
|
||||
|
|
|
|||
200
lib/connect.c
200
lib/connect.c
|
|
@ -52,7 +52,6 @@
|
|||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "if2ip.h"
|
||||
#include "strerror.h"
|
||||
#include "cfilters.h"
|
||||
#include "connect.h"
|
||||
|
|
@ -60,63 +59,60 @@
|
|||
#include "cf-https-connect.h"
|
||||
#include "cf-ip-happy.h"
|
||||
#include "cf-socket.h"
|
||||
#include "select.h"
|
||||
#include "url.h" /* for Curl_safefree() */
|
||||
#include "multiif.h"
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "curlx/inet_ntop.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "vtls/vtls.h" /* for vtsl cfilters */
|
||||
#include "progress.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "conncache.h"
|
||||
#include "multihandle.h"
|
||||
#include "share.h"
|
||||
#include "http_proxy.h"
|
||||
#include "socks.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_ALTSVC) || defined(USE_HTTPSRR)
|
||||
|
||||
enum alpnid Curl_alpn2alpnid(const char *name, size_t len)
|
||||
enum alpnid Curl_alpn2alpnid(const unsigned char *name, size_t len)
|
||||
{
|
||||
if(len == 2) {
|
||||
if(curl_strnequal(name, "h1", 2))
|
||||
if(!memcmp(name, "h1", 2))
|
||||
return ALPN_h1;
|
||||
if(curl_strnequal(name, "h2", 2))
|
||||
if(!memcmp(name, "h2", 2))
|
||||
return ALPN_h2;
|
||||
if(curl_strnequal(name, "h3", 2))
|
||||
if(!memcmp(name, "h3", 2))
|
||||
return ALPN_h3;
|
||||
}
|
||||
else if(len == 8) {
|
||||
if(curl_strnequal(name, "http/1.1", 8))
|
||||
if(!memcmp(name, "http/1.1", 8))
|
||||
return ALPN_h1;
|
||||
}
|
||||
return ALPN_none; /* unknown, probably rubbish input */
|
||||
}
|
||||
|
||||
enum alpnid Curl_str2alpnid(const struct Curl_str *cstr)
|
||||
{
|
||||
return Curl_alpn2alpnid((const unsigned char *)curlx_str(cstr),
|
||||
curlx_strlen(cstr));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_timeleft() returns the amount of milliseconds left allowed for the
|
||||
* Curl_timeleft_ms() returns the amount of milliseconds left allowed for the
|
||||
* transfer/connection. If the value is 0, there is no timeout (ie there is
|
||||
* infinite time left). If the value is negative, the timeout time has already
|
||||
* elapsed.
|
||||
* @param data the transfer to check on
|
||||
* @param nowp timestamp to use for calculation, NULL to use curlx_now()
|
||||
* @param duringconnect TRUE iff connect timeout is also taken into account.
|
||||
* @unittest: 1303
|
||||
*/
|
||||
timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
struct curltime *nowp,
|
||||
bool duringconnect)
|
||||
timediff_t Curl_timeleft_now_ms(struct Curl_easy *data,
|
||||
const struct curltime *pnow,
|
||||
bool duringconnect)
|
||||
{
|
||||
timediff_t timeleft_ms = 0;
|
||||
timediff_t ctimeleft_ms = 0;
|
||||
struct curltime now;
|
||||
timediff_t ctimeout_ms;
|
||||
|
||||
/* The duration of a connect and the total transfer are calculated from two
|
||||
different time-stamps. It can end up with the total timeout being reached
|
||||
|
|
@ -126,90 +122,76 @@ timediff_t Curl_timeleft(struct Curl_easy *data,
|
|||
if((!data->set.timeout || data->set.connect_only) && !duringconnect)
|
||||
return 0; /* no timeout in place or checked, return "no limit" */
|
||||
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
|
||||
if(data->set.timeout) {
|
||||
timeleft_ms = data->set.timeout -
|
||||
curlx_timediff(*nowp, data->progress.t_startop);
|
||||
curlx_ptimediff_ms(pnow, &data->progress.t_startop);
|
||||
if(!timeleft_ms)
|
||||
timeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
if(!duringconnect)
|
||||
return timeleft_ms; /* no connect check, this is it */
|
||||
}
|
||||
|
||||
if(duringconnect) {
|
||||
timediff_t ctimeout_ms = (data->set.connecttimeout > 0) ?
|
||||
data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT;
|
||||
ctimeleft_ms = ctimeout_ms -
|
||||
curlx_timediff(*nowp, data->progress.t_startsingle);
|
||||
if(!ctimeleft_ms)
|
||||
ctimeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
if(!timeleft_ms)
|
||||
return ctimeleft_ms; /* no general timeout, this is it */
|
||||
}
|
||||
if(!duringconnect)
|
||||
return timeleft_ms; /* no connect check, this is it */
|
||||
ctimeout_ms = (data->set.connecttimeout > 0) ?
|
||||
data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT;
|
||||
ctimeleft_ms = ctimeout_ms -
|
||||
curlx_ptimediff_ms(pnow, &data->progress.t_startsingle);
|
||||
if(!ctimeleft_ms)
|
||||
ctimeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
if(!timeleft_ms)
|
||||
return ctimeleft_ms; /* no general timeout, this is it */
|
||||
|
||||
/* return minimal time left or max amount already expired */
|
||||
return (ctimeleft_ms < timeleft_ms) ? ctimeleft_ms : timeleft_ms;
|
||||
}
|
||||
|
||||
void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
|
||||
int timeout_ms, struct curltime *nowp)
|
||||
timediff_t Curl_timeleft_ms(struct Curl_easy *data,
|
||||
bool duringconnect)
|
||||
{
|
||||
return Curl_timeleft_now_ms(data, Curl_pgrs_now(data), duringconnect);
|
||||
}
|
||||
|
||||
void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
|
||||
int timeout_ms)
|
||||
{
|
||||
struct curltime now;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
conn->shutdown.start[sockindex] = *nowp;
|
||||
conn->shutdown.start[sockindex] = *Curl_pgrs_now(data);
|
||||
conn->shutdown.timeout_ms = (timeout_ms > 0) ?
|
||||
(timediff_t)timeout_ms :
|
||||
((data->set.shutdowntimeout > 0) ?
|
||||
data->set.shutdowntimeout : DEFAULT_SHUTDOWN_TIMEOUT_MS);
|
||||
/* Set a timer, unless we operate on the admin handle */
|
||||
if(data->mid)
|
||||
Curl_expire_ex(data, nowp, conn->shutdown.timeout_ms,
|
||||
EXPIRE_SHUTDOWN);
|
||||
Curl_expire_ex(data, conn->shutdown.timeout_ms, EXPIRE_SHUTDOWN);
|
||||
}
|
||||
|
||||
timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex,
|
||||
struct curltime *nowp)
|
||||
timediff_t Curl_shutdown_timeleft(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
struct curltime now;
|
||||
timediff_t left_ms;
|
||||
|
||||
if(!conn->shutdown.start[sockindex].tv_sec ||
|
||||
(conn->shutdown.timeout_ms <= 0))
|
||||
return 0; /* not started or no limits */
|
||||
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
left_ms = conn->shutdown.timeout_ms -
|
||||
curlx_timediff(*nowp, conn->shutdown.start[sockindex]);
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&conn->shutdown.start[sockindex]);
|
||||
return left_ms ? left_ms : -1;
|
||||
}
|
||||
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct connectdata *conn,
|
||||
struct curltime *nowp)
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
timediff_t left_ms = 0, ms;
|
||||
struct curltime now;
|
||||
int i;
|
||||
|
||||
for(i = 0; conn->shutdown.timeout_ms && (i < 2); ++i) {
|
||||
if(!conn->shutdown.start[i].tv_sec)
|
||||
continue;
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
ms = Curl_shutdown_timeleft(conn, i, nowp);
|
||||
ms = Curl_shutdown_timeleft(data, conn, i);
|
||||
if(ms && (!left_ms || ms < left_ms))
|
||||
left_ms = ms;
|
||||
}
|
||||
|
|
@ -231,56 +213,53 @@ bool Curl_shutdown_started(struct Curl_easy *data, int sockindex)
|
|||
/* retrieves ip address and port from a sockaddr structure. note it calls
|
||||
curlx_inet_ntop which sets errno on fail, not SOCKERRNO. */
|
||||
bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
|
||||
char *addr, int *port)
|
||||
char *addr, uint16_t *port)
|
||||
{
|
||||
struct sockaddr_in *si = NULL;
|
||||
#ifdef USE_IPV6
|
||||
struct sockaddr_in6 *si6 = NULL;
|
||||
#endif
|
||||
#if (defined(HAVE_SYS_UN_H) || defined(WIN32_SOCKADDR_UN)) && defined(AF_UNIX)
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
struct sockaddr_un *su = NULL;
|
||||
#else
|
||||
(void)salen;
|
||||
#endif
|
||||
|
||||
switch(sa->sa_family) {
|
||||
case AF_INET:
|
||||
si = (struct sockaddr_in *)(void *) sa;
|
||||
if(curlx_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN)) {
|
||||
unsigned short us_port = ntohs(si->sin_port);
|
||||
*port = us_port;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_IPV6
|
||||
case AF_INET6:
|
||||
si6 = (struct sockaddr_in6 *)(void *) sa;
|
||||
if(curlx_inet_ntop(sa->sa_family, &si6->sin6_addr, addr,
|
||||
MAX_IPADR_LEN)) {
|
||||
unsigned short us_port = ntohs(si6->sin6_port);
|
||||
*port = us_port;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if (defined(HAVE_SYS_UN_H) || defined(WIN32_SOCKADDR_UN)) && defined(AF_UNIX)
|
||||
case AF_UNIX:
|
||||
if(salen > (curl_socklen_t)sizeof(CURL_SA_FAMILY_T)) {
|
||||
su = (struct sockaddr_un*)sa;
|
||||
curl_msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
|
||||
}
|
||||
else
|
||||
addr[0] = 0; /* socket with no name */
|
||||
*port = 0;
|
||||
case AF_INET:
|
||||
si = (struct sockaddr_in *)(void *)sa;
|
||||
if(curlx_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN)) {
|
||||
*port = ntohs(si->sin_port);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_IPV6
|
||||
case AF_INET6:
|
||||
si6 = (struct sockaddr_in6 *)(void *)sa;
|
||||
if(curlx_inet_ntop(sa->sa_family, &si6->sin6_addr, addr, MAX_IPADR_LEN)) {
|
||||
*port = ntohs(si6->sin6_port);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
case AF_UNIX:
|
||||
if(salen > (curl_socklen_t)sizeof(CURL_SA_FAMILY_T)) {
|
||||
su = (struct sockaddr_un *)sa;
|
||||
curl_msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
|
||||
}
|
||||
else
|
||||
addr[0] = 0; /* socket with no name */
|
||||
*port = 0;
|
||||
return TRUE;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
addr[0] = '\0';
|
||||
*port = 0;
|
||||
CURL_SETERRNO(SOCKEAFNOSUPPORT);
|
||||
errno = SOCKEAFNOSUPPORT;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -337,7 +316,7 @@ void Curl_conncontrol(struct connectdata *conn,
|
|||
#endif
|
||||
is_multiplex = Curl_conn_is_multiplex(conn, FIRSTSOCKET);
|
||||
closeit = (ctrl == CONNCTRL_CONNECTION) ||
|
||||
((ctrl == CONNCTRL_STREAM) && !is_multiplex);
|
||||
((ctrl == CONNCTRL_STREAM) && !is_multiplex);
|
||||
if((ctrl == CONNCTRL_STREAM) && is_multiplex)
|
||||
; /* stream signal on multiplex conn never affects close state */
|
||||
else if((bit)closeit != conn->bits.close) {
|
||||
|
|
@ -359,7 +338,7 @@ typedef enum {
|
|||
struct cf_setup_ctx {
|
||||
cf_setup_state state;
|
||||
int ssl_mode;
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
};
|
||||
|
||||
static CURLcode cf_setup_connect(struct Curl_cfilter *cf,
|
||||
|
|
@ -408,8 +387,8 @@ connect_sub_chain:
|
|||
|
||||
if(ctx->state < CF_SETUP_CNNCT_HTTP_PROXY && cf->conn->bits.httpproxy) {
|
||||
#ifdef USE_SSL
|
||||
if(IS_HTTPS_PROXY(cf->conn->http_proxy.proxytype)
|
||||
&& !Curl_conn_is_ssl(cf->conn, cf->sockindex)) {
|
||||
if(IS_HTTPS_PROXY(cf->conn->http_proxy.proxytype) &&
|
||||
!Curl_conn_is_ssl(cf->conn, cf->sockindex)) {
|
||||
result = Curl_cf_ssl_proxy_insert_after(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
|
|
@ -449,9 +428,9 @@ connect_sub_chain:
|
|||
|
||||
if(ctx->state < CF_SETUP_CNNCT_SSL) {
|
||||
#ifdef USE_SSL
|
||||
if((ctx->ssl_mode == CURL_CF_SSL_ENABLE
|
||||
|| (ctx->ssl_mode != CURL_CF_SSL_DISABLE
|
||||
&& cf->conn->handler->flags & PROTOPT_SSL)) /* we want SSL */
|
||||
if((ctx->ssl_mode == CURL_CF_SSL_ENABLE ||
|
||||
(ctx->ssl_mode != CURL_CF_SSL_DISABLE &&
|
||||
cf->conn->handler->flags & PROTOPT_SSL)) /* we want SSL */
|
||||
&& !Curl_conn_is_ssl(cf->conn, cf->sockindex)) { /* it is missing */
|
||||
result = Curl_cf_ssl_insert_after(cf, data);
|
||||
if(result)
|
||||
|
|
@ -493,7 +472,6 @@ static void cf_setup_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
Curl_safefree(ctx);
|
||||
}
|
||||
|
||||
|
||||
struct Curl_cftype Curl_cft_setup = {
|
||||
"SETUP",
|
||||
0,
|
||||
|
|
@ -514,7 +492,7 @@ struct Curl_cftype Curl_cft_setup = {
|
|||
|
||||
static CURLcode cf_setup_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
int ssl_mode)
|
||||
{
|
||||
struct Curl_cfilter *cf = NULL;
|
||||
|
|
@ -522,7 +500,7 @@ static CURLcode cf_setup_create(struct Curl_cfilter **pcf,
|
|||
CURLcode result = CURLE_OK;
|
||||
|
||||
(void)data;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
|
|
@ -539,7 +517,7 @@ static CURLcode cf_setup_create(struct Curl_cfilter **pcf,
|
|||
out:
|
||||
*pcf = result ? NULL : cf;
|
||||
if(ctx) {
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -547,7 +525,7 @@ out:
|
|||
static CURLcode cf_setup_add(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
int ssl_mode)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
|
|
@ -564,7 +542,7 @@ out:
|
|||
|
||||
CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
int ssl_mode)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
|
|
|
|||
|
|
@ -26,36 +26,40 @@
|
|||
#include "curl_setup.h"
|
||||
|
||||
#include "curlx/nonblock.h" /* for curlx_nonblock() */
|
||||
#include "sockaddr.h"
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
struct Curl_dns_entry;
|
||||
struct ip_quadruple;
|
||||
struct Curl_str;
|
||||
|
||||
enum alpnid Curl_alpn2alpnid(const char *name, size_t len);
|
||||
enum alpnid Curl_alpn2alpnid(const unsigned char *name, size_t len);
|
||||
enum alpnid Curl_str2alpnid(const struct Curl_str *str);
|
||||
|
||||
/* generic function that returns how much time there is left to run, according
|
||||
to the timeouts set */
|
||||
timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
struct curltime *nowp,
|
||||
bool duringconnect);
|
||||
timediff_t Curl_timeleft_ms(struct Curl_easy *data,
|
||||
bool duringconnect);
|
||||
timediff_t Curl_timeleft_now_ms(struct Curl_easy *data,
|
||||
const struct curltime *pnow,
|
||||
bool duringconnect);
|
||||
|
||||
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
||||
|
||||
#define DEFAULT_SHUTDOWN_TIMEOUT_MS (2 * 1000)
|
||||
|
||||
void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
|
||||
int timeout_ms, struct curltime *nowp);
|
||||
int timeout_ms);
|
||||
|
||||
/* return how much time there is left to shutdown the connection at
|
||||
* sockindex. Returns 0 if there is no limit or shutdown has not started. */
|
||||
timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex,
|
||||
struct curltime *nowp);
|
||||
timediff_t Curl_shutdown_timeleft(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex);
|
||||
|
||||
/* return how much time there is left to shutdown the connection.
|
||||
* Returns 0 if there is no limit or shutdown has not started. */
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct connectdata *conn,
|
||||
struct curltime *nowp);
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
void Curl_shutdown_clear(struct Curl_easy *data, int sockindex);
|
||||
|
||||
|
|
@ -72,7 +76,7 @@ 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);
|
||||
char *addr, uint16_t *port);
|
||||
|
||||
/*
|
||||
* Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
|
||||
|
|
@ -98,18 +102,18 @@ void Curl_conncontrol(struct connectdata *conn,
|
|||
);
|
||||
|
||||
#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)
|
||||
#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)
|
||||
#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
|
||||
|
||||
CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
int ssl_mode);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@
|
|||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#include <zlib.h>
|
||||
|
|
@ -52,10 +50,6 @@
|
|||
#include "http.h"
|
||||
#include "content_encoding.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define CONTENT_ENCODING_DEFAULT "identity"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
|
|
@ -90,24 +84,20 @@ struct zlib_writer {
|
|||
z_stream z; /* State structure for zlib. */
|
||||
};
|
||||
|
||||
|
||||
static voidpf
|
||||
zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
|
||||
static voidpf zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
|
||||
{
|
||||
(void)opaque;
|
||||
/* not a typo, keep it calloc() */
|
||||
return (voidpf) calloc(items, size);
|
||||
/* not a typo, keep it curlx_calloc() */
|
||||
return (voidpf)curlx_calloc(items, size);
|
||||
}
|
||||
|
||||
static void
|
||||
zfree_cb(voidpf opaque, voidpf ptr)
|
||||
static void zfree_cb(voidpf opaque, voidpf ptr)
|
||||
{
|
||||
(void)opaque;
|
||||
free(ptr);
|
||||
curlx_free(ptr);
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
process_zlib_error(struct Curl_easy *data, z_stream *z)
|
||||
static CURLcode process_zlib_error(struct Curl_easy *data, z_stream *z)
|
||||
{
|
||||
if(z->msg)
|
||||
failf(data, "Error while processing content unencoding: %s",
|
||||
|
|
@ -119,9 +109,8 @@ process_zlib_error(struct Curl_easy *data, z_stream *z)
|
|||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
exit_zlib(struct Curl_easy *data,
|
||||
z_stream *z, zlibInitState *zlib_init, CURLcode result)
|
||||
static CURLcode exit_zlib(struct Curl_easy *data, z_stream *z,
|
||||
zlibInitState *zlib_init, CURLcode result)
|
||||
{
|
||||
if(*zlib_init != ZLIB_UNINIT) {
|
||||
if(inflateEnd(z) != Z_OK && result == CURLE_OK)
|
||||
|
|
@ -132,8 +121,7 @@ exit_zlib(struct Curl_easy *data,
|
|||
return result;
|
||||
}
|
||||
|
||||
static CURLcode process_trailer(struct Curl_easy *data,
|
||||
struct zlib_writer *zp)
|
||||
static CURLcode process_trailer(struct Curl_easy *data, struct zlib_writer *zp)
|
||||
{
|
||||
z_stream *z = &zp->z;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
|
@ -160,7 +148,7 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
|||
struct Curl_cwriter *writer, int type,
|
||||
zlibInitState started)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
uInt nread = z->avail_in;
|
||||
z_const Bytef *orig_in = z->next_in;
|
||||
|
|
@ -180,7 +168,7 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
|||
done = TRUE;
|
||||
|
||||
/* (re)set buffer for decompressed output for every iteration */
|
||||
z->next_out = (Bytef *) zp->buffer;
|
||||
z->next_out = (Bytef *)zp->buffer;
|
||||
z->avail_out = DECOMPRESS_BUFFER_SIZE;
|
||||
|
||||
status = inflate(z, Z_BLOCK);
|
||||
|
|
@ -241,17 +229,16 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Deflate handler. */
|
||||
static CURLcode deflate_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
/* Initialize zlib */
|
||||
z->zalloc = (alloc_func) zalloc_cb;
|
||||
z->zfree = (free_func) zfree_cb;
|
||||
z->zalloc = (alloc_func)zalloc_cb;
|
||||
z->zfree = (free_func)zfree_cb;
|
||||
|
||||
if(inflateInit(z) != Z_OK)
|
||||
return process_zlib_error(data, z);
|
||||
|
|
@ -263,7 +250,7 @@ static CURLcode deflate_do_write(struct Curl_easy *data,
|
|||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
if(!(type & CLIENTWRITE_BODY) || !nbytes)
|
||||
|
|
@ -283,7 +270,7 @@ static CURLcode deflate_do_write(struct Curl_easy *data,
|
|||
static void deflate_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
exit_zlib(data, z, &zp->zlib_init, CURLE_OK);
|
||||
|
|
@ -298,17 +285,19 @@ static const struct Curl_cwtype deflate_encoding = {
|
|||
sizeof(struct zlib_writer)
|
||||
};
|
||||
|
||||
/*
|
||||
* Gzip handler.
|
||||
*/
|
||||
|
||||
/* Gzip handler. */
|
||||
static CURLcode gzip_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
/* Initialize zlib */
|
||||
z->zalloc = (alloc_func) zalloc_cb;
|
||||
z->zfree = (free_func) zfree_cb;
|
||||
z->zalloc = (alloc_func)zalloc_cb;
|
||||
z->zfree = (free_func)zfree_cb;
|
||||
|
||||
if(inflateInit2(z, MAX_WBITS + 32) != Z_OK)
|
||||
return process_zlib_error(data, z);
|
||||
|
|
@ -321,7 +310,7 @@ static CURLcode gzip_do_write(struct Curl_easy *data,
|
|||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
if(!(type & CLIENTWRITE_BODY) || !nbytes)
|
||||
|
|
@ -342,7 +331,7 @@ static CURLcode gzip_do_write(struct Curl_easy *data,
|
|||
static void gzip_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
exit_zlib(data, z, &zp->zlib_init, CURLE_OK);
|
||||
|
|
@ -384,12 +373,10 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
|
|||
case BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:
|
||||
case BROTLI_DECODER_ERROR_FORMAT_PADDING_1:
|
||||
case BROTLI_DECODER_ERROR_FORMAT_PADDING_2:
|
||||
#ifdef BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY
|
||||
#ifdef BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY /* brotli v1.1.0+ */
|
||||
case BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY:
|
||||
#endif
|
||||
#ifdef BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET
|
||||
case BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:
|
||||
#endif
|
||||
case BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:
|
||||
|
|
@ -408,7 +395,7 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
|
|||
static CURLcode brotli_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct brotli_writer *bp = (struct brotli_writer *) writer;
|
||||
struct brotli_writer *bp = (struct brotli_writer *)writer;
|
||||
(void)data;
|
||||
|
||||
bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL);
|
||||
|
|
@ -419,8 +406,8 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
|||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct brotli_writer *bp = (struct brotli_writer *) writer;
|
||||
const uint8_t *src = (const uint8_t *) buf;
|
||||
struct brotli_writer *bp = (struct brotli_writer *)writer;
|
||||
const uint8_t *src = (const uint8_t *)buf;
|
||||
uint8_t *dst;
|
||||
size_t dstleft;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
|
@ -434,7 +421,7 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
|||
|
||||
while((nbytes || r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) &&
|
||||
result == CURLE_OK) {
|
||||
dst = (uint8_t *) bp->buffer;
|
||||
dst = (uint8_t *)bp->buffer;
|
||||
dstleft = DECOMPRESS_BUFFER_SIZE;
|
||||
r = BrotliDecoderDecompressStream(bp->br,
|
||||
&nbytes, &src, &dstleft, &dst, NULL);
|
||||
|
|
@ -463,7 +450,7 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
|||
static void brotli_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct brotli_writer *bp = (struct brotli_writer *) writer;
|
||||
struct brotli_writer *bp = (struct brotli_writer *)writer;
|
||||
(void)data;
|
||||
|
||||
if(bp->br) {
|
||||
|
|
@ -507,7 +494,7 @@ static void Curl_zstd_free(void *opaque, void *address)
|
|||
static CURLcode zstd_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zstd_writer *zp = (struct zstd_writer *) writer;
|
||||
struct zstd_writer *zp = (struct zstd_writer *)writer;
|
||||
|
||||
(void)data;
|
||||
|
||||
|
|
@ -529,7 +516,7 @@ static CURLcode zstd_do_write(struct Curl_easy *data,
|
|||
const char *buf, size_t nbytes)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct zstd_writer *zp = (struct zstd_writer *) writer;
|
||||
struct zstd_writer *zp = (struct zstd_writer *)writer;
|
||||
ZSTD_inBuffer in;
|
||||
ZSTD_outBuffer out;
|
||||
size_t errorCode;
|
||||
|
|
@ -566,7 +553,7 @@ static CURLcode zstd_do_write(struct Curl_easy *data,
|
|||
static void zstd_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zstd_writer *zp = (struct zstd_writer *) writer;
|
||||
struct zstd_writer *zp = (struct zstd_writer *)writer;
|
||||
(void)data;
|
||||
|
||||
if(zp->zds) {
|
||||
|
|
@ -620,7 +607,7 @@ static const struct Curl_cwtype * const transfer_unencoders[] = {
|
|||
};
|
||||
|
||||
/* Provide a list of comma-separated names of supported encodings.
|
||||
*/
|
||||
*/
|
||||
void Curl_all_content_encodings(char *buf, size_t blen)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
|
|
|||
904
lib/cookie.c
904
lib/cookie.c
File diff suppressed because it is too large
Load diff
68
lib/cookie.h
68
lib/cookie.h
|
|
@ -25,34 +25,31 @@
|
|||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
struct Cookie {
|
||||
struct Curl_llist_node node; /* for the main cookie list */
|
||||
struct Curl_llist_node node; /* for the main cookie list */
|
||||
struct Curl_llist_node getnode; /* for getlist */
|
||||
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> */
|
||||
unsigned int creationtime; /* time when the cookie was written */
|
||||
BIT(tailmatch); /* tail-match the domain name */
|
||||
BIT(secure); /* the 'secure' keyword was used */
|
||||
BIT(livecookie); /* updated from a server, not a stored file */
|
||||
BIT(httponly); /* the httponly directive is present */
|
||||
BIT(prefix_secure); /* secure prefix is set */
|
||||
BIT(prefix_host); /* host prefix is set */
|
||||
char *name; /* <this> = value */
|
||||
char *value; /* name = <this> */
|
||||
char *path; /* canonical path */
|
||||
char *domain; /* domain = <this> */
|
||||
curl_off_t expires; /* expires = <this> */
|
||||
unsigned int creationtime; /* time when the cookie was written */
|
||||
BIT(tailmatch); /* tail-match the domain name */
|
||||
BIT(secure); /* the 'secure' keyword was used */
|
||||
BIT(livecookie); /* updated from server, not a stored file */
|
||||
BIT(httponly); /* the httponly directive is present */
|
||||
BIT(prefix_secure); /* secure prefix is set */
|
||||
BIT(prefix_host); /* host prefix is 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_PREFIX__SECURE (1 << 0)
|
||||
#define COOKIE_PREFIX__HOST (1 << 1)
|
||||
|
||||
#define COOKIE_HASH_SIZE 63
|
||||
|
||||
|
|
@ -60,9 +57,9 @@ struct CookieInfo {
|
|||
/* linked lists of cookies we know of */
|
||||
struct Curl_llist cookielist[COOKIE_HASH_SIZE];
|
||||
curl_off_t next_expiration; /* the next time at which expiration happens */
|
||||
unsigned int numcookies; /* number of cookies in the "jar" */
|
||||
unsigned int lastct; /* last creation-time used in the jar */
|
||||
BIT(running); /* state info, for cookie adding information */
|
||||
unsigned int numcookies; /* number of cookies in the "jar" */
|
||||
unsigned int lastct; /* last creation-time used in the jar */
|
||||
BIT(running); /* state info, for cookie adding information */
|
||||
BIT(newsession); /* new session, discard session cookies on load */
|
||||
};
|
||||
|
||||
|
|
@ -113,30 +110,31 @@ struct connectdata;
|
|||
*/
|
||||
|
||||
bool Curl_secure_context(struct connectdata *conn, const char *host);
|
||||
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);
|
||||
int Curl_cookie_getlist(struct Curl_easy *data, struct connectdata *conn,
|
||||
const char *host, struct Curl_llist *list);
|
||||
CURLcode 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) WARN_UNUSED_RESULT;
|
||||
CURLcode Curl_cookie_getlist(struct Curl_easy *data, struct connectdata *conn,
|
||||
bool *okay, const char *host,
|
||||
struct Curl_llist *list) WARN_UNUSED_RESULT;
|
||||
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_loadfiles(x) CURLE_OK
|
||||
#define Curl_cookie_init() NULL
|
||||
#define Curl_cookie_run(x) Curl_nop_stmt
|
||||
#define Curl_cookie_cleanup(x) Curl_nop_stmt
|
||||
#define Curl_flush_cookies(x,y) 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 CookieInfo *Curl_cookie_init(void);
|
||||
struct curl_slist *Curl_cookie_list(struct Curl_easy *data);
|
||||
void Curl_cookie_loadfiles(struct Curl_easy *data);
|
||||
CURLcode Curl_cookie_loadfiles(struct Curl_easy *data) WARN_UNUSED_RESULT;
|
||||
void Curl_cookie_run(struct Curl_easy *data);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_COOKIE_H */
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "cfilters.h"
|
||||
|
|
@ -35,17 +33,11 @@
|
|||
#include "multi_ev.h"
|
||||
#include "sendf.h"
|
||||
#include "cshutdn.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "sigpipe.h"
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
static void cshutdn_run_conn_handler(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
|
|
@ -123,7 +115,6 @@ void Curl_cshutdn_run_once(struct Curl_easy *data,
|
|||
Curl_detach_connection(data);
|
||||
}
|
||||
|
||||
|
||||
void Curl_cshutdn_terminate(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool do_shutdown)
|
||||
|
|
@ -231,15 +222,12 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void cshutdn_perform(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_llist_node *e = Curl_llist_head(&cshutdn->list);
|
||||
struct Curl_llist_node *enext;
|
||||
struct connectdata *conn;
|
||||
struct curltime *nowp = NULL;
|
||||
struct curltime now;
|
||||
timediff_t next_expire_ms = 0, ms;
|
||||
bool done;
|
||||
|
||||
|
|
@ -259,11 +247,7 @@ static void cshutdn_perform(struct cshutdn *cshutdn,
|
|||
else {
|
||||
/* idata has one timer list, but maybe more than one connection.
|
||||
* Set EXPIRE_SHUTDOWN to the smallest time left for all. */
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
ms = Curl_conn_shutdown_timeleft(conn, nowp);
|
||||
ms = Curl_conn_shutdown_timeleft(data, conn);
|
||||
if(ms && ms < next_expire_ms)
|
||||
next_expire_ms = ms;
|
||||
}
|
||||
|
|
@ -271,15 +255,14 @@ static void cshutdn_perform(struct cshutdn *cshutdn,
|
|||
}
|
||||
|
||||
if(next_expire_ms)
|
||||
Curl_expire_ex(data, nowp, next_expire_ms, EXPIRE_SHUTDOWN);
|
||||
Curl_expire_ex(data, next_expire_ms, EXPIRE_SHUTDOWN);
|
||||
}
|
||||
|
||||
|
||||
static void cshutdn_terminate_all(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data,
|
||||
int timeout_ms)
|
||||
{
|
||||
struct curltime started = curlx_now();
|
||||
struct curltime started = *Curl_pgrs_now(data);
|
||||
struct Curl_llist_node *e;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
|
|
@ -291,7 +274,7 @@ static void cshutdn_terminate_all(struct cshutdn *cshutdn,
|
|||
sigpipe_apply(data, &pipe_st);
|
||||
|
||||
while(Curl_llist_head(&cshutdn->list)) {
|
||||
timediff_t timespent;
|
||||
timediff_t spent_ms;
|
||||
int remain_ms;
|
||||
|
||||
cshutdn_perform(cshutdn, data);
|
||||
|
|
@ -302,14 +285,14 @@ static void cshutdn_terminate_all(struct cshutdn *cshutdn,
|
|||
}
|
||||
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
timespent = curlx_timediff(curlx_now(), started);
|
||||
if(timespent >= (timediff_t)timeout_ms) {
|
||||
spent_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &started);
|
||||
if(spent_ms >= (timediff_t)timeout_ms) {
|
||||
CURL_TRC_M(data, "[SHUTDOWN] shutdown finished, %s",
|
||||
(timeout_ms > 0) ? "timeout" : "best effort done");
|
||||
(timeout_ms > 0) ? "timeout" : "best effort done");
|
||||
break;
|
||||
}
|
||||
|
||||
remain_ms = timeout_ms - (int)timespent;
|
||||
remain_ms = timeout_ms - (int)spent_ms;
|
||||
if(cshutdn_wait(cshutdn, data, remain_ms)) {
|
||||
CURL_TRC_M(data, "[SHUTDOWN] shutdown finished, aborted");
|
||||
break;
|
||||
|
|
@ -329,7 +312,6 @@ static void cshutdn_terminate_all(struct cshutdn *cshutdn,
|
|||
sigpipe_restore(&pipe_st);
|
||||
}
|
||||
|
||||
|
||||
int Curl_cshutdn_init(struct cshutdn *cshutdn,
|
||||
struct Curl_multi *multi)
|
||||
{
|
||||
|
|
@ -340,7 +322,6 @@ int Curl_cshutdn_init(struct cshutdn *cshutdn,
|
|||
return 0; /* good */
|
||||
}
|
||||
|
||||
|
||||
void Curl_cshutdn_destroy(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
|
|
@ -392,7 +373,6 @@ size_t Curl_cshutdn_dest_count(struct Curl_easy *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static CURLMcode cshutdn_update_ev(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
|
|
@ -408,14 +388,12 @@ static CURLMcode cshutdn_update_ev(struct cshutdn *cshutdn,
|
|||
return mresult;
|
||||
}
|
||||
|
||||
|
||||
void Curl_cshutdn_add(struct cshutdn *cshutdn,
|
||||
struct connectdata *conn,
|
||||
size_t conns_in_pool)
|
||||
{
|
||||
struct Curl_easy *data = cshutdn->multi->admin;
|
||||
size_t max_total = (cshutdn->multi->max_total_connections > 0) ?
|
||||
(size_t)cshutdn->multi->max_total_connections : 0;
|
||||
size_t max_total = cshutdn->multi->max_total_connections;
|
||||
|
||||
/* Add the connection to our shutdown list for non-blocking shutdown
|
||||
* during multi processing. */
|
||||
|
|
@ -441,7 +419,6 @@ void Curl_cshutdn_add(struct cshutdn *cshutdn,
|
|||
conn->connection_id, Curl_llist_count(&cshutdn->list));
|
||||
}
|
||||
|
||||
|
||||
static void cshutdn_multi_socket(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data,
|
||||
curl_socket_t s)
|
||||
|
|
@ -466,7 +443,6 @@ static void cshutdn_multi_socket(struct cshutdn *cshutdn,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Curl_cshutdn_perform(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data,
|
||||
curl_socket_t s)
|
||||
|
|
@ -488,8 +464,7 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn,
|
|||
struct easy_pollset ps;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
for(e = Curl_llist_head(&cshutdn->list); e;
|
||||
e = Curl_node_next(e)) {
|
||||
for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) {
|
||||
unsigned int i;
|
||||
struct connectdata *conn = Curl_node_elem(e);
|
||||
CURLcode result;
|
||||
|
|
@ -503,20 +478,23 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn,
|
|||
continue;
|
||||
|
||||
for(i = 0; i < ps.n; i++) {
|
||||
curl_socket_t sock = ps.sockets[i];
|
||||
if(!FDSET_SOCK(sock))
|
||||
continue;
|
||||
#ifdef __DJGPP__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warith-conversion"
|
||||
#endif
|
||||
if(ps.actions[i] & CURL_POLL_IN)
|
||||
FD_SET(ps.sockets[i], read_fd_set);
|
||||
FD_SET(sock, read_fd_set);
|
||||
if(ps.actions[i] & CURL_POLL_OUT)
|
||||
FD_SET(ps.sockets[i], write_fd_set);
|
||||
FD_SET(sock, write_fd_set);
|
||||
#ifdef __DJGPP__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
if((ps.actions[i] & (CURL_POLL_OUT | CURL_POLL_IN)) &&
|
||||
((int)ps.sockets[i] > *maxfd))
|
||||
*maxfd = (int)ps.sockets[i];
|
||||
((int)sock > *maxfd))
|
||||
*maxfd = (int)sock;
|
||||
}
|
||||
}
|
||||
Curl_pollset_cleanup(&ps);
|
||||
|
|
@ -537,8 +515,7 @@ unsigned int Curl_cshutdn_add_waitfds(struct cshutdn *cshutdn,
|
|||
CURLcode result;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
for(e = Curl_llist_head(&cshutdn->list); e;
|
||||
e = Curl_node_next(e)) {
|
||||
for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) {
|
||||
conn = Curl_node_elem(e);
|
||||
Curl_pollset_reset(&ps);
|
||||
Curl_attach_connection(data, conn);
|
||||
|
|
@ -565,8 +542,7 @@ CURLcode Curl_cshutdn_add_pollfds(struct cshutdn *cshutdn,
|
|||
struct connectdata *conn;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
for(e = Curl_llist_head(&cshutdn->list); e;
|
||||
e = Curl_node_next(e)) {
|
||||
for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) {
|
||||
conn = Curl_node_elem(e);
|
||||
Curl_pollset_reset(&ps);
|
||||
Curl_attach_connection(data, conn);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
struct connectdata;
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
|
@ -47,17 +45,13 @@
|
|||
# include <inet.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stddef.h> /* for offsetof() */
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
#include "fake_addrinfo.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "curlx/warnless.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_freeaddrinfo()
|
||||
*
|
||||
|
|
@ -68,26 +62,24 @@
|
|||
*/
|
||||
|
||||
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
|
||||
defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
|
||||
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)
|
||||
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);
|
||||
curlx_free(ca);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
/*
|
||||
* Curl_getaddrinfo_ex()
|
||||
|
|
@ -102,12 +94,10 @@ Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
|
|||
* 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)
|
||||
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;
|
||||
|
|
@ -146,7 +136,7 @@ Curl_getaddrinfo_ex(const char *nodename,
|
|||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
ca = malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
ca = curlx_malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
|
|
@ -180,7 +170,6 @@ Curl_getaddrinfo_ex(const char *nodename,
|
|||
if(calast)
|
||||
calast->ai_next = ca;
|
||||
calast = ca;
|
||||
|
||||
}
|
||||
|
||||
/* destroy the addrinfo list */
|
||||
|
|
@ -212,7 +201,6 @@ Curl_getaddrinfo_ex(const char *nodename,
|
|||
}
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
|
||||
/*
|
||||
* Curl_he2ai()
|
||||
*
|
||||
|
|
@ -252,10 +240,8 @@ Curl_getaddrinfo_ex(const char *nodename,
|
|||
*
|
||||
* #define h_addr h_addr_list[0]
|
||||
*/
|
||||
|
||||
#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
|
||||
struct Curl_addrinfo *
|
||||
Curl_he2ai(const struct hostent *he, int port)
|
||||
struct Curl_addrinfo *Curl_he2ai(const struct hostent *he, int port)
|
||||
{
|
||||
struct Curl_addrinfo *ai;
|
||||
struct Curl_addrinfo *prevai = NULL;
|
||||
|
|
@ -285,7 +271,7 @@ Curl_he2ai(const struct hostent *he, int port)
|
|||
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);
|
||||
ai = curlx_calloc(1, sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
if(!ai) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
|
|
@ -347,16 +333,15 @@ Curl_he2ai(const struct hostent *he, int port)
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Curl_ip2addr()
|
||||
* 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)
|
||||
static CURLcode ip2addr(struct Curl_addrinfo **addrp, int af,
|
||||
const void *inaddr, const char *hostname, int port)
|
||||
{
|
||||
struct Curl_addrinfo *ai;
|
||||
size_t addrsize;
|
||||
|
|
@ -369,6 +354,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
|||
DEBUGASSERT(inaddr && hostname);
|
||||
|
||||
namelen = strlen(hostname) + 1;
|
||||
*addrp = NULL;
|
||||
|
||||
if(af == AF_INET)
|
||||
addrsize = sizeof(struct sockaddr_in);
|
||||
|
|
@ -377,12 +363,12 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
|||
addrsize = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
else
|
||||
return NULL;
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
/* allocate memory to hold the struct, the address and the name */
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + addrsize + namelen);
|
||||
ai = curlx_calloc(1, sizeof(struct Curl_addrinfo) + addrsize + namelen);
|
||||
if(!ai)
|
||||
return NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
/* put the address after the struct */
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
/* then put the name after the address */
|
||||
|
|
@ -412,29 +398,46 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
|||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ai;
|
||||
*addrp = ai;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
CURLcode Curl_str2addr(const char *address, int port,
|
||||
struct Curl_addrinfo **addrp)
|
||||
{
|
||||
struct in_addr in;
|
||||
if(curlx_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);
|
||||
return ip2addr(addrp, AF_INET, &in, address, port);
|
||||
#ifdef USE_IPV6
|
||||
{
|
||||
struct in6_addr in6;
|
||||
if(curlx_inet_pton(AF_INET6, address, &in6) > 0)
|
||||
/* This is a dotted IPv6 address ::1-style */
|
||||
return Curl_ip2addr(AF_INET6, &in6, address, port);
|
||||
return ip2addr(addrp, AF_INET6, &in6, address, port);
|
||||
}
|
||||
#endif
|
||||
return NULL; /* bad input format */
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT; /* bad input format */
|
||||
}
|
||||
|
||||
bool Curl_is_ipaddr(const char *address)
|
||||
{
|
||||
struct in_addr in;
|
||||
if(curlx_inet_pton(AF_INET, address, &in) > 0)
|
||||
return TRUE;
|
||||
#ifdef USE_IPV6
|
||||
{
|
||||
struct in6_addr in6;
|
||||
if(curlx_inet_pton(AF_INET6, address, &in6) > 0)
|
||||
/* This is a dotted IPv6 address ::1-style */
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
|
|
@ -452,18 +455,19 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
|||
|
||||
*longpath = FALSE;
|
||||
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_un));
|
||||
ai = curlx_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 = (void *)ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
|
||||
/* sun_path must be able to store the null-terminated path */
|
||||
path_len = strlen(path) + 1;
|
||||
if(path_len > sizeof(sa_un->sun_path)) {
|
||||
free(ai);
|
||||
curlx_free(ai);
|
||||
*longpath = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -492,10 +496,8 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
|||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I did not want to include in memdebug.c
|
||||
*/
|
||||
|
||||
void
|
||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source)
|
||||
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);
|
||||
|
|
@ -517,7 +519,6 @@ curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
|||
}
|
||||
#endif /* CURLDEBUG && HAVE_FREEADDRINFO */
|
||||
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
|
||||
/*
|
||||
* curl_dbg_getaddrinfo()
|
||||
|
|
@ -526,13 +527,11 @@ curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
|||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I did not 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)
|
||||
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);
|
||||
|
|
@ -550,11 +549,10 @@ curl_dbg_getaddrinfo(const char *hostname,
|
|||
#endif
|
||||
if(res == 0)
|
||||
/* success */
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n",
|
||||
source, line, (void *)*result);
|
||||
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);
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n", source, line);
|
||||
return res;
|
||||
}
|
||||
#endif /* CURLDEBUG && HAVE_GETADDRINFO */
|
||||
|
|
|
|||
|
|
@ -60,26 +60,21 @@ struct Curl_addrinfo {
|
|||
struct Curl_addrinfo *ai_next;
|
||||
};
|
||||
|
||||
void
|
||||
Curl_freeaddrinfo(struct Curl_addrinfo *cahead);
|
||||
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);
|
||||
int Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct Curl_addrinfo **result);
|
||||
#endif
|
||||
|
||||
#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
|
||||
struct Curl_addrinfo *
|
||||
Curl_he2ai(const struct hostent *he, int port);
|
||||
struct Curl_addrinfo *Curl_he2ai(const struct hostent *he, int port);
|
||||
#endif
|
||||
|
||||
struct Curl_addrinfo *
|
||||
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
|
||||
|
||||
struct Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
bool Curl_is_ipaddr(const char *address);
|
||||
CURLcode Curl_str2addr(const char *dotted, int port, struct Curl_addrinfo **);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
||||
|
|
@ -87,23 +82,23 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
|||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
defined(HAVE_FREEADDRINFO)
|
||||
void
|
||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source);
|
||||
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);
|
||||
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)
|
||||
#define Curl_addrinfo_set_port(x, y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@
|
|||
/* disabled WebSocket */
|
||||
#cmakedefine CURL_DISABLE_WEBSOCKETS 1
|
||||
|
||||
/* disables use of socketpair for curl_multi_poll */
|
||||
/* disables use of socketpair for curl_multi_poll() */
|
||||
#cmakedefine CURL_DISABLE_SOCKETPAIR 1
|
||||
|
||||
/* disables TELNET */
|
||||
|
|
@ -160,6 +160,9 @@
|
|||
/* disables TFTP */
|
||||
#cmakedefine CURL_DISABLE_TFTP 1
|
||||
|
||||
/* disables curl_easy_setopt()/curl_easy_getinfo() type checking */
|
||||
#cmakedefine CURL_DISABLE_TYPECHECK 1
|
||||
|
||||
/* disables verbose strings */
|
||||
#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
|
||||
|
||||
|
|
@ -388,6 +391,9 @@
|
|||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#cmakedefine HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if you have a working localtime_r function. */
|
||||
#cmakedefine HAVE_LOCALTIME_R 1
|
||||
|
||||
/* Define to 1 if the compiler supports the 'long long' data type. */
|
||||
#cmakedefine HAVE_LONGLONG 1
|
||||
|
||||
|
|
@ -727,6 +733,9 @@ ${SIZEOF_TIME_T_CODE}
|
|||
/* Define to 1 if you have the <uv.h> header file. */
|
||||
#cmakedefine HAVE_UV_H 1
|
||||
|
||||
/* if libbacktrace is in use */
|
||||
#cmakedefine USE_BACKTRACE 1
|
||||
|
||||
/* Define to 1 if you do not want the OpenSSL configuration to be loaded
|
||||
automatically */
|
||||
#cmakedefine CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG 1
|
||||
|
|
@ -755,9 +764,6 @@ ${SIZEOF_TIME_T_CODE}
|
|||
/* 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
|
||||
|
||||
|
|
@ -25,17 +25,17 @@
|
|||
***************************************************************************/
|
||||
|
||||
#define ISLOWHEXALHA(x) (((x) >= 'a') && ((x) <= 'f'))
|
||||
#define ISUPHEXALHA(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 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 ISCNTRL(x) (ISLOWCNTRL(x) || IS7F(x))
|
||||
#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x))
|
||||
#define ISXDIGIT(x) (ISDIGIT(x) || ISLOWHEXALHA(x) || ISUPHEXALHA(x))
|
||||
#define ISODIGIT(x) (((x) >= '0') && ((x) <= '7'))
|
||||
#define ISALNUM(x) (ISDIGIT(x) || ISLOWER(x) || ISUPPER(x))
|
||||
|
|
|
|||
|
|
@ -24,13 +24,8 @@
|
|||
|
||||
#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
|
||||
|
||||
|
|
@ -243,7 +238,7 @@ static int setcharset(const unsigned char **p, unsigned char *charset)
|
|||
case CURLFNM_SCHS_RIGHTBRLEFTBR:
|
||||
if(c == ']')
|
||||
return SETCHARSET_OK;
|
||||
state = CURLFNM_SCHS_DEFAULT;
|
||||
state = CURLFNM_SCHS_DEFAULT;
|
||||
charset[c] = 1;
|
||||
(*p)++;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -31,10 +31,6 @@
|
|||
#include "rand.h"
|
||||
#include "curl_fopen.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
The dirslash() function breaks a null-terminated pathname string into
|
||||
directory and filename components then returns the directory component up
|
||||
|
|
@ -66,10 +62,10 @@ static char *dirslash(const char *path)
|
|||
n = strlen(path);
|
||||
if(n) {
|
||||
/* find the rightmost path separator, if any */
|
||||
while(n && !IS_SEP(path[n-1]))
|
||||
while(n && !IS_SEP(path[n - 1]))
|
||||
--n;
|
||||
/* skip over all the path separators, if any */
|
||||
while(n && IS_SEP(path[n-1]))
|
||||
while(n && IS_SEP(path[n - 1]))
|
||||
--n;
|
||||
}
|
||||
if(curlx_dyn_addn(&out, path, n))
|
||||
|
|
@ -93,25 +89,22 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
|||
CURLcode result = CURLE_WRITE_ERROR;
|
||||
unsigned char randbuf[41];
|
||||
char *tempstore = NULL;
|
||||
#ifndef _WIN32
|
||||
struct_stat sb;
|
||||
#endif
|
||||
int fd = -1;
|
||||
char *dir = NULL;
|
||||
*tempname = NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
*fh = curlx_fopen(filename, FOPEN_WRITETEXT);
|
||||
if(!*fh)
|
||||
goto fail;
|
||||
if(
|
||||
#ifdef UNDER_CE
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
stat(filename, &sb) == -1
|
||||
#else
|
||||
fstat(fileno(*fh), &sb) == -1
|
||||
#endif
|
||||
|| !S_ISREG(sb.st_mode)) {
|
||||
if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) {
|
||||
return CURLE_OK;
|
||||
}
|
||||
curlx_fclose(*fh);
|
||||
#endif
|
||||
*fh = NULL;
|
||||
|
||||
result = Curl_rand_alnum(data, randbuf, sizeof(randbuf));
|
||||
|
|
@ -123,7 +116,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
|||
/* The temp filename should not end up too long for the target file
|
||||
system */
|
||||
tempstore = curl_maprintf("%s%s.tmp", dir, randbuf);
|
||||
free(dir);
|
||||
curlx_free(dir);
|
||||
}
|
||||
|
||||
if(!tempstore) {
|
||||
|
|
@ -132,13 +125,16 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
|||
}
|
||||
|
||||
result = CURLE_WRITE_ERROR;
|
||||
#if (defined(ANDROID) || defined(__ANDROID__)) && \
|
||||
#ifdef _WIN32
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
S_IREAD | S_IWRITE);
|
||||
#elif (defined(ANDROID) || defined(__ANDROID__)) && \
|
||||
(defined(__i386__) || defined(__arm__))
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
(mode_t)(0600 | sb.st_mode));
|
||||
(mode_t)(S_IRUSR | S_IWUSR | sb.st_mode));
|
||||
#else
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
0600 | sb.st_mode);
|
||||
S_IRUSR | S_IWUSR | sb.st_mode);
|
||||
#endif
|
||||
if(fd == -1)
|
||||
goto fail;
|
||||
|
|
@ -156,7 +152,7 @@ fail:
|
|||
unlink(tempstore);
|
||||
}
|
||||
|
||||
free(tempstore);
|
||||
curlx_free(tempstore);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,12 +28,8 @@
|
|||
!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"
|
||||
|
||||
#define appendnl(b) \
|
||||
curlx_dyn_addn(buf, "\n", 1)
|
||||
#define appendnl(b) curlx_dyn_addn(buf, "\n", 1)
|
||||
|
||||
/*
|
||||
* Curl_get_line() returns only complete whole lines that end with newline.
|
||||
|
|
@ -60,7 +56,7 @@ CURLcode Curl_get_line(struct dynbuf *buf, FILE *input, bool *eof)
|
|||
/* now check the full line */
|
||||
rlen = curlx_dyn_len(buf);
|
||||
b = curlx_dyn_ptr(buf);
|
||||
if(rlen && (b[rlen-1] == '\n'))
|
||||
if(rlen && (b[rlen - 1] == '\n'))
|
||||
/* LF at end of the line */
|
||||
return CURLE_OK; /* all good */
|
||||
if(*eof)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
|
|||
if(strlen(force_hostname) < (size_t)namelen)
|
||||
strcpy(name, force_hostname);
|
||||
else
|
||||
return 1; /* can't do it */
|
||||
return 1; /* cannot do it */
|
||||
err = 0;
|
||||
}
|
||||
else {
|
||||
|
|
@ -93,5 +93,4 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
|
|||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,10 +31,8 @@
|
|||
|
||||
#ifdef DEBUGBUILD
|
||||
#if defined(HAVE_GSSGNU) || !defined(_WIN32)
|
||||
/* To avoid memdebug macro replacement, wrap the name in parentheses to call
|
||||
the original version. It is freed via the GSS API gss_release_buffer(). */
|
||||
#define Curl_gss_alloc (malloc)
|
||||
#define Curl_gss_free (free)
|
||||
#define Curl_gss_alloc malloc /* freed via the GSS API gss_release_buffer() */
|
||||
#define Curl_gss_free free /* pair of the above */
|
||||
#define CURL_GSS_STUB
|
||||
/* For correctness this would be required for all platforms, not only Windows,
|
||||
but, as of v1.22.1, MIT Kerberos uses a special allocator only for Windows,
|
||||
|
|
@ -51,10 +49,6 @@
|
|||
#endif
|
||||
#endif /* DEBUGBUILD */
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CURL_ALIGN8 __attribute__((aligned(8)))
|
||||
#else
|
||||
|
|
@ -160,7 +154,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
|||
}
|
||||
|
||||
/* Server response, either D (RA==) or C (Qw==) */
|
||||
if(((char *) input_token->value)[0] == 'D') {
|
||||
if(((char *)input_token->value)[0] == 'D') {
|
||||
/* Done */
|
||||
switch(ctx->sent) {
|
||||
case STUB_GSS_KRB5:
|
||||
|
|
@ -176,7 +170,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
|||
}
|
||||
}
|
||||
|
||||
if(((char *) input_token->value)[0] != 'C') {
|
||||
if(((char *)input_token->value)[0] != 'C') {
|
||||
/* We only support Done or Continue */
|
||||
*min = STUB_GSS_SERVER_ERR;
|
||||
return GSS_S_FAILURE;
|
||||
|
|
@ -208,7 +202,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
|||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
|
|
@ -225,7 +219,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
|||
else if(ctx->have_ntlm)
|
||||
ctx->sent = STUB_GSS_NTLM1;
|
||||
else {
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MECH;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
|
@ -236,7 +230,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
|||
|
||||
token = Curl_gss_alloc(length);
|
||||
if(!token) {
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
|
@ -250,14 +244,14 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
|||
&target_desc, &name_type);
|
||||
if(GSS_ERROR(major_status)) {
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if(strlen(creds) + target_desc.length + 5 >= sizeof(ctx->creds)) {
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
|
@ -273,7 +267,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
|||
|
||||
if(used >= length) {
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
|
@ -308,7 +302,7 @@ stub_gss_delete_sec_context(OM_uint32 *min,
|
|||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
free(*context);
|
||||
curlx_free(*context);
|
||||
*context = NULL;
|
||||
*min = 0;
|
||||
|
||||
|
|
@ -392,7 +386,8 @@ OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min,
|
|||
|
||||
#define GSS_LOG_BUFFER_LEN 1024
|
||||
static size_t display_gss_error(OM_uint32 status, int type,
|
||||
char *buf, size_t len) {
|
||||
char *buf, size_t len)
|
||||
{
|
||||
OM_uint32 maj_stat;
|
||||
OM_uint32 min_stat;
|
||||
OM_uint32 msg_ctx = 0;
|
||||
|
|
@ -433,7 +428,7 @@ static size_t display_gss_error(OM_uint32 status, int type,
|
|||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
OM_uint32 major, OM_uint32 minor)
|
||||
{
|
||||
char buf[GSS_LOG_BUFFER_LEN];
|
||||
char buf[GSS_LOG_BUFFER_LEN] = "";
|
||||
size_t len = 0;
|
||||
|
||||
if(major != GSS_S_FAILURE)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
!defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \
|
||||
defined(USE_LIBSSH2) || defined(USE_SSL)
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define HMAC_MD5_LENGTH 16
|
||||
|
||||
typedef CURLcode (*HMAC_hinit)(void *context);
|
||||
|
|
@ -48,7 +46,6 @@ struct HMAC_params {
|
|||
unsigned int resultlen; /* Result length (bytes). */
|
||||
};
|
||||
|
||||
|
||||
/* HMAC computation context. */
|
||||
struct HMAC_context {
|
||||
const struct HMAC_params *hash; /* Hash function definition. */
|
||||
|
|
@ -56,7 +53,6 @@ struct HMAC_context {
|
|||
void *hashctxt2; /* Hash function context 2. */
|
||||
};
|
||||
|
||||
|
||||
/* Prototypes. */
|
||||
struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams,
|
||||
const unsigned char *key,
|
||||
|
|
|
|||
|
|
@ -26,11 +26,12 @@
|
|||
#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)))
|
||||
#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
|
||||
|
||||
void Curl_ldap_version(char *buf, size_t bufsz);
|
||||
#endif
|
||||
#endif /* HEADER_CURL_LDAP_H */
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef USE_CURL_NTLM_CORE
|
||||
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
#ifndef HEADER_CURL_MEMORY_H
|
||||
#define HEADER_CURL_MEMORY_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Nasty internal details ahead...
|
||||
*
|
||||
* File curl_memory.h must be included by _all_ *.c source files
|
||||
* that use memory related functions strdup, malloc, calloc, realloc
|
||||
* or free, and given source file is used to build libcurl library.
|
||||
* It should be included immediately before memdebug.h as the last files
|
||||
* included to avoid undesired interaction with other memory function
|
||||
* headers in dependent libraries.
|
||||
*
|
||||
* There is nearly no exception to above rule. All libcurl source
|
||||
* files in 'lib' subdirectory as well as those living deep inside
|
||||
* 'packages' subdirectories and linked together in order to build
|
||||
* libcurl library shall follow it.
|
||||
*
|
||||
* File lib/strdup.c is an exception, given that it provides a strdup
|
||||
* clone implementation while using malloc. Extra care needed inside
|
||||
* this one.
|
||||
*
|
||||
* The need for curl_memory.h inclusion is due to libcurl's feature
|
||||
* of allowing library user to provide memory replacement functions,
|
||||
* memory callbacks, at runtime with curl_global_init_mem()
|
||||
*
|
||||
* Any *.c source file used to build libcurl library that does not
|
||||
* include curl_memory.h and uses any memory function of the five
|
||||
* mentioned above will compile without any indication, but it will
|
||||
* trigger weird memory related issues at runtime.
|
||||
*
|
||||
*/
|
||||
|
||||
#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
|
||||
#undef Curl_tcsdup
|
||||
#ifdef UNICODE
|
||||
#define Curl_tcsdup(ptr) Curl_wcsdup(ptr)
|
||||
#else
|
||||
#define Curl_tcsdup(ptr) Curl_cstrdup(ptr)
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* CURLDEBUG */
|
||||
#endif /* HEADER_CURL_MEMORY_H */
|
||||
|
|
@ -24,13 +24,7 @@
|
|||
|
||||
#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
|
||||
/*
|
||||
|
|
@ -41,9 +35,7 @@
|
|||
* 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)
|
||||
void *Curl_memrchr(const void *s, int c, size_t n)
|
||||
{
|
||||
if(n > 0) {
|
||||
const unsigned char *p = s;
|
||||
|
|
|
|||
|
|
@ -28,14 +28,13 @@
|
|||
|
||||
#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))
|
||||
#define memrchr(x, y, z) Curl_memrchr(x, y, z)
|
||||
|
||||
#endif /* HAVE_MEMRCHR */
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
#ifdef USE_MBEDTLS
|
||||
#include <mbedtls/version.h>
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03020000
|
||||
#error "mbedTLS 3.2.0 or later required"
|
||||
#error "mbedTLS 3.2.0 or later required"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -69,8 +69,6 @@
|
|||
|
||||
#ifdef USE_OPENSSL
|
||||
# include <openssl/des.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/rand.h>
|
||||
# ifdef OPENSSL_IS_AWSLC /* for versions 1.2.0 to 1.30.1 */
|
||||
# define DES_set_key_unchecked (void)DES_set_key
|
||||
# endif
|
||||
|
|
@ -78,16 +76,14 @@
|
|||
#else
|
||||
# include <wolfssl/options.h>
|
||||
# include <wolfssl/openssl/des.h>
|
||||
# include <wolfssl/openssl/ssl.h>
|
||||
# include <wolfssl/openssl/rand.h>
|
||||
# ifdef OPENSSL_COEXIST
|
||||
# define DES_key_schedule WOLFSSL_DES_key_schedule
|
||||
# define DES_cblock WOLFSSL_DES_cblock
|
||||
# define DES_set_odd_parity wolfSSL_DES_set_odd_parity
|
||||
# define DES_set_key wolfSSL_DES_set_key
|
||||
# define DES_key_schedule WOLFSSL_DES_key_schedule
|
||||
# define DES_cblock WOLFSSL_DES_cblock
|
||||
# define DES_set_odd_parity wolfSSL_DES_set_odd_parity
|
||||
# define DES_set_key wolfSSL_DES_set_key
|
||||
# define DES_set_key_unchecked wolfSSL_DES_set_key_unchecked
|
||||
# define DES_ecb_encrypt wolfSSL_DES_ecb_encrypt
|
||||
# define DESKEY(x) ((WOLFSSL_DES_key_schedule *)(x))
|
||||
# define DES_ecb_encrypt wolfSSL_DES_ecb_encrypt
|
||||
# define DESKEY(x) ((WOLFSSL_DES_key_schedule *)(x))
|
||||
# else
|
||||
# define DESKEY(x) &x
|
||||
# endif
|
||||
|
|
@ -119,13 +115,8 @@
|
|||
#include "curl_md5.h"
|
||||
#include "curl_hmac.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "curl_endian.h"
|
||||
#include "curl_md4.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef USE_CURL_DES_SET_ODD_PARITY
|
||||
/*
|
||||
* curl_des_set_odd_parity()
|
||||
|
|
@ -165,8 +156,8 @@ static void curl_des_set_odd_parity(unsigned char *bytes, size_t len)
|
|||
#endif /* USE_CURL_DES_SET_ODD_PARITY */
|
||||
|
||||
/*
|
||||
* Turns a 56-bit key into being 64-bit wide.
|
||||
*/
|
||||
* 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] = (char)key_56[0];
|
||||
|
|
@ -190,7 +181,7 @@ static void setup_des_key(const unsigned char *key_56,
|
|||
DES_cblock key;
|
||||
|
||||
/* Expand the 56-bit key to 64 bits */
|
||||
extend_key_56_to_64(key_56, (char *) &key);
|
||||
extend_key_56_to_64(key_56, (char *)&key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
DES_set_odd_parity(&key);
|
||||
|
|
@ -201,8 +192,7 @@ static void setup_des_key(const unsigned char *key_56,
|
|||
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
static void setup_des_key(const unsigned char *key_56,
|
||||
struct des_ctx *des)
|
||||
static void setup_des_key(const unsigned char *key_56, struct des_ctx *des)
|
||||
{
|
||||
char key[8];
|
||||
|
||||
|
|
@ -210,10 +200,10 @@ static void setup_des_key(const unsigned char *key_56,
|
|||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
curl_des_set_odd_parity((unsigned char *)key, sizeof(key));
|
||||
|
||||
/* Set the key */
|
||||
des_set_key(des, (const uint8_t *) key);
|
||||
des_set_key(des, (const uint8_t *)key);
|
||||
}
|
||||
|
||||
#elif defined(USE_MBEDTLS_DES)
|
||||
|
|
@ -228,11 +218,11 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
|||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
mbedtls_des_key_set_parity((unsigned char *) key);
|
||||
mbedtls_des_key_set_parity((unsigned char *)key);
|
||||
|
||||
/* Perform the encryption */
|
||||
mbedtls_des_init(&ctx);
|
||||
mbedtls_des_setkey_enc(&ctx, (unsigned char *) key);
|
||||
mbedtls_des_setkey_enc(&ctx, (unsigned char *)key);
|
||||
return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
|
||||
}
|
||||
|
||||
|
|
@ -252,10 +242,10 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
|||
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);
|
||||
curl_des_set_odd_parity((unsigned char *)ctl.Crypto_Key, ctl.Data_Len);
|
||||
|
||||
/* Perform the encryption */
|
||||
_CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
|
||||
_CIPHER((_SPCPTR *)&out, &ctl, (_SPCPTR *)&in);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -290,10 +280,10 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
|||
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));
|
||||
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)) {
|
||||
if(!CryptImportKey(hprov, (BYTE *)&blob, sizeof(blob), 0, 0, &hkey)) {
|
||||
CryptReleaseContext(hprov, 0);
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -312,11 +302,11 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
|||
|
||||
#endif /* 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.
|
||||
*/
|
||||
/*
|
||||
* 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)
|
||||
|
|
@ -325,16 +315,16 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
|||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(keys, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*)CURL_UNCONST(plaintext),
|
||||
(DES_cblock*)results, DESKEY(ks), DES_ENCRYPT);
|
||||
DES_ecb_encrypt((DES_cblock *)CURL_UNCONST(plaintext),
|
||||
(DES_cblock *)results, DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(keys + 7, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*)CURL_UNCONST(plaintext),
|
||||
(DES_cblock*)(results + 8), DESKEY(ks), DES_ENCRYPT);
|
||||
DES_ecb_encrypt((DES_cblock *)CURL_UNCONST(plaintext),
|
||||
(DES_cblock *)(results + 8), DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(keys + 14, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*)CURL_UNCONST(plaintext),
|
||||
(DES_cblock*)(results + 16), DESKEY(ks), DES_ENCRYPT);
|
||||
DES_ecb_encrypt((DES_cblock *)CURL_UNCONST(plaintext),
|
||||
(DES_cblock *)(results + 16), DESKEY(ks), DES_ENCRYPT);
|
||||
#elif defined(USE_GNUTLS)
|
||||
struct des_ctx des;
|
||||
setup_des_key(keys, &des);
|
||||
|
|
@ -435,9 +425,9 @@ CURLcode Curl_ntlm_core_mk_nt_hash(const char *password,
|
|||
size_t len = strlen(password);
|
||||
unsigned char *pw;
|
||||
CURLcode result;
|
||||
if(len > SIZE_MAX/2) /* avoid integer overflow */
|
||||
if(len > SIZE_MAX / 2) /* avoid integer overflow */
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
pw = len ? malloc(len * 2) : (unsigned char *)strdup("");
|
||||
pw = len ? curlx_malloc(len * 2) : (unsigned char *)curlx_strdup("");
|
||||
if(!pw)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -448,7 +438,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(const char *password,
|
|||
if(!result)
|
||||
memset(ntbuffer + 16, 0, 21 - 16);
|
||||
|
||||
free(pw);
|
||||
curlx_free(pw);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -456,7 +446,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(const char *password,
|
|||
#ifndef USE_WINDOWS_SSPI
|
||||
|
||||
#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
|
||||
#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4)
|
||||
#define NTLMv2_BLOB_LEN (44 - 16 + ntlm->target_info_len + 4)
|
||||
|
||||
/* Timestamp in tenths of a microsecond since January 1, 1601 00:00:00 UTC. */
|
||||
struct ms_filetime {
|
||||
|
|
@ -469,20 +459,20 @@ static void time2filetime(struct ms_filetime *ft, time_t t)
|
|||
{
|
||||
#if SIZEOF_TIME_T > 4
|
||||
t = (t + (curl_off_t)11644473600) * 10000000;
|
||||
ft->dwLowDateTime = (unsigned int) (t & 0xFFFFFFFF);
|
||||
ft->dwHighDateTime = (unsigned int) (t >> 32);
|
||||
ft->dwLowDateTime = (unsigned int)(t & 0xFFFFFFFF);
|
||||
ft->dwHighDateTime = (unsigned int)(t >> 32);
|
||||
#else
|
||||
unsigned int r, s;
|
||||
unsigned int i;
|
||||
|
||||
ft->dwLowDateTime = (unsigned int)t & 0xFFFFFFFF;
|
||||
ft->dwLowDateTime = (unsigned int)(t & 0xFFFFFFFF);
|
||||
ft->dwHighDateTime = 0;
|
||||
|
||||
# ifndef HAVE_TIME_T_UNSIGNED
|
||||
#ifndef HAVE_TIME_T_UNSIGNED
|
||||
/* Extend sign if needed. */
|
||||
if(ft->dwLowDateTime & 0x80000000)
|
||||
ft->dwHighDateTime = ~(unsigned int)0;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Bias seconds to Jan 1, 1601.
|
||||
134774 days = 11644473600 seconds = 0x2B6109100 */
|
||||
|
|
@ -525,7 +515,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
identity_len = (userlen + domlen) * 2;
|
||||
identity = malloc(identity_len + 1);
|
||||
identity = curlx_malloc(identity_len + 1);
|
||||
|
||||
if(!identity)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
|
@ -535,7 +525,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
|||
|
||||
result = Curl_hmacit(&Curl_HMAC_MD5, ntlmhash, 16, identity, identity_len,
|
||||
ntlmv2hash);
|
||||
free(identity);
|
||||
curlx_free(identity);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -563,20 +553,20 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
|||
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
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
/* 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;
|
||||
|
|
@ -589,7 +579,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
|||
#ifdef DEBUGBUILD
|
||||
char *force_timestamp = getenv("CURL_FORCETIME");
|
||||
if(force_timestamp)
|
||||
time2filetime(&tw, (time_t) 0);
|
||||
time2filetime(&tw, (time_t)0);
|
||||
else
|
||||
#endif
|
||||
time2filetime(&tw, time(NULL));
|
||||
|
|
@ -598,7 +588,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
|||
len = HMAC_MD5_LENGTH + NTLMv2_BLOB_LEN;
|
||||
|
||||
/* Allocate the response */
|
||||
ptr = calloc(1, len);
|
||||
ptr = curlx_calloc(1, len);
|
||||
if(!ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -622,7 +612,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
|||
result = Curl_hmacit(&Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8,
|
||||
NTLMv2_BLOB_LEN + 8, hmac_output);
|
||||
if(result) {
|
||||
free(ptr);
|
||||
curlx_free(ptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -650,10 +640,10 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
|||
*
|
||||
* 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)
|
||||
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];
|
||||
|
|
|
|||
|
|
@ -58,16 +58,16 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
|||
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_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);
|
||||
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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -23,18 +23,18 @@
|
|||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_range.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_trc.h"
|
||||
#include "curlx/strparse.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.
|
||||
*/
|
||||
/*
|
||||
Check if this is a range download, and if so, set the internal variables
|
||||
properly.
|
||||
*/
|
||||
CURLcode Curl_range(struct Curl_easy *data)
|
||||
{
|
||||
if(data->state.use_range && data->state.range) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
CURLcode Curl_range(struct Curl_easy *data);
|
||||
|
|
|
|||
|
|
@ -33,24 +33,18 @@
|
|||
#include "curlx/nonblock.h" /* for curlx_nonblock */
|
||||
#include "progress.h" /* for Curl_pgrsSetUploadSize */
|
||||
#include "transfer.h"
|
||||
#include "bufref.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <librtmp/rtmp.h>
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#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
|
||||
#if defined(USE_WINSOCK) || 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}
|
||||
#define SET_RCVTIMEO(tv, s) struct timeval tv = { s, 0 }
|
||||
#endif
|
||||
|
||||
#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */
|
||||
#define DEF_BUFTIME (2 * 60 * 60 * 1000) /* 2 hours */
|
||||
|
||||
/* meta key for storing RTMP* at connection */
|
||||
#define CURL_META_RTMP_CONN "meta:proto:rtmp:conn"
|
||||
|
|
@ -68,7 +62,7 @@ static Curl_recv rtmp_recv;
|
|||
static Curl_send rtmp_send;
|
||||
|
||||
/*
|
||||
* RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu
|
||||
* RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu/
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmp = {
|
||||
|
|
@ -240,10 +234,9 @@ static CURLcode rtmp_setup_connection(struct Curl_easy *data,
|
|||
|
||||
RTMP_Init(r);
|
||||
RTMP_SetBufferMS(r, DEF_BUFTIME);
|
||||
if(!RTMP_SetupURL(r, data->state.url)) {
|
||||
RTMP_Free(r);
|
||||
if(!RTMP_SetupURL(r, CURL_UNCONST(Curl_bufref_ptr(&data->state.url))))
|
||||
/* rtmp_conn_dtor() performs the cleanup */
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
|
@ -256,6 +249,11 @@ static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
|
|||
if(!r)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
if(conn->sock[FIRSTSOCKET] > INT_MAX) {
|
||||
/* The socket value is invalid for rtmp. */
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET];
|
||||
|
||||
/* We have to know if it is a write before we send the
|
||||
|
|
@ -331,15 +329,15 @@ static CURLcode rtmp_recv(struct Curl_easy *data, int sockindex, char *buf,
|
|||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = Curl_conn_meta_get(conn, CURL_META_RTMP_CONN);
|
||||
CURLcode result = CURLE_OK;
|
||||
ssize_t nread;
|
||||
ssize_t rv;
|
||||
|
||||
(void)sockindex;
|
||||
*pnread = 0;
|
||||
if(!r)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
nread = RTMP_Read(r, buf, curlx_uztosi(len));
|
||||
if(nread < 0) {
|
||||
rv = RTMP_Read(r, buf, curlx_uztosi(len));
|
||||
if(!curlx_sztouz(rv, pnread)) {
|
||||
if(r->m_read.status == RTMP_READ_COMPLETE ||
|
||||
r->m_read.status == RTMP_READ_EOF) {
|
||||
data->req.size = data->req.bytecount;
|
||||
|
|
@ -347,19 +345,17 @@ static CURLcode rtmp_recv(struct Curl_easy *data, int sockindex, char *buf,
|
|||
else
|
||||
result = CURLE_RECV_ERROR;
|
||||
}
|
||||
else
|
||||
*pnread = (size_t)nread;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = Curl_conn_meta_get(conn, CURL_META_RTMP_CONN);
|
||||
ssize_t nwritten;
|
||||
ssize_t rv;
|
||||
|
||||
(void)sockindex;
|
||||
(void)eos;
|
||||
|
|
@ -367,11 +363,10 @@ static CURLcode rtmp_send(struct Curl_easy *data, int sockindex,
|
|||
if(!r)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
nwritten = RTMP_Write(r, (const char *)buf, curlx_uztosi(len));
|
||||
if(nwritten < 0)
|
||||
rv = RTMP_Write(r, (const char *)buf, curlx_uztosi(len));
|
||||
if(!curlx_sztouz(rv, pnwritten))
|
||||
return CURLE_SEND_ERROR;
|
||||
|
||||
*pnwritten = (size_t)nwritten;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,22 +39,15 @@
|
|||
!defined(CURL_DISABLE_POP3) || \
|
||||
(!defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP))
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
|
||||
#include "curlx/base64.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "cfilters.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "curl_hmac.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "sendf.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Supported mechanisms */
|
||||
static const struct {
|
||||
const char *name; /* Name */
|
||||
|
|
@ -96,7 +89,7 @@ unsigned short Curl_sasl_decode_mech(const char *ptr, size_t maxlen,
|
|||
|
||||
for(i = 0; mechtable[i].name; i++) {
|
||||
if(maxlen >= mechtable[i].len &&
|
||||
!memcmp(ptr, mechtable[i].name, mechtable[i].len)) {
|
||||
curl_strnequal(ptr, mechtable[i].name, mechtable[i].len)) {
|
||||
if(len)
|
||||
*len = mechtable[i].len;
|
||||
|
||||
|
|
@ -239,7 +232,7 @@ static CURLcode get_server_message(struct SASL *sasl, struct Curl_easy *data,
|
|||
if(!result && (sasl->params->flags & SASL_FLAG_BASE64)) {
|
||||
unsigned char *msg;
|
||||
size_t msglen;
|
||||
const char *serverdata = (const char *) Curl_bufref_ptr(out);
|
||||
const char *serverdata = Curl_bufref_ptr(out);
|
||||
|
||||
if(!*serverdata || *serverdata == '=')
|
||||
Curl_bufref_set(out, NULL, 0, NULL);
|
||||
|
|
@ -267,7 +260,7 @@ static CURLcode build_message(struct SASL *sasl, struct bufref *msg)
|
|||
char *base64;
|
||||
size_t base64len;
|
||||
|
||||
result = curlx_base64_encode((const char *) Curl_bufref_ptr(msg),
|
||||
result = curlx_base64_encode(Curl_bufref_uptr(msg),
|
||||
Curl_bufref_len(msg), &base64, &base64len);
|
||||
if(!result)
|
||||
Curl_bufref_set(msg, base64, base64len, curl_free);
|
||||
|
|
@ -285,7 +278,7 @@ static CURLcode build_message(struct SASL *sasl, struct bufref *msg)
|
|||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data)
|
||||
{
|
||||
/* Have credentials been provided? */
|
||||
if(data->state.aptr.user)
|
||||
if(data->conn->user[0])
|
||||
return TRUE;
|
||||
|
||||
/* EXTERNAL can authenticate without a username and/or password */
|
||||
|
|
@ -298,7 +291,6 @@ bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data)
|
|||
struct sasl_ctx {
|
||||
struct SASL *sasl;
|
||||
struct connectdata *conn;
|
||||
const char *user;
|
||||
unsigned short enabledmechs;
|
||||
const char *mech;
|
||||
saslstate state1;
|
||||
|
|
@ -324,8 +316,7 @@ static bool sasl_choose_external(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
#ifdef USE_KERBEROS5
|
||||
static bool sasl_choose_krb5(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
if(sctx->user &&
|
||||
(sctx->enabledmechs & SASL_MECH_GSSAPI) &&
|
||||
if((sctx->enabledmechs & SASL_MECH_GSSAPI) &&
|
||||
Curl_auth_is_gssapi_supported() &&
|
||||
Curl_auth_user_contains_domain(sctx->conn->user)) {
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
|
|
@ -359,8 +350,8 @@ static bool sasl_choose_gsasl(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
struct gsasldata *gsasl;
|
||||
struct bufref nullmsg;
|
||||
|
||||
if(sctx->user &&
|
||||
(sctx->enabledmechs & (SASL_MECH_SCRAM_SHA_256|SASL_MECH_SCRAM_SHA_1))) {
|
||||
if((sctx->enabledmechs &
|
||||
(SASL_MECH_SCRAM_SHA_256 | SASL_MECH_SCRAM_SHA_1))) {
|
||||
gsasl = Curl_auth_gsasl_get(sctx->conn);
|
||||
if(!gsasl) {
|
||||
sctx->result = CURLE_OUT_OF_MEMORY;
|
||||
|
|
@ -368,14 +359,14 @@ static bool sasl_choose_gsasl(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
}
|
||||
|
||||
if((sctx->enabledmechs & SASL_MECH_SCRAM_SHA_256) &&
|
||||
Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_256,
|
||||
gsasl)) {
|
||||
Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_256,
|
||||
gsasl)) {
|
||||
sctx->mech = SASL_MECH_STRING_SCRAM_SHA_256;
|
||||
sctx->sasl->authused = SASL_MECH_SCRAM_SHA_256;
|
||||
}
|
||||
else if((sctx->enabledmechs & SASL_MECH_SCRAM_SHA_1) &&
|
||||
Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1,
|
||||
gsasl)) {
|
||||
Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1,
|
||||
gsasl)) {
|
||||
sctx->mech = SASL_MECH_STRING_SCRAM_SHA_1;
|
||||
sctx->sasl->authused = SASL_MECH_SCRAM_SHA_1;
|
||||
}
|
||||
|
|
@ -400,9 +391,7 @@ static bool sasl_choose_gsasl(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
static bool sasl_choose_digest(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
(void)data;
|
||||
if(!sctx->user)
|
||||
return FALSE;
|
||||
else if((sctx->enabledmechs & SASL_MECH_DIGEST_MD5) &&
|
||||
if((sctx->enabledmechs & SASL_MECH_DIGEST_MD5) &&
|
||||
Curl_auth_is_digest_supported()) {
|
||||
sctx->mech = SASL_MECH_STRING_DIGEST_MD5;
|
||||
sctx->state1 = SASL_DIGESTMD5;
|
||||
|
|
@ -422,10 +411,8 @@ static bool sasl_choose_digest(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
#ifdef USE_NTLM
|
||||
static bool sasl_choose_ntlm(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
if(!sctx->user)
|
||||
return FALSE;
|
||||
else if((sctx->enabledmechs & SASL_MECH_NTLM) &&
|
||||
Curl_auth_is_ntlm_supported()) {
|
||||
if((sctx->enabledmechs & SASL_MECH_NTLM) &&
|
||||
Curl_auth_is_ntlm_supported()) {
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
sctx->sasl->params->service;
|
||||
|
|
@ -456,10 +443,11 @@ static bool sasl_choose_ntlm(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
|
||||
static bool sasl_choose_oauth(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
const char *oauth_bearer = data->set.str[STRING_BEARER];
|
||||
const char *oauth_bearer =
|
||||
(!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ?
|
||||
data->set.str[STRING_BEARER] : NULL;
|
||||
|
||||
if(sctx->user && oauth_bearer &&
|
||||
(sctx->enabledmechs & SASL_MECH_OAUTHBEARER)) {
|
||||
if(oauth_bearer && (sctx->enabledmechs & SASL_MECH_OAUTHBEARER)) {
|
||||
const char *hostname;
|
||||
int port;
|
||||
Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port);
|
||||
|
|
@ -481,10 +469,11 @@ static bool sasl_choose_oauth(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
|
||||
static bool sasl_choose_oauth2(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
const char *oauth_bearer = data->set.str[STRING_BEARER];
|
||||
const char *oauth_bearer =
|
||||
(!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ?
|
||||
data->set.str[STRING_BEARER] : NULL;
|
||||
|
||||
if(sctx->user && oauth_bearer &&
|
||||
(sctx->enabledmechs & SASL_MECH_XOAUTH2)) {
|
||||
if(oauth_bearer && (sctx->enabledmechs & SASL_MECH_XOAUTH2)) {
|
||||
sctx->mech = SASL_MECH_STRING_XOAUTH2;
|
||||
sctx->state1 = SASL_OAUTH2;
|
||||
sctx->sasl->authused = SASL_MECH_XOAUTH2;
|
||||
|
|
@ -500,7 +489,7 @@ static bool sasl_choose_oauth2(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
|
||||
static bool sasl_choose_plain(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
if(sctx->user && (sctx->enabledmechs & SASL_MECH_PLAIN)) {
|
||||
if(sctx->enabledmechs & SASL_MECH_PLAIN) {
|
||||
sctx->mech = SASL_MECH_STRING_PLAIN;
|
||||
sctx->state1 = SASL_PLAIN;
|
||||
sctx->sasl->authused = SASL_MECH_PLAIN;
|
||||
|
|
@ -517,7 +506,7 @@ static bool sasl_choose_plain(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
|
||||
static bool sasl_choose_login(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
if(sctx->user && (sctx->enabledmechs & SASL_MECH_LOGIN)) {
|
||||
if(sctx->enabledmechs & SASL_MECH_LOGIN) {
|
||||
sctx->mech = SASL_MECH_STRING_LOGIN;
|
||||
sctx->state1 = SASL_LOGIN;
|
||||
sctx->state2 = SASL_LOGIN_PASSWD;
|
||||
|
|
@ -547,7 +536,6 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
|
|||
memset(&sctx, 0, sizeof(sctx));
|
||||
sctx.sasl = sasl;
|
||||
sctx.conn = data->conn;
|
||||
sctx.user = data->state.aptr.user;
|
||||
Curl_bufref_init(&sctx.resp);
|
||||
sctx.enabledmechs = sasl->authmechs & sasl->prefmech;
|
||||
sctx.state1 = SASL_STOP;
|
||||
|
|
@ -709,7 +697,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
case SASL_NTLM_TYPE2MSG: {
|
||||
/* Decode the type-2 message */
|
||||
struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, FALSE);
|
||||
result = !ntlm ? CURLE_FAILED_INIT :
|
||||
result = !ntlm ? CURLE_OUT_OF_MEMORY :
|
||||
get_server_message(sasl, data, &serverdata);
|
||||
if(!result)
|
||||
result = Curl_auth_decode_ntlm_type2_message(data, &serverdata, ntlm);
|
||||
|
|
@ -876,7 +864,7 @@ static void sasl_unchosen(struct Curl_easy *data, unsigned short mech,
|
|||
else {
|
||||
if(param_missing)
|
||||
infof(data, "SASL: %s is missing %s", mname, param_missing);
|
||||
if(!data->state.aptr.user)
|
||||
if(!data->conn->user[0])
|
||||
infof(data, "SASL: %s is missing username", mname);
|
||||
}
|
||||
}
|
||||
|
|
@ -932,10 +920,10 @@ CURLcode Curl_sasl_is_blocked(struct SASL *sasl, struct Curl_easy *data)
|
|||
CURL_SASL_DIGEST, TRUE, NULL);
|
||||
sasl_unchosen(data, SASL_MECH_NTLM, enabledmechs,
|
||||
CURL_SASL_NTLM, Curl_auth_is_ntlm_supported(), NULL);
|
||||
sasl_unchosen(data, SASL_MECH_OAUTHBEARER, enabledmechs, TRUE, TRUE,
|
||||
sasl_unchosen(data, SASL_MECH_OAUTHBEARER, enabledmechs, TRUE, TRUE,
|
||||
data->set.str[STRING_BEARER] ?
|
||||
NULL : "CURLOPT_XOAUTH2_BEARER");
|
||||
sasl_unchosen(data, SASL_MECH_XOAUTH2, enabledmechs, TRUE, TRUE,
|
||||
sasl_unchosen(data, SASL_MECH_XOAUTH2, enabledmechs, TRUE, TRUE,
|
||||
data->set.str[STRING_BEARER] ?
|
||||
NULL : "CURLOPT_XOAUTH2_BEARER");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "bufref.h"
|
||||
|
||||
struct Curl_easy;
|
||||
|
|
|
|||
275
lib/curl_setup.h
275
lib/curl_setup.h
|
|
@ -75,14 +75,14 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__) && !defined(__MINGW32CE__) && \
|
||||
#if defined(__MINGW32__) && \
|
||||
(!defined(__MINGW64_VERSION_MAJOR) || (__MINGW64_VERSION_MAJOR < 3))
|
||||
#error "Building curl requires mingw-w64 3.0 or later"
|
||||
#endif
|
||||
|
||||
/* Visual Studio 2008 is the minimum Visual Studio version we support.
|
||||
/* Visual Studio 2010 is the minimum Visual Studio version we support.
|
||||
Workarounds for older versions of Visual Studio have been removed. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1500)
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
#error "Ancient versions of Visual Studio are no longer supported due to bugs."
|
||||
#endif
|
||||
|
||||
|
|
@ -90,11 +90,11 @@
|
|||
/* Disable Visual Studio warnings: 4127 "conditional expression is constant" */
|
||||
#pragma warning(disable:4127)
|
||||
/* Avoid VS2005 and upper complaining about portable C functions. */
|
||||
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE /* for strdup(), write(), etc. */
|
||||
#ifndef _CRT_NONSTDC_NO_DEPRECATE /* mingw-w64 v2+. MS SDK ~10+/~VS2017+. */
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE /* for close(), fileno(), unlink(), etc. */
|
||||
#endif
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE /* for fopen(), getenv(), etc. */
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS /* for getenv(), strcpy(), tests: sscanf() */
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
|
|
@ -122,14 +122,6 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Avoid bogus format check warnings with mingw32ce gcc 4.4.0 in
|
||||
C99 (-std=gnu99) mode */
|
||||
#if defined(__MINGW32CE__) && !defined(CURL_NO_FMT_CHECKS) && \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) && \
|
||||
(defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 4))
|
||||
#define CURL_NO_FMT_CHECKS
|
||||
#endif
|
||||
|
||||
/* Compatibility */
|
||||
#ifdef ENABLE_IPV6
|
||||
#define USE_IPV6 1
|
||||
|
|
@ -170,7 +162,7 @@
|
|||
|
||||
/* ================================================================ */
|
||||
/* Definition of preprocessor macros/symbols which modify compiler */
|
||||
/* behavior or generated code characteristics must be done here, */
|
||||
/* 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 */
|
||||
|
|
@ -187,7 +179,6 @@
|
|||
* 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
|
||||
|
|
@ -199,7 +190,6 @@
|
|||
* 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
|
||||
|
|
@ -226,7 +216,6 @@
|
|||
/*
|
||||
* Disable other protocols when http is the only one desired.
|
||||
*/
|
||||
|
||||
#ifdef HTTP_ONLY
|
||||
# ifndef CURL_DISABLE_DICT
|
||||
# define CURL_DISABLE_DICT
|
||||
|
|
@ -275,7 +264,6 @@
|
|||
/*
|
||||
* When http is disabled rtsp is not supported.
|
||||
*/
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP)
|
||||
# define CURL_DISABLE_RTSP
|
||||
#endif
|
||||
|
|
@ -283,7 +271,6 @@
|
|||
/*
|
||||
* When HTTP is disabled, disable HTTP-only features
|
||||
*/
|
||||
|
||||
#ifdef CURL_DISABLE_HTTP
|
||||
# define CURL_DISABLE_ALTSVC 1
|
||||
# define CURL_DISABLE_COOKIES 1
|
||||
|
|
@ -305,7 +292,6 @@
|
|||
/*
|
||||
* OS/400 setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef __OS400__
|
||||
# include "setup-os400.h"
|
||||
#endif
|
||||
|
|
@ -313,7 +299,6 @@
|
|||
/*
|
||||
* VMS setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef __VMS
|
||||
# include "setup-vms.h"
|
||||
#endif
|
||||
|
|
@ -321,7 +306,6 @@
|
|||
/*
|
||||
* Windows setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
# include "setup-win32.h"
|
||||
#endif
|
||||
|
|
@ -332,8 +316,8 @@
|
|||
* 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)
|
||||
#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 it matches the GNU format attribute we
|
||||
|
|
@ -347,7 +331,6 @@
|
|||
#endif
|
||||
|
||||
/* based on logic in "curl/mprintf.h" */
|
||||
|
||||
#if (defined(__GNUC__) || defined(__clang__) || \
|
||||
defined(__IAR_SYSTEMS_ICC__)) && \
|
||||
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
||||
|
|
@ -438,9 +421,9 @@
|
|||
# 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)
|
||||
# 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)
|
||||
# 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
|
||||
|
|
@ -466,7 +449,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
#ifdef __TANDEM /* for ns*-tandem-nsk systems */
|
||||
# if ! defined __LP64
|
||||
# ifndef __LP64
|
||||
# include <floss.h> /* FLOSS is only used for 32-bit builds. */
|
||||
# endif
|
||||
#endif
|
||||
|
|
@ -487,31 +470,19 @@
|
|||
# endif
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# ifdef USE_WIN32_LARGE_FILES
|
||||
/* Large file (>2Gb) support using Win32 functions. */
|
||||
# undef lseek
|
||||
# define lseek(fdes, offset, whence) _lseeki64(fdes, offset, whence)
|
||||
# undef fstat
|
||||
# define fstat(fdes,stp) _fstati64(fdes, stp)
|
||||
# undef stat
|
||||
# define struct_stat struct _stati64
|
||||
# define LSEEK_ERROR (__int64)-1
|
||||
# else
|
||||
/* Small file (<2Gb) support using Win32 functions. */
|
||||
# ifndef UNDER_CE
|
||||
# undef lseek
|
||||
# define lseek(fdes, offset, whence) _lseek(fdes, (long)offset, whence)
|
||||
# define fstat(fdes, stp) _fstat(fdes, stp)
|
||||
# define struct_stat struct _stat
|
||||
# endif
|
||||
# define LSEEK_ERROR (long)-1
|
||||
# endif
|
||||
/* Large file (>2Gb) support using Win32 functions. */
|
||||
# undef lseek
|
||||
# define lseek(fdes, offset, whence) _lseeki64(fdes, offset, whence)
|
||||
# undef fstat
|
||||
# define fstat(fdes, stp) _fstati64(fdes, stp)
|
||||
# define struct_stat struct _stati64
|
||||
# define LSEEK_ERROR (__int64)-1
|
||||
#elif defined(__DJGPP__)
|
||||
/* Requires DJGPP 2.04 */
|
||||
# include <unistd.h>
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) llseek(fdes, offset, whence)
|
||||
# define LSEEK_ERROR (offset_t)-1
|
||||
# define lseek(fdes, offset, whence) llseek(fdes, offset, whence)
|
||||
# define LSEEK_ERROR (offset_t)-1
|
||||
#endif
|
||||
|
||||
#ifndef struct_stat
|
||||
|
|
@ -538,9 +509,13 @@
|
|||
#endif
|
||||
|
||||
#if SIZEOF_CURL_SOCKET_T < 8
|
||||
#ifdef _WIN32
|
||||
# define FMT_SOCKET_T "u"
|
||||
#else
|
||||
# define FMT_SOCKET_T "d"
|
||||
#elif defined(__MINGW32__)
|
||||
# define FMT_SOCKET_T "zd"
|
||||
#endif
|
||||
#elif defined(_WIN32)
|
||||
# define FMT_SOCKET_T "zu"
|
||||
#else
|
||||
# define FMT_SOCKET_T "qd"
|
||||
#endif
|
||||
|
|
@ -580,21 +555,7 @@
|
|||
#endif
|
||||
#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - 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 FMT_PRId64 CURL_FORMAT_CURL_OFF_T
|
||||
# define FMT_PRIu64 CURL_FORMAT_CURL_OFF_TU
|
||||
#endif
|
||||
|
||||
#define FMT_OFF_T CURL_FORMAT_CURL_OFF_T
|
||||
#define FMT_OFF_T CURL_FORMAT_CURL_OFF_T
|
||||
#define FMT_OFF_TU CURL_FORMAT_CURL_OFF_TU
|
||||
|
||||
#if (SIZEOF_TIME_T == 4)
|
||||
|
|
@ -633,10 +594,13 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if SIZEOF_LONG > SIZEOF_SIZE_T
|
||||
#error "unexpected: 'long' is larger than 'size_t'"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Arg 2 type for gethostname in case it has not been defined in config file.
|
||||
*/
|
||||
|
||||
#ifndef GETHOSTNAME_TYPE_ARG2
|
||||
# ifdef USE_WINSOCK
|
||||
# define GETHOSTNAME_TYPE_ARG2 int
|
||||
|
|
@ -646,10 +610,9 @@
|
|||
#endif
|
||||
|
||||
/* Below we define some functions. They should
|
||||
|
||||
4. set the SIGALRM signal timeout
|
||||
5. set dir/file naming defines
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
|
|
@ -660,8 +623,8 @@
|
|||
# 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))
|
||||
# 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>
|
||||
# undef word
|
||||
# undef byte
|
||||
|
|
@ -685,7 +648,6 @@
|
|||
/*
|
||||
* Mutually exclusive CURLRES_* definitions.
|
||||
*/
|
||||
|
||||
#if defined(USE_IPV6) && defined(HAVE_GETADDRINFO)
|
||||
# define CURLRES_IPV6
|
||||
#elif defined(USE_IPV6) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||
|
|
@ -813,44 +775,20 @@
|
|||
/*
|
||||
* Include macros and defines that should only be processed once.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CURL_SETUP_ONCE_H
|
||||
#include "curl_setup_once.h"
|
||||
#endif
|
||||
|
||||
#ifdef UNDER_CE
|
||||
#define getenv curl_getenv /* Windows CE does not support getenv() */
|
||||
#define raise(s) ((void)(s))
|
||||
/* Terrible workarounds to make Windows CE compile */
|
||||
#define errno 0
|
||||
#define CURL_SETERRNO(x) ((void)(x))
|
||||
#define EINTR 4
|
||||
#define EAGAIN 11
|
||||
#define ENOMEM 12
|
||||
#define EACCES 13
|
||||
#define EEXIST 17
|
||||
#define EISDIR 21
|
||||
#define EINVAL 22
|
||||
#define ENOSPC 28
|
||||
#define strerror(x) "?"
|
||||
#undef STDIN_FILENO
|
||||
#define STDIN_FILENO 0
|
||||
#else
|
||||
#define CURL_SETERRNO(x) (errno = (x))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definition of our NOP statement Object-like macro
|
||||
*/
|
||||
|
||||
#ifndef Curl_nop_stmt
|
||||
#define Curl_nop_stmt do { } while(0)
|
||||
#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!"
|
||||
|
|
@ -860,7 +798,6 @@
|
|||
/*
|
||||
* shutdown() flags for systems that do not define them
|
||||
*/
|
||||
|
||||
#ifndef SHUT_RD
|
||||
#define SHUT_RD 0x00
|
||||
#endif
|
||||
|
|
@ -906,8 +843,8 @@
|
|||
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_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.
|
||||
|
|
@ -916,18 +853,18 @@ 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_READTEXT "rt"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#define FOPEN_APPENDTEXT "a"
|
||||
#else
|
||||
#define FOPEN_READTEXT "r"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#define FOPEN_READTEXT "r"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#define FOPEN_APPENDTEXT "a"
|
||||
#endif
|
||||
|
||||
/* for systems that do not detect this in configure */
|
||||
#ifndef CURL_SA_FAMILY_T
|
||||
# if defined(_WIN32) && !defined(UNDER_CE)
|
||||
# ifdef _WIN32
|
||||
# define CURL_SA_FAMILY_T ADDRESS_FAMILY
|
||||
# elif defined(HAVE_SA_FAMILY_T)
|
||||
# define CURL_SA_FAMILY_T sa_family_t
|
||||
|
|
@ -941,15 +878,15 @@ endings either CRLF or LF so 't' is appropriate.
|
|||
|
||||
/* 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))
|
||||
#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
|
||||
#define STRCONST(x) x, sizeof(x) - 1
|
||||
|
||||
#define CURL_ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#define CURL_ARRAYSIZE(A) (sizeof(A) / sizeof((A)[0]))
|
||||
|
||||
/* Buffer size for error messages retrieved via
|
||||
curlx_strerror() and Curl_sspi_strerror() */
|
||||
|
|
@ -982,9 +919,12 @@ extern curl_calloc_callback Curl_ccalloc;
|
|||
* This macro also assigns NULL to given pointer when free'd.
|
||||
*/
|
||||
#define Curl_safefree(ptr) \
|
||||
do { free((ptr)); (ptr) = NULL;} while(0)
|
||||
do { \
|
||||
curlx_free(ptr); \
|
||||
(ptr) = NULL; \
|
||||
} while(0)
|
||||
|
||||
#include <curl/curl.h> /* for CURL_EXTERN, mprintf.h */
|
||||
#include <curl/curl.h> /* for CURL_EXTERN, curl_socket_t, mprintf.h */
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
#ifdef __clang__
|
||||
|
|
@ -1065,35 +1005,36 @@ CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd,
|
|||
|
||||
/* FILE functions */
|
||||
CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source);
|
||||
CURL_EXTERN ALLOC_FUNC
|
||||
FILE *curl_dbg_fopen(const char *file, const char *mode,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN ALLOC_FUNC
|
||||
FILE *curl_dbg_fdopen(int filedes, const char *mode,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_fopen(const char *file, const char *mode,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_freopen(const char *file,
|
||||
const char *mode, FILE *fh,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_fdopen(int filedes, const char *mode,
|
||||
int line, const char *source);
|
||||
|
||||
#define sclose(sockfd) curl_dbg_sclose(sockfd,__LINE__,__FILE__)
|
||||
#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd,__LINE__,__FILE__)
|
||||
#define sclose(sockfd) curl_dbg_sclose(sockfd, __LINE__, __FILE__)
|
||||
#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd, __LINE__, __FILE__)
|
||||
|
||||
#define CURL_GETADDRINFO(host,serv,hint,res) \
|
||||
#define CURL_GETADDRINFO(host, serv, hint, res) \
|
||||
curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
|
||||
#define CURL_FREEADDRINFO(data) \
|
||||
curl_dbg_freeaddrinfo(data, __LINE__, __FILE__)
|
||||
#define CURL_SOCKET(domain,type,protocol) \
|
||||
#define CURL_SOCKET(domain, type, protocol) \
|
||||
curl_dbg_socket((int)domain, type, protocol, __LINE__, __FILE__)
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
#define CURL_SOCKETPAIR(domain,type,protocol,socket_vector) \
|
||||
#define CURL_SOCKETPAIR(domain, type, protocol, socket_vector) \
|
||||
curl_dbg_socketpair((int)domain, type, protocol, socket_vector, \
|
||||
__LINE__, __FILE__)
|
||||
#endif
|
||||
#define CURL_ACCEPT(sock,addr,len) \
|
||||
#define CURL_ACCEPT(sock, addr, len) \
|
||||
curl_dbg_accept(sock, addr, len, __LINE__, __FILE__)
|
||||
#ifdef HAVE_ACCEPT4
|
||||
#define CURL_ACCEPT4(sock,addr,len,flags) \
|
||||
#define CURL_ACCEPT4(sock, addr, len, flags) \
|
||||
curl_dbg_accept4(sock, addr, len, flags, __LINE__, __FILE__)
|
||||
#endif
|
||||
#define CURL_SEND(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__)
|
||||
#define CURL_RECV(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__)
|
||||
#define CURL_SEND(a, b, c, d) curl_dbg_send(a, b, c, d, __LINE__, __FILE__)
|
||||
#define CURL_RECV(a, b, c, d) curl_dbg_recv(a, b, c, d, __LINE__, __FILE__)
|
||||
|
||||
#else /* !CURLDEBUG */
|
||||
|
||||
|
|
@ -1115,6 +1056,56 @@ CURL_EXTERN ALLOC_FUNC
|
|||
|
||||
#endif /* CURLDEBUG */
|
||||
|
||||
/* Allocator macros */
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
|
||||
#define curlx_strdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__)
|
||||
#define curlx_malloc(size) curl_dbg_malloc(size, __LINE__, __FILE__)
|
||||
#define curlx_calloc(nbelem, size) \
|
||||
curl_dbg_calloc(nbelem, size, __LINE__, __FILE__)
|
||||
#define curlx_realloc(ptr, size) \
|
||||
curl_dbg_realloc(ptr, size, __LINE__, __FILE__)
|
||||
#define curlx_free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__)
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef UNICODE
|
||||
#define curlx_tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__)
|
||||
#else
|
||||
#define curlx_tcsdup(ptr) curlx_strdup(ptr)
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#else /* !CURLDEBUG */
|
||||
|
||||
#ifdef BUILDING_LIBCURL
|
||||
#define curlx_strdup(ptr) Curl_cstrdup(ptr)
|
||||
#define curlx_malloc(size) Curl_cmalloc(size)
|
||||
#define curlx_calloc(nbelem, size) Curl_ccalloc(nbelem, size)
|
||||
#define curlx_realloc(ptr, size) Curl_crealloc(ptr, size)
|
||||
#define curlx_free(ptr) Curl_cfree(ptr)
|
||||
#else /* !BUILDING_LIBCURL */
|
||||
#ifdef _WIN32
|
||||
#define curlx_strdup(ptr) _strdup(ptr)
|
||||
#else
|
||||
#define curlx_strdup(ptr) strdup(ptr)
|
||||
#endif
|
||||
#define curlx_malloc(size) malloc(size)
|
||||
#define curlx_calloc(nbelem, size) calloc(nbelem, size)
|
||||
#define curlx_realloc(ptr, size) realloc(ptr, size)
|
||||
#define curlx_free(ptr) free(ptr)
|
||||
#endif /* BUILDING_LIBCURL */
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef UNICODE
|
||||
#define curlx_tcsdup(ptr) Curl_wcsdup(ptr)
|
||||
#else
|
||||
#define curlx_tcsdup(ptr) curlx_strdup(ptr)
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* CURLDEBUG */
|
||||
|
||||
/* Some versions of the Android NDK is missing the declaration */
|
||||
#if defined(HAVE_GETPWUID_R) && \
|
||||
defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
|
||||
|
|
@ -1134,8 +1125,8 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
|||
#endif
|
||||
|
||||
#if (defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || \
|
||||
(defined(USE_OPENSSL_QUIC) && defined(USE_NGHTTP3)) || \
|
||||
defined(USE_QUICHE)
|
||||
(defined(USE_OPENSSL_QUIC) && defined(USE_NGHTTP3)) || \
|
||||
defined(USE_QUICHE)
|
||||
|
||||
#ifdef CURL_WITH_MULTI_SSL
|
||||
#error "MultiSSL combined with QUIC is not supported"
|
||||
|
|
@ -1157,17 +1148,17 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
|||
#endif
|
||||
|
||||
#if defined(USE_UNIX_SOCKETS) && defined(_WIN32)
|
||||
# ifndef 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 {
|
||||
CURL_SA_FAMILY_T sun_family;
|
||||
char sun_path[UNIX_PATH_MAX];
|
||||
} SOCKADDR_UN, *PSOCKADDR_UN;
|
||||
# define WIN32_SOCKADDR_UN
|
||||
# endif
|
||||
/* Offered by mingw-w64 v10+. MS SDK 10.17763/~VS2017+. */
|
||||
#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR >= 10)
|
||||
# include <afunix.h>
|
||||
#elif !defined(UNIX_PATH_MAX) /* Replicate logic present in afunix.h */
|
||||
# define UNIX_PATH_MAX 108
|
||||
/* !checksrc! disable TYPEDEFSTRUCT 1 */
|
||||
typedef struct sockaddr_un {
|
||||
CURL_SA_FAMILY_T sun_family;
|
||||
char sun_path[UNIX_PATH_MAX];
|
||||
} SOCKADDR_UN, *PSOCKADDR_UN;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
|
|
@ -1205,5 +1196,3 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
|||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
||||
|
||||
#include "curl_mem_undef.h"
|
||||
|
|
|
|||
|
|
@ -28,14 +28,11 @@
|
|||
* Inclusion of common header files.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#ifndef UNDER_CE
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
|
|
@ -67,8 +64,6 @@
|
|||
Use it for APIs that do not or cannot support the const qualifier. */
|
||||
#ifdef HAVE_STDINT_H
|
||||
# define CURL_UNCONST(p) ((void *)(uintptr_t)(const void *)(p))
|
||||
#elif defined(_WIN32) /* for VS2008 */
|
||||
# define CURL_UNCONST(p) ((void *)(ULONG_PTR)(const void *)(p))
|
||||
#else
|
||||
# define CURL_UNCONST(p) ((void *)(p)) /* Fall back to simple cast */
|
||||
#endif
|
||||
|
|
@ -108,7 +103,6 @@
|
|||
/*
|
||||
* Definition of timeval struct for platforms that do not have it.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_STRUCT_TIMEVAL
|
||||
struct timeval {
|
||||
long tv_sec;
|
||||
|
|
@ -116,24 +110,21 @@ struct timeval {
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
||||
#ifdef __minix
|
||||
/* Minix does not 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))
|
||||
#define sread(x, y, z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
|
||||
(RECV_TYPE_ARG2)(y), \
|
||||
(RECV_TYPE_ARG3)(z))
|
||||
|
||||
#elif defined(HAVE_RECV)
|
||||
/*
|
||||
|
|
@ -158,48 +149,45 @@ struct timeval {
|
|||
* 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))
|
||||
#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 */
|
||||
|
||||
|
||||
#ifdef __minix
|
||||
/* Minix does not support send on TCP sockets */
|
||||
#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
|
||||
(SEND_TYPE_ARG2)CURL_UNCONST(y), \
|
||||
(SEND_TYPE_ARG3)(z))
|
||||
#define swrite(x, y, z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
|
||||
(SEND_TYPE_ARG2)CURL_UNCONST(y), \
|
||||
(SEND_TYPE_ARG3)(z))
|
||||
#elif defined(HAVE_SEND)
|
||||
#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
|
||||
#define swrite(x, y, z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
|
||||
(SEND_QUAL_ARG2 SEND_TYPE_ARG2)CURL_UNCONST(y), \
|
||||
(SEND_TYPE_ARG3)(z), \
|
||||
(SEND_TYPE_ARG4)(SEND_4TH_ARG))
|
||||
(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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CLOSESOCKET
|
||||
# define CURL_SCLOSE(x) closesocket((x))
|
||||
# define CURL_SCLOSE(x) closesocket(x)
|
||||
#elif defined(HAVE_CLOSESOCKET_CAMEL)
|
||||
# define CURL_SCLOSE(x) CloseSocket((x))
|
||||
# define CURL_SCLOSE(x) CloseSocket(x)
|
||||
#elif defined(MSDOS) /* Watt-32 */
|
||||
# define CURL_SCLOSE(x) close_s((x))
|
||||
# define CURL_SCLOSE(x) close_s(x)
|
||||
#elif defined(USE_LWIPSOCK)
|
||||
# define CURL_SCLOSE(x) lwip_close((x))
|
||||
# define CURL_SCLOSE(x) lwip_close(x)
|
||||
#else
|
||||
# define CURL_SCLOSE(x) close((x))
|
||||
# define CURL_SCLOSE(x) close(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -214,7 +202,6 @@ struct timeval {
|
|||
/*
|
||||
* 'bool' stuff compatible with HP-UX headers.
|
||||
*/
|
||||
|
||||
#if defined(__hpux) && !defined(HAVE_BOOL_T)
|
||||
typedef int bool;
|
||||
# define false 0
|
||||
|
|
@ -222,14 +209,12 @@ struct timeval {
|
|||
# define HAVE_BOOL_T
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* 'bool' exists on platforms with <stdbool.h>, i.e. C99 platforms.
|
||||
* On non-C99 platforms there is 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,
|
||||
|
|
@ -262,7 +247,6 @@ typedef unsigned int bit;
|
|||
* '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
|
||||
|
|
@ -272,35 +256,29 @@ typedef unsigned int bit;
|
|||
|
||||
#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)
|
||||
#define DEBUGF(x) do {} while(0)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Macro used to include assertion code only in debug builds.
|
||||
*/
|
||||
|
||||
#undef DEBUGASSERT
|
||||
#ifdef DEBUGBUILD
|
||||
#define DEBUGASSERT(x) assert(x)
|
||||
#else
|
||||
#define DEBUGASSERT(x) do { } while(0)
|
||||
#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)))
|
||||
|
|
@ -309,11 +287,9 @@ typedef unsigned int bit;
|
|||
#define SET_SOCKERRNO(x) (errno = (x))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Portable error number symbolic names defined to Winsock error codes.
|
||||
*/
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
#define SOCKEACCES WSAEACCES
|
||||
#define SOCKEADDRINUSE WSAEADDRINUSE
|
||||
|
|
@ -353,22 +329,18 @@ typedef unsigned int bit;
|
|||
/*
|
||||
* Macro argv_item_t hides platform details to code using it.
|
||||
*/
|
||||
|
||||
#ifdef __VMS
|
||||
#define argv_item_t __char_ptr32
|
||||
#elif defined(_UNICODE) && !defined(UNDER_CE)
|
||||
#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 */
|
||||
|
|
|
|||
|
|
@ -25,10 +25,11 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \
|
||||
defined(USE_LIBSSH2) || defined(USE_SSL)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_hmac.h"
|
||||
|
||||
extern const struct HMAC_params Curl_HMAC_SHA256;
|
||||
|
|
|
|||
|
|
@ -30,20 +30,18 @@
|
|||
#include "curlx/warnless.h"
|
||||
|
||||
/* The recommended order of the TLS backends:
|
||||
* * OpenSSL
|
||||
* * GnuTLS
|
||||
* * wolfSSL
|
||||
* * Schannel SSPI
|
||||
* * mbedTLS
|
||||
* * Rustls
|
||||
* 1. OpenSSL
|
||||
* 2. GnuTLS
|
||||
* 3. wolfSSL
|
||||
* 4. Schannel SSPI
|
||||
* 5. mbedTLS
|
||||
* 6. Rustls
|
||||
* Skip the backend if it does not support the required algorithm */
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
# include <openssl/opensslv.h>
|
||||
# if (!defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
OPENSSL_VERSION_NUMBER >= 0x10101000L) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
LIBRESSL_VERSION_NUMBER >= 0x3080000fL)
|
||||
# if !defined(LIBRESSL_VERSION_NUMBER) || \
|
||||
(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>
|
||||
|
|
@ -67,14 +65,12 @@
|
|||
(__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>
|
||||
# ifdef SHA512_256_DIGEST_SIZE
|
||||
|
|
@ -111,7 +107,7 @@ typedef EVP_MD_CTX *Curl_sha512_256_ctx;
|
|||
*/
|
||||
static CURLcode Curl_sha512_256_init(void *context)
|
||||
{
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
*ctx = EVP_MD_CTX_create();
|
||||
if(!*ctx)
|
||||
|
|
@ -131,7 +127,6 @@ static CURLcode Curl_sha512_256_init(void *context)
|
|||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process portion of bytes.
|
||||
*
|
||||
|
|
@ -144,7 +139,7 @@ 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;
|
||||
Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
if(!EVP_DigestUpdate(*ctx, data, length))
|
||||
return CURLE_SSL_CIPHER;
|
||||
|
|
@ -152,7 +147,6 @@ static CURLcode Curl_sha512_256_update(void *context,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finalise SHA-512/256 calculation, return digest.
|
||||
*
|
||||
|
|
@ -165,7 +159,7 @@ static CURLcode Curl_sha512_256_update(void *context,
|
|||
static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
|
||||
{
|
||||
CURLcode ret;
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
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:
|
||||
|
|
@ -204,7 +198,7 @@ typedef struct sha512_256_ctx Curl_sha512_256_ctx;
|
|||
*/
|
||||
static CURLcode Curl_sha512_256_init(void *context)
|
||||
{
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
/* Check whether the header and this file use the same numbers */
|
||||
DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE);
|
||||
|
|
@ -214,7 +208,6 @@ static CURLcode Curl_sha512_256_init(void *context)
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process portion of bytes.
|
||||
*
|
||||
|
|
@ -227,7 +220,7 @@ 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;
|
||||
Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
DEBUGASSERT((data != NULL) || (length == 0));
|
||||
|
||||
|
|
@ -236,7 +229,6 @@ static CURLcode Curl_sha512_256_update(void *context,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finalise SHA-512/256 calculation, return digest.
|
||||
*
|
||||
|
|
@ -245,10 +237,9 @@ static CURLcode Curl_sha512_256_update(void *context,
|
|||
# bytes
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode Curl_sha512_256_finish(unsigned char *digest,
|
||||
void *context)
|
||||
static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
|
||||
{
|
||||
Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
||||
Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
|
||||
|
||||
sha512_256_digest(ctx,
|
||||
(size_t)CURL_SHA512_256_DIGEST_SIZE, (uint8_t *)digest);
|
||||
|
|
@ -288,32 +279,31 @@ static CURLcode Curl_sha512_256_finish(unsigned char *digest,
|
|||
/* Bits manipulation macros and functions.
|
||||
Can be moved to other headers to reuse. */
|
||||
|
||||
#define CURL_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 CURL_GET_64BIT_BE(ptr) \
|
||||
(((uint64_t)(((const uint8_t *)(ptr))[0]) << 56) | \
|
||||
((uint64_t)(((const uint8_t *)(ptr))[1]) << 48) | \
|
||||
((uint64_t)(((const uint8_t *)(ptr))[2]) << 40) | \
|
||||
((uint64_t)(((const uint8_t *)(ptr))[3]) << 32) | \
|
||||
((uint64_t)(((const uint8_t *)(ptr))[4]) << 24) | \
|
||||
((uint64_t)(((const uint8_t *)(ptr))[5]) << 16) | \
|
||||
((uint64_t)(((const uint8_t *)(ptr))[6]) << 8) | \
|
||||
(uint64_t)(((const uint8_t *)(ptr))[7]))
|
||||
|
||||
#define CURL_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); \
|
||||
#define CURL_PUT_64BIT_BE(ptr,val) do { \
|
||||
((uint8_t*)(ptr))[7] = (uint8_t) ((uint64_t)(val)); \
|
||||
((uint8_t*)(ptr))[6] = (uint8_t)(((uint64_t)(val)) >> 8); \
|
||||
((uint8_t*)(ptr))[5] = (uint8_t)(((uint64_t)(val)) >> 16); \
|
||||
((uint8_t*)(ptr))[4] = (uint8_t)(((uint64_t)(val)) >> 24); \
|
||||
((uint8_t*)(ptr))[3] = (uint8_t)(((uint64_t)(val)) >> 32); \
|
||||
((uint8_t*)(ptr))[2] = (uint8_t)(((uint64_t)(val)) >> 40); \
|
||||
((uint8_t*)(ptr))[1] = (uint8_t)(((uint64_t)(val)) >> 48); \
|
||||
((uint8_t*)(ptr))[0] = (uint8_t)(((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 CURL_FORCEINLINE curl_uint64_t Curl_rotr64(curl_uint64_t value,
|
||||
unsigned int bits)
|
||||
static CURL_FORCEINLINE uint64_t Curl_rotr64(uint64_t value, unsigned int bits)
|
||||
{
|
||||
bits %= 64;
|
||||
if(bits == 0)
|
||||
|
|
@ -344,7 +334,7 @@ static CURL_FORCEINLINE curl_uint64_t Curl_rotr64(curl_uint64_t value,
|
|||
* 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)
|
||||
#define SHA512_256_DIGEST_SIZE_WORDS (SHA512_256_HASH_SIZE_WORDS / 2)
|
||||
|
||||
/**
|
||||
* Size of the SHA-512/256 resulting digest in bytes
|
||||
|
|
@ -378,22 +368,22 @@ struct Curl_sha512_256ctx {
|
|||
* 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];
|
||||
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];
|
||||
uint64_t buffer[SHA512_256_BLOCK_SIZE_WORDS];
|
||||
/**
|
||||
* The number of bytes, lower part
|
||||
*/
|
||||
curl_uint64_t count;
|
||||
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;
|
||||
uint64_t count_bits_hi;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -401,7 +391,6 @@ struct Curl_sha512_256ctx {
|
|||
*/
|
||||
typedef struct Curl_sha512_256ctx Curl_sha512_256_ctx;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise structure for SHA-512/256 calculation.
|
||||
*
|
||||
|
|
@ -410,119 +399,117 @@ typedef struct Curl_sha512_256ctx Curl_sha512_256_ctx;
|
|||
*/
|
||||
static CURLcode Curl_sha512_256_init(void *context)
|
||||
{
|
||||
struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context;
|
||||
struct Curl_sha512_256ctx * const ctx = (struct Curl_sha512_256ctx *)context;
|
||||
|
||||
/* Check whether the header and this file use the same numbers */
|
||||
DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE);
|
||||
|
||||
DEBUGASSERT(sizeof(curl_uint64_t) == 8);
|
||||
DEBUGASSERT(sizeof(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);
|
||||
ctx->H[0] = UINT64_C(0x22312194FC2BF72C);
|
||||
ctx->H[1] = UINT64_C(0x9F555FA3C84C64C2);
|
||||
ctx->H[2] = UINT64_C(0x2393B86B6F53B151);
|
||||
ctx->H[3] = UINT64_C(0x963877195940EABD);
|
||||
ctx->H[4] = UINT64_C(0x96283EE2A88EFFE3);
|
||||
ctx->H[5] = UINT64_C(0xBE5E1E2553863992);
|
||||
ctx->H[6] = UINT64_C(0x2B0199FC2C85B8AA);
|
||||
ctx->H[7] = 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);
|
||||
ctx->count = UINT64_C(0);
|
||||
ctx->count_bits_hi = 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 #CURL_SHA512_256_BLOCK_SIZE bytes block
|
||||
*/
|
||||
static
|
||||
void Curl_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
||||
const void *data)
|
||||
static void Curl_sha512_256_transform(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];
|
||||
uint64_t a = H[0];
|
||||
uint64_t b = H[1];
|
||||
uint64_t c = H[2];
|
||||
uint64_t d = H[3];
|
||||
uint64_t e = H[4];
|
||||
uint64_t f = H[5];
|
||||
uint64_t g = H[6];
|
||||
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];
|
||||
uint64_t W[16];
|
||||
|
||||
/* 'Ch' and 'Maj' macro functions are defined with widely-used optimization.
|
||||
See FIPS PUB 180-4 formulae 4.8, 4.9. */
|
||||
#define Sha512_Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) )
|
||||
#define Sha512_Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
|
||||
#define Sha512_Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define Sha512_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) \
|
||||
( Curl_rotr64((x), 28) ^ Curl_rotr64((x), 34) ^ Curl_rotr64((x), 39) )
|
||||
(Curl_rotr64((x), 28) ^ Curl_rotr64((x), 34) ^ Curl_rotr64((x), 39))
|
||||
#define SIG1(x) \
|
||||
( Curl_rotr64((x), 14) ^ Curl_rotr64((x), 18) ^ Curl_rotr64((x), 41) )
|
||||
(Curl_rotr64((x), 14) ^ Curl_rotr64((x), 18) ^ Curl_rotr64((x), 41))
|
||||
#define sig0(x) \
|
||||
( Curl_rotr64((x), 1) ^ Curl_rotr64((x), 8) ^ ((x) >> 7) )
|
||||
(Curl_rotr64((x), 1) ^ Curl_rotr64((x), 8) ^ ((x) >> 7))
|
||||
#define sig1(x) \
|
||||
( Curl_rotr64((x), 19) ^ Curl_rotr64((x), 61) ^ ((x) >> 6) )
|
||||
(Curl_rotr64((x), 19) ^ Curl_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)
|
||||
static const uint64_t K[80] = {
|
||||
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
|
||||
UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
|
||||
UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
|
||||
UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
|
||||
UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
|
||||
UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
|
||||
UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
|
||||
UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
|
||||
UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
|
||||
UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
|
||||
UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
|
||||
UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
|
||||
UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
|
||||
UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
|
||||
UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
|
||||
UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
|
||||
UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
|
||||
UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
|
||||
UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
|
||||
UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
|
||||
UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
|
||||
UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
|
||||
UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
|
||||
UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
|
||||
UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
|
||||
UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
|
||||
UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
|
||||
UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
|
||||
UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
|
||||
UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
|
||||
UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
|
||||
UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
|
||||
UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
|
||||
UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
|
||||
UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
|
||||
UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
|
||||
UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
|
||||
UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
|
||||
UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
|
||||
UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
/* One step of SHA-512/256 computation,
|
||||
|
|
@ -535,38 +522,41 @@ void Curl_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
|||
* 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)) + Sha512_Ch((vE),(vF),(vG)) + (kt) + (wt)); \
|
||||
(vH) += SIG0((vA)) + Sha512_Maj((vA),(vB),(vC)); } while (0)
|
||||
#define SHA2STEP64(vA, vB, vC, vD, vE, vF, vG, vH, kt, wt) \
|
||||
do { \
|
||||
(vD) += ((vH) += SIG1((vE)) + Sha512_Ch((vE), (vF), (vG)) + (kt) + (wt)); \
|
||||
(vH) += SIG0((vA)) + Sha512_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)
|
||||
#define SHA2STEP64RV(vA, vB, vC, vD, vE, vF, vG, vH, kt, wt) \
|
||||
do { \
|
||||
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) \
|
||||
CURL_GET_64BIT_BE( \
|
||||
((const unsigned char*) (buf)) + (t) * SHA512_256_BYTES_IN_WORD)
|
||||
#define SHA512_GET_W_FROM_DATA(buf, t) \
|
||||
CURL_GET_64BIT_BE(((const uint8_t *)(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], \
|
||||
SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t],
|
||||
W[t] = SHA512_GET_W_FROM_DATA(data, t));
|
||||
}
|
||||
|
||||
|
|
@ -575,15 +565,15 @@ void Curl_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
|||
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]) )
|
||||
#define Wgen(w, t) \
|
||||
(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], \
|
||||
SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t],
|
||||
W[t & 15] = Wgen(W, t));
|
||||
}
|
||||
}
|
||||
|
|
@ -600,7 +590,6 @@ void Curl_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
|||
H[7] += h;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process portion of bytes.
|
||||
*
|
||||
|
|
@ -614,9 +603,9 @@ static CURLcode Curl_sha512_256_update(void *context,
|
|||
size_t length)
|
||||
{
|
||||
unsigned int bytes_have; /**< Number of bytes in the context buffer */
|
||||
struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context;
|
||||
struct Curl_sha512_256ctx * const ctx = (struct Curl_sha512_256ctx *)context;
|
||||
/* the void pointer here is required to mute Intel compiler warning */
|
||||
void *const ctx_buf = ctx->buffer;
|
||||
void * const ctx_buf = ctx->buffer;
|
||||
|
||||
DEBUGASSERT((data != NULL) || (length == 0));
|
||||
|
||||
|
|
@ -625,21 +614,19 @@ static CURLcode Curl_sha512_256_update(void *context,
|
|||
|
||||
/* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1))
|
||||
equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */
|
||||
bytes_have = (unsigned int) (ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1));
|
||||
bytes_have = (unsigned int)(ctx->count & (CURL_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);
|
||||
ctx->count &= UINT64_C(0x1FFFFFFFFFFFFFFF);
|
||||
|
||||
if(bytes_have) {
|
||||
unsigned int bytes_left = CURL_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);
|
||||
memcpy(((unsigned char *)ctx_buf) + bytes_have, data, bytes_left);
|
||||
data += bytes_left;
|
||||
length -= bytes_left;
|
||||
Curl_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
|
|
@ -658,13 +645,12 @@ static CURLcode Curl_sha512_256_update(void *context,
|
|||
if(length) {
|
||||
/* Copy incomplete block of new data (if any)
|
||||
to the buffer. */
|
||||
memcpy(((unsigned char *) ctx_buf) + bytes_have, data, length);
|
||||
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.
|
||||
|
|
@ -686,11 +672,11 @@ static CURLcode Curl_sha512_256_update(void *context,
|
|||
*/
|
||||
static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
|
||||
{
|
||||
struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context;
|
||||
curl_uint64_t num_bits; /**< Number of processed bits */
|
||||
struct Curl_sha512_256ctx * const ctx = (struct Curl_sha512_256ctx *)context;
|
||||
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;
|
||||
void * const ctx_buf = ctx->buffer;
|
||||
|
||||
/* Memorise the number of processed bits.
|
||||
The padding and other data added here during the postprocessing must
|
||||
|
|
@ -699,7 +685,7 @@ static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
|
|||
|
||||
/* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1))
|
||||
equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */
|
||||
bytes_have = (unsigned int) (ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1));
|
||||
bytes_have = (unsigned int)(ctx->count & (CURL_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
|
||||
|
|
@ -711,13 +697,13 @@ static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
|
|||
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;
|
||||
((unsigned char *)ctx_buf)[bytes_have++] = 0x80U;
|
||||
|
||||
if(CURL_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 < CURL_SHA512_256_BLOCK_SIZE)
|
||||
memset(((unsigned char *) ctx_buf) + bytes_have, 0,
|
||||
memset(((unsigned char *)ctx_buf) + bytes_have, 0,
|
||||
CURL_SHA512_256_BLOCK_SIZE - bytes_have);
|
||||
/* Process the full block. */
|
||||
Curl_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
|
|
@ -726,17 +712,17 @@ static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
|
|||
}
|
||||
|
||||
/* Pad the rest of the buffer with zeros. */
|
||||
memset(((unsigned char *) ctx_buf) + bytes_have, 0,
|
||||
memset(((unsigned char *)ctx_buf) + bytes_have, 0,
|
||||
CURL_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 */
|
||||
CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
||||
CURL_PUT_64BIT_BE(((unsigned char *)ctx_buf) \
|
||||
+ CURL_SHA512_256_BLOCK_SIZE \
|
||||
- SHA512_256_SIZE_OF_LEN_ADD, \
|
||||
ctx->count_bits_hi);
|
||||
CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
||||
CURL_PUT_64BIT_BE(((unsigned char *)ctx_buf) \
|
||||
+ CURL_SHA512_256_BLOCK_SIZE \
|
||||
- SHA512_256_SIZE_OF_LEN_ADD \
|
||||
+ SHA512_256_BYTES_IN_WORD, \
|
||||
|
|
@ -760,7 +746,6 @@ static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
|
|||
|
||||
#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
|
||||
|
|
@ -778,7 +763,7 @@ CURLcode Curl_sha512_256it(unsigned char *output, const unsigned char *input,
|
|||
if(res != CURLE_OK)
|
||||
return res;
|
||||
|
||||
res = Curl_sha512_256_update(&ctx, (const void *) input, input_size);
|
||||
res = Curl_sha512_256_update(&ctx, (const void *)input, input_size);
|
||||
|
||||
if(res != CURLE_OK) {
|
||||
(void)Curl_sha512_256_finish(output, &ctx);
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_DIGEST_AUTH) && !defined(CURL_DISABLE_SHA512_256)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_hmac.h"
|
||||
|
||||
#define CURL_HAVE_SHA512_256
|
||||
|
|
@ -35,9 +36,8 @@ extern const struct HMAC_params Curl_HMAC_SHA512_256[1];
|
|||
|
||||
#define CURL_SHA512_256_DIGEST_LENGTH 32
|
||||
|
||||
CURLcode
|
||||
Curl_sha512_256it(unsigned char *output, const unsigned char *input,
|
||||
size_t input_size);
|
||||
CURLcode Curl_sha512_256it(unsigned char *output, const unsigned char *input,
|
||||
size_t input_size);
|
||||
|
||||
#endif /* !CURL_DISABLE_DIGEST_AUTH && !CURL_DISABLE_SHA512_256 */
|
||||
|
||||
|
|
|
|||
|
|
@ -24,31 +24,24 @@
|
|||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "connect.h"
|
||||
#include "share.h"
|
||||
#include "psl.h"
|
||||
#include "curl_share.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "vtls/vtls_scache.h"
|
||||
#include "hsts.h"
|
||||
#include "url.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
CURLSH *
|
||||
curl_share_init(void)
|
||||
CURLSH *curl_share_init(void)
|
||||
{
|
||||
struct Curl_share *share = calloc(1, sizeof(struct Curl_share));
|
||||
struct Curl_share *share = curlx_calloc(1, sizeof(struct Curl_share));
|
||||
if(share) {
|
||||
share->magic = CURL_GOOD_SHARE;
|
||||
share->specifier |= (1 << CURL_LOCK_DATA_SHARE);
|
||||
Curl_dnscache_init(&share->dnscache, 23);
|
||||
share->admin = curl_easy_init();
|
||||
if(!share->admin) {
|
||||
free(share);
|
||||
curlx_free(share);
|
||||
return NULL;
|
||||
}
|
||||
/* admin handles have mid 0 */
|
||||
|
|
@ -64,8 +57,7 @@ curl_share_init(void)
|
|||
}
|
||||
|
||||
#undef curl_share_setopt
|
||||
CURLSHcode
|
||||
curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
|
||||
CURLSHcode curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
|
||||
{
|
||||
va_list param;
|
||||
int type;
|
||||
|
|
@ -97,7 +89,7 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
|
|||
case CURL_LOCK_DATA_COOKIE:
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
if(!share->cookies) {
|
||||
share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE);
|
||||
share->cookies = Curl_cookie_init();
|
||||
if(!share->cookies)
|
||||
res = CURLSHE_NOMEM;
|
||||
}
|
||||
|
|
@ -228,8 +220,7 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
|
|||
return res;
|
||||
}
|
||||
|
||||
CURLSHcode
|
||||
curl_share_cleanup(CURLSH *sh)
|
||||
CURLSHcode curl_share_cleanup(CURLSH *sh)
|
||||
{
|
||||
struct Curl_share *share = sh;
|
||||
if(!GOOD_SHARE_HANDLE(share))
|
||||
|
|
@ -272,15 +263,13 @@ curl_share_cleanup(CURLSH *sh)
|
|||
if(share->unlockfunc)
|
||||
share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
|
||||
share->magic = 0;
|
||||
free(share);
|
||||
curlx_free(share);
|
||||
|
||||
return CURLSHE_OK;
|
||||
}
|
||||
|
||||
|
||||
CURLSHcode
|
||||
Curl_share_lock(struct Curl_easy *data, curl_lock_data type,
|
||||
curl_lock_access accesstype)
|
||||
CURLSHcode Curl_share_lock(struct Curl_easy *data, curl_lock_data type,
|
||||
curl_lock_access accesstype)
|
||||
{
|
||||
struct Curl_share *share = data->share;
|
||||
|
||||
|
|
@ -296,8 +285,7 @@ Curl_share_lock(struct Curl_easy *data, curl_lock_data type,
|
|||
return CURLSHE_OK;
|
||||
}
|
||||
|
||||
CURLSHcode
|
||||
Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
|
||||
CURLSHcode Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
|
||||
{
|
||||
struct Curl_share *share = data->share;
|
||||
|
||||
|
|
@ -306,7 +294,7 @@ Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
|
|||
|
||||
if(share->specifier & (unsigned int)(1 << type)) {
|
||||
if(share->unlockfunc) /* only call this if set! */
|
||||
share->unlockfunc (data, type, share->clientdata);
|
||||
share->unlockfunc(data, type, share->clientdata);
|
||||
}
|
||||
|
||||
return CURLSHE_OK;
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "cookie.h"
|
||||
#include "psl.h"
|
||||
#include "urldata.h"
|
||||
|
|
@ -38,7 +38,7 @@ struct Curl_ssl_scache;
|
|||
#define GOOD_SHARE_HANDLE(x) ((x) && (x)->magic == CURL_GOOD_SHARE)
|
||||
|
||||
#define CURL_SHARE_KEEP_CONNECT(s) \
|
||||
((s) && ((s)->specifier & (1<< CURL_LOCK_DATA_CONNECT)))
|
||||
((s) && ((s)->specifier & (1 << CURL_LOCK_DATA_CONNECT)))
|
||||
|
||||
/* this struct is libcurl-private, do not export details */
|
||||
struct Curl_share {
|
||||
|
|
@ -71,8 +71,8 @@ CURLSHcode Curl_share_lock(struct Curl_easy *, curl_lock_data,
|
|||
CURLSHcode Curl_share_unlock(struct Curl_easy *, curl_lock_data);
|
||||
|
||||
/* convenience macro to check if this handle is using a shared SSL spool */
|
||||
#define CURL_SHARE_ssl_scache(data) (data->share && \
|
||||
#define CURL_SHARE_ssl_scache(data) (data->share && \
|
||||
(data->share->specifier & \
|
||||
(1<<CURL_LOCK_DATA_SSL_SESSION)))
|
||||
(1 << CURL_LOCK_DATA_SSL_SESSION)))
|
||||
|
||||
#endif /* HEADER_CURL_SHARE_H */
|
||||
|
|
@ -26,17 +26,11 @@
|
|||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_sspi.h"
|
||||
#include "strdup.h"
|
||||
#include "curlx/multibyte.h"
|
||||
#include "system_win32.h"
|
||||
#include "curlx/warnless.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Pointer to SSPI dispatch table */
|
||||
PSecurityFunctionTable Curl_pSecFn = NULL;
|
||||
|
||||
|
|
@ -62,11 +56,7 @@ CURLcode Curl_sspi_global_init(void)
|
|||
/* If security interface is not yet initialized try to do this */
|
||||
if(!Curl_pSecFn) {
|
||||
/* Get pointer to Security Service Provider Interface dispatch table */
|
||||
#ifdef __MINGW32CE__
|
||||
Curl_pSecFn = InitSecurityInterfaceW();
|
||||
#else
|
||||
Curl_pSecFn = InitSecurityInterface();
|
||||
#endif
|
||||
if(!Curl_pSecFn)
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
|
@ -138,43 +128,54 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
|||
}
|
||||
|
||||
/* Setup the identity's user and length */
|
||||
dup_user.tchar_ptr = Curl_tcsdup(user.tchar_ptr);
|
||||
dup_user.tchar_ptr = curlx_tcsdup(user.tchar_ptr);
|
||||
if(!dup_user.tchar_ptr) {
|
||||
curlx_unicodefree(useranddomain.tchar_ptr);
|
||||
curlx_free(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));
|
||||
dup_domain.tchar_ptr = curlx_malloc(sizeof(TCHAR) * (domlen + 1));
|
||||
if(!dup_domain.tchar_ptr) {
|
||||
curlx_unicodefree(useranddomain.tchar_ptr);
|
||||
curlx_free(dup_user.tchar_ptr);
|
||||
curlx_free(useranddomain.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(_tcsncpy_s(dup_domain.tchar_ptr, domlen + 1, domain.tchar_ptr, domlen)) {
|
||||
curlx_free(dup_user.tchar_ptr);
|
||||
curlx_free(dup_domain.tchar_ptr);
|
||||
curlx_free(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);
|
||||
curlx_free(useranddomain.tchar_ptr);
|
||||
|
||||
/* Setup the identity's password and length */
|
||||
passwd.tchar_ptr = curlx_convert_UTF8_to_tchar(passwdp);
|
||||
if(!passwd.tchar_ptr)
|
||||
if(!passwd.tchar_ptr) {
|
||||
curlx_free(dup_user.tchar_ptr);
|
||||
curlx_free(dup_domain.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
dup_passwd.tchar_ptr = Curl_tcsdup(passwd.tchar_ptr);
|
||||
}
|
||||
dup_passwd.tchar_ptr = curlx_tcsdup(passwd.tchar_ptr);
|
||||
if(!dup_passwd.tchar_ptr) {
|
||||
curlx_unicodefree(passwd.tchar_ptr);
|
||||
curlx_free(dup_user.tchar_ptr);
|
||||
curlx_free(dup_domain.tchar_ptr);
|
||||
curlx_free(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);
|
||||
curlx_free(passwd.tchar_ptr);
|
||||
|
||||
identity->User = dup_user.tbyte_ptr;
|
||||
identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr));
|
||||
dup_user.tchar_ptr = NULL;
|
||||
identity->Domain = dup_domain.tbyte_ptr;
|
||||
identity->DomainLength = curlx_uztoul(domlen);
|
||||
dup_domain.tchar_ptr = NULL;
|
||||
|
||||
/* Setup the identity's flags */
|
||||
identity->Flags = (unsigned long)
|
||||
|
|
|
|||
254
lib/curl_sspi.h
254
lib/curl_sspi.h
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
#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.
|
||||
|
|
@ -70,225 +68,6 @@ extern PSecurityFunctionTable Curl_pSecFn;
|
|||
#define ISC_REQ_USE_HTTP_STYLE 0x01000000
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32CE__
|
||||
#ifndef ISC_RET_REPLAY_DETECT
|
||||
#define ISC_RET_REPLAY_DETECT 0x00000004
|
||||
#endif
|
||||
#ifndef ISC_RET_SEQUENCE_DETECT
|
||||
#define ISC_RET_SEQUENCE_DETECT 0x00000008
|
||||
#endif
|
||||
#ifndef ISC_RET_CONFIDENTIALITY
|
||||
#define ISC_RET_CONFIDENTIALITY 0x00000010
|
||||
#endif
|
||||
#ifndef ISC_RET_ALLOCATED_MEMORY
|
||||
#define ISC_RET_ALLOCATED_MEMORY 0x00000100
|
||||
#endif
|
||||
#ifndef ISC_RET_STREAM
|
||||
#define ISC_RET_STREAM 0x00008000
|
||||
#endif
|
||||
|
||||
#ifndef SEC_E_INSUFFICIENT_MEMORY
|
||||
#define SEC_E_INSUFFICIENT_MEMORY ((HRESULT)0x80090300L)
|
||||
#endif
|
||||
#ifndef SEC_E_INVALID_HANDLE
|
||||
#define SEC_E_INVALID_HANDLE ((HRESULT)0x80090301L)
|
||||
#endif
|
||||
#ifndef SEC_E_UNSUPPORTED_FUNCTION
|
||||
#define SEC_E_UNSUPPORTED_FUNCTION ((HRESULT)0x80090302L)
|
||||
#endif
|
||||
#ifndef SEC_E_TARGET_UNKNOWN
|
||||
#define SEC_E_TARGET_UNKNOWN ((HRESULT)0x80090303L)
|
||||
#endif
|
||||
#ifndef SEC_E_INTERNAL_ERROR
|
||||
#define SEC_E_INTERNAL_ERROR ((HRESULT)0x80090304L)
|
||||
#endif
|
||||
#ifndef SEC_E_SECPKG_NOT_FOUND
|
||||
#define SEC_E_SECPKG_NOT_FOUND ((HRESULT)0x80090305L)
|
||||
#endif
|
||||
#ifndef SEC_E_NOT_OWNER
|
||||
#define SEC_E_NOT_OWNER ((HRESULT)0x80090306L)
|
||||
#endif
|
||||
#ifndef SEC_E_CANNOT_INSTALL
|
||||
#define SEC_E_CANNOT_INSTALL ((HRESULT)0x80090307L)
|
||||
#endif
|
||||
#ifndef SEC_E_INVALID_TOKEN
|
||||
#define SEC_E_INVALID_TOKEN ((HRESULT)0x80090308L)
|
||||
#endif
|
||||
#ifndef SEC_E_CANNOT_PACK
|
||||
#define SEC_E_CANNOT_PACK ((HRESULT)0x80090309L)
|
||||
#endif
|
||||
#ifndef SEC_E_QOP_NOT_SUPPORTED
|
||||
#define SEC_E_QOP_NOT_SUPPORTED ((HRESULT)0x8009030AL)
|
||||
#endif
|
||||
#ifndef SEC_E_NO_IMPERSONATION
|
||||
#define SEC_E_NO_IMPERSONATION ((HRESULT)0x8009030BL)
|
||||
#endif
|
||||
#ifndef SEC_E_LOGON_DENIED
|
||||
#define SEC_E_LOGON_DENIED ((HRESULT)0x8009030CL)
|
||||
#endif
|
||||
#ifndef SEC_E_UNKNOWN_CREDENTIALS
|
||||
#define SEC_E_UNKNOWN_CREDENTIALS ((HRESULT)0x8009030DL)
|
||||
#endif
|
||||
#ifndef SEC_E_NO_CREDENTIALS
|
||||
#define SEC_E_NO_CREDENTIALS ((HRESULT)0x8009030EL)
|
||||
#endif
|
||||
#ifndef SEC_E_MESSAGE_ALTERED
|
||||
#define SEC_E_MESSAGE_ALTERED ((HRESULT)0x8009030FL)
|
||||
#endif
|
||||
#ifndef SEC_E_OUT_OF_SEQUENCE
|
||||
#define SEC_E_OUT_OF_SEQUENCE ((HRESULT)0x80090310L)
|
||||
#endif
|
||||
#ifndef SEC_E_NO_AUTHENTICATING_AUTHORITY
|
||||
#define SEC_E_NO_AUTHENTICATING_AUTHORITY ((HRESULT)0x80090311L)
|
||||
#endif
|
||||
#ifndef SEC_E_BAD_PKGID
|
||||
#define SEC_E_BAD_PKGID ((HRESULT)0x80090316L)
|
||||
#endif
|
||||
#ifndef SEC_E_CONTEXT_EXPIRED
|
||||
#define SEC_E_CONTEXT_EXPIRED ((HRESULT)0x80090317L)
|
||||
#endif
|
||||
#ifndef SEC_E_INCOMPLETE_MESSAGE
|
||||
#define SEC_E_INCOMPLETE_MESSAGE ((HRESULT)0x80090318L)
|
||||
#endif
|
||||
#ifndef SEC_E_INCOMPLETE_CREDENTIALS
|
||||
#define SEC_E_INCOMPLETE_CREDENTIALS ((HRESULT)0x80090320L)
|
||||
#endif
|
||||
#ifndef SEC_E_BUFFER_TOO_SMALL
|
||||
#define SEC_E_BUFFER_TOO_SMALL ((HRESULT)0x80090321L)
|
||||
#endif
|
||||
#ifndef SEC_E_WRONG_PRINCIPAL
|
||||
#define SEC_E_WRONG_PRINCIPAL ((HRESULT)0x80090322L)
|
||||
#endif
|
||||
#ifndef SEC_E_TIME_SKEW
|
||||
#define SEC_E_TIME_SKEW ((HRESULT)0x80090324L)
|
||||
#endif
|
||||
#ifndef SEC_E_UNTRUSTED_ROOT
|
||||
#define SEC_E_UNTRUSTED_ROOT ((HRESULT)0x80090325L)
|
||||
#endif
|
||||
#ifndef SEC_E_ILLEGAL_MESSAGE
|
||||
#define SEC_E_ILLEGAL_MESSAGE ((HRESULT)0x80090326L)
|
||||
#endif
|
||||
#ifndef SEC_E_CERT_UNKNOWN
|
||||
#define SEC_E_CERT_UNKNOWN ((HRESULT)0x80090327L)
|
||||
#endif
|
||||
#ifndef SEC_E_CERT_EXPIRED
|
||||
#define SEC_E_CERT_EXPIRED ((HRESULT)0x80090328L)
|
||||
#endif
|
||||
#ifndef SEC_E_ENCRYPT_FAILURE
|
||||
#define SEC_E_ENCRYPT_FAILURE ((HRESULT)0x80090329L)
|
||||
#endif
|
||||
#ifndef SEC_E_DECRYPT_FAILURE
|
||||
#define SEC_E_DECRYPT_FAILURE ((HRESULT)0x80090330L)
|
||||
#endif
|
||||
#ifndef SEC_E_ALGORITHM_MISMATCH
|
||||
#define SEC_E_ALGORITHM_MISMATCH ((HRESULT)0x80090331L)
|
||||
#endif
|
||||
#ifndef SEC_E_SECURITY_QOS_FAILED
|
||||
#define SEC_E_SECURITY_QOS_FAILED ((HRESULT)0x80090332L)
|
||||
#endif
|
||||
#ifndef SEC_E_UNFINISHED_CONTEXT_DELETED
|
||||
#define SEC_E_UNFINISHED_CONTEXT_DELETED ((HRESULT)0x80090333L)
|
||||
#endif
|
||||
#ifndef SEC_E_NO_TGT_REPLY
|
||||
#define SEC_E_NO_TGT_REPLY ((HRESULT)0x80090334L)
|
||||
#endif
|
||||
#ifndef SEC_E_NO_IP_ADDRESSES
|
||||
#define SEC_E_NO_IP_ADDRESSES ((HRESULT)0x80090335L)
|
||||
#endif
|
||||
#ifndef SEC_E_WRONG_CREDENTIAL_HANDLE
|
||||
#define SEC_E_WRONG_CREDENTIAL_HANDLE ((HRESULT)0x80090336L)
|
||||
#endif
|
||||
#ifndef SEC_E_CRYPTO_SYSTEM_INVALID
|
||||
#define SEC_E_CRYPTO_SYSTEM_INVALID ((HRESULT)0x80090337L)
|
||||
#endif
|
||||
#ifndef SEC_E_MAX_REFERRALS_EXCEEDED
|
||||
#define SEC_E_MAX_REFERRALS_EXCEEDED ((HRESULT)0x80090338L)
|
||||
#endif
|
||||
#ifndef SEC_E_MUST_BE_KDC
|
||||
#define SEC_E_MUST_BE_KDC ((HRESULT)0x80090339L)
|
||||
#endif
|
||||
#ifndef SEC_E_STRONG_CRYPTO_NOT_SUPPORTED
|
||||
#define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED ((HRESULT)0x8009033AL)
|
||||
#endif
|
||||
#ifndef SEC_E_TOO_MANY_PRINCIPALS
|
||||
#define SEC_E_TOO_MANY_PRINCIPALS ((HRESULT)0x8009033BL)
|
||||
#endif
|
||||
#ifndef SEC_E_NO_PA_DATA
|
||||
#define SEC_E_NO_PA_DATA ((HRESULT)0x8009033CL)
|
||||
#endif
|
||||
#ifndef SEC_E_PKINIT_NAME_MISMATCH
|
||||
#define SEC_E_PKINIT_NAME_MISMATCH ((HRESULT)0x8009033DL)
|
||||
#endif
|
||||
#ifndef SEC_E_SMARTCARD_LOGON_REQUIRED
|
||||
#define SEC_E_SMARTCARD_LOGON_REQUIRED ((HRESULT)0x8009033EL)
|
||||
#endif
|
||||
#ifndef SEC_E_SHUTDOWN_IN_PROGRESS
|
||||
#define SEC_E_SHUTDOWN_IN_PROGRESS ((HRESULT)0x8009033FL)
|
||||
#endif
|
||||
#ifndef SEC_E_KDC_INVALID_REQUEST
|
||||
#define SEC_E_KDC_INVALID_REQUEST ((HRESULT)0x80090340L)
|
||||
#endif
|
||||
#ifndef SEC_E_KDC_UNABLE_TO_REFER
|
||||
#define SEC_E_KDC_UNABLE_TO_REFER ((HRESULT)0x80090341L)
|
||||
#endif
|
||||
#ifndef SEC_E_KDC_UNKNOWN_ETYPE
|
||||
#define SEC_E_KDC_UNKNOWN_ETYPE ((HRESULT)0x80090342L)
|
||||
#endif
|
||||
#ifndef SEC_E_UNSUPPORTED_PREAUTH
|
||||
#define SEC_E_UNSUPPORTED_PREAUTH ((HRESULT)0x80090343L)
|
||||
#endif
|
||||
#ifndef SEC_E_DELEGATION_REQUIRED
|
||||
#define SEC_E_DELEGATION_REQUIRED ((HRESULT)0x80090345L)
|
||||
#endif
|
||||
#ifndef SEC_E_BAD_BINDINGS
|
||||
#define SEC_E_BAD_BINDINGS ((HRESULT)0x80090346L)
|
||||
#endif
|
||||
#ifndef SEC_E_MULTIPLE_ACCOUNTS
|
||||
#define SEC_E_MULTIPLE_ACCOUNTS ((HRESULT)0x80090347L)
|
||||
#endif
|
||||
#ifndef SEC_E_NO_KERB_KEY
|
||||
#define SEC_E_NO_KERB_KEY ((HRESULT)0x80090348L)
|
||||
#endif
|
||||
#ifndef SEC_E_CERT_WRONG_USAGE
|
||||
#define SEC_E_CERT_WRONG_USAGE ((HRESULT)0x80090349L)
|
||||
#endif
|
||||
#ifndef SEC_E_DOWNGRADE_DETECTED
|
||||
#define SEC_E_DOWNGRADE_DETECTED ((HRESULT)0x80090350L)
|
||||
#endif
|
||||
#ifndef SEC_E_SMARTCARD_CERT_REVOKED
|
||||
#define SEC_E_SMARTCARD_CERT_REVOKED ((HRESULT)0x80090351L)
|
||||
#endif
|
||||
#ifndef SEC_E_ISSUING_CA_UNTRUSTED
|
||||
#define SEC_E_ISSUING_CA_UNTRUSTED ((HRESULT)0x80090352L)
|
||||
#endif
|
||||
#ifndef SEC_E_REVOCATION_OFFLINE_C
|
||||
#define SEC_E_REVOCATION_OFFLINE_C ((HRESULT)0x80090353L)
|
||||
#endif
|
||||
#ifndef SEC_E_PKINIT_CLIENT_FAILURE
|
||||
#define SEC_E_PKINIT_CLIENT_FAILURE ((HRESULT)0x80090354L)
|
||||
#endif
|
||||
#ifndef SEC_E_SMARTCARD_CERT_EXPIRED
|
||||
#define SEC_E_SMARTCARD_CERT_EXPIRED ((HRESULT)0x80090355L)
|
||||
#endif
|
||||
#ifndef SEC_E_NO_S4U_PROT_SUPPORT
|
||||
#define SEC_E_NO_S4U_PROT_SUPPORT ((HRESULT)0x80090356L)
|
||||
#endif
|
||||
#ifndef SEC_E_CROSSREALM_DELEGATION_FAILURE
|
||||
#define SEC_E_CROSSREALM_DELEGATION_FAILURE ((HRESULT)0x80090357L)
|
||||
#endif
|
||||
#ifndef SEC_E_REVOCATION_OFFLINE_KDC
|
||||
#define SEC_E_REVOCATION_OFFLINE_KDC ((HRESULT)0x80090358L)
|
||||
#endif
|
||||
#ifndef SEC_E_ISSUING_CA_UNTRUSTED_KDC
|
||||
#define SEC_E_ISSUING_CA_UNTRUSTED_KDC ((HRESULT)0x80090359L)
|
||||
#endif
|
||||
#ifndef SEC_E_KDC_CERT_EXPIRED
|
||||
#define SEC_E_KDC_CERT_EXPIRED ((HRESULT)0x8009035AL)
|
||||
#endif
|
||||
#ifndef SEC_E_KDC_CERT_REVOKED
|
||||
#define SEC_E_KDC_CERT_REVOKED ((HRESULT)0x8009035BL)
|
||||
#endif
|
||||
#endif /* __MINGW32CE__ */
|
||||
/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */
|
||||
#ifndef SEC_E_INVALID_PARAMETER
|
||||
#define SEC_E_INVALID_PARAMETER ((HRESULT)0x8009035DL)
|
||||
|
|
@ -302,44 +81,11 @@ extern PSecurityFunctionTable Curl_pSecFn;
|
|||
#define SEC_E_POLICY_NLTM_ONLY ((HRESULT)0x8009035FL)
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32CE__
|
||||
#ifndef SEC_I_CONTINUE_NEEDED
|
||||
#define SEC_I_CONTINUE_NEEDED ((HRESULT)0x00090312L)
|
||||
#endif
|
||||
#ifndef SEC_I_COMPLETE_NEEDED
|
||||
#define SEC_I_COMPLETE_NEEDED ((HRESULT)0x00090313L)
|
||||
#endif
|
||||
#ifndef SEC_I_COMPLETE_AND_CONTINUE
|
||||
#define SEC_I_COMPLETE_AND_CONTINUE ((HRESULT)0x00090314L)
|
||||
#endif
|
||||
#ifndef SEC_I_LOCAL_LOGON
|
||||
#define SEC_I_LOCAL_LOGON ((HRESULT)0x00090315L)
|
||||
#endif
|
||||
#ifndef SEC_I_CONTEXT_EXPIRED
|
||||
#define SEC_I_CONTEXT_EXPIRED ((HRESULT)0x00090317L)
|
||||
#endif
|
||||
#ifndef SEC_I_INCOMPLETE_CREDENTIALS
|
||||
#define SEC_I_INCOMPLETE_CREDENTIALS ((HRESULT)0x00090320L)
|
||||
#endif
|
||||
#ifndef SEC_I_RENEGOTIATE
|
||||
#define SEC_I_RENEGOTIATE ((HRESULT)0x00090321L)
|
||||
#endif
|
||||
#ifndef SEC_I_NO_LSA_CONTEXT
|
||||
#define SEC_I_NO_LSA_CONTEXT ((HRESULT)0x00090323L)
|
||||
#endif
|
||||
#endif /* __MINGW32CE__ */
|
||||
|
||||
/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */
|
||||
#ifndef SEC_I_SIGNATURE_NEEDED
|
||||
#define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL)
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32CE__
|
||||
#ifndef CRYPT_E_NOT_IN_REVOCATION_DATABASE
|
||||
#define CRYPT_E_NOT_IN_REVOCATION_DATABASE ((HRESULT)0x80092014L)
|
||||
#endif
|
||||
#endif /* __MINGW32CE__ */
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -24,16 +24,11 @@
|
|||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "curl_threads.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include FILE should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef USE_THREADS_POSIX
|
||||
|
||||
|
|
@ -48,7 +43,7 @@ static void *curl_thread_create_thunk(void *arg)
|
|||
unsigned int (*func)(void *) = ac->func;
|
||||
void *real_arg = ac->arg;
|
||||
|
||||
free(ac);
|
||||
curlx_free(ac);
|
||||
|
||||
(*func)(real_arg);
|
||||
|
||||
|
|
@ -58,8 +53,8 @@ static void *curl_thread_create_thunk(void *arg)
|
|||
curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T
|
||||
(CURL_STDCALL *func) (void *), void *arg)
|
||||
{
|
||||
curl_thread_t t = malloc(sizeof(pthread_t));
|
||||
struct Curl_actual_call *ac = malloc(sizeof(struct Curl_actual_call));
|
||||
curl_thread_t t = curlx_malloc(sizeof(pthread_t));
|
||||
struct Curl_actual_call *ac = curlx_malloc(sizeof(struct Curl_actual_call));
|
||||
int rc;
|
||||
if(!(ac && t))
|
||||
goto err;
|
||||
|
|
@ -69,15 +64,15 @@ curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T
|
|||
|
||||
rc = pthread_create(t, NULL, curl_thread_create_thunk, ac);
|
||||
if(rc) {
|
||||
CURL_SETERRNO(rc);
|
||||
errno = rc;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return t;
|
||||
|
||||
err:
|
||||
free(t);
|
||||
free(ac);
|
||||
curlx_free(t);
|
||||
curlx_free(ac);
|
||||
return curl_thread_t_null;
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +80,7 @@ void Curl_thread_destroy(curl_thread_t *hnd)
|
|||
{
|
||||
if(*hnd != curl_thread_t_null) {
|
||||
pthread_detach(**hnd);
|
||||
free(*hnd);
|
||||
curlx_free(*hnd);
|
||||
*hnd = curl_thread_t_null;
|
||||
}
|
||||
}
|
||||
|
|
@ -94,7 +89,7 @@ int Curl_thread_join(curl_thread_t *hnd)
|
|||
{
|
||||
int ret = (pthread_join(**hnd, NULL) == 0);
|
||||
|
||||
free(*hnd);
|
||||
curlx_free(*hnd);
|
||||
*hnd = curl_thread_t_null;
|
||||
|
||||
return ret;
|
||||
|
|
@ -109,10 +104,9 @@ curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T
|
|||
if(!t) {
|
||||
DWORD gle = GetLastError();
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
int err = (gle == ERROR_ACCESS_DENIED ||
|
||||
gle == ERROR_NOT_ENOUGH_MEMORY) ?
|
||||
EACCES : EINVAL;
|
||||
CURL_SETERRNO(err);
|
||||
errno = (gle == ERROR_ACCESS_DENIED ||
|
||||
gle == ERROR_NOT_ENOUGH_MEMORY) ?
|
||||
EACCES : EINVAL;
|
||||
return curl_thread_t_null;
|
||||
}
|
||||
return t;
|
||||
|
|
@ -128,11 +122,7 @@ void Curl_thread_destroy(curl_thread_t *hnd)
|
|||
|
||||
int Curl_thread_join(curl_thread_t *hnd)
|
||||
{
|
||||
#ifdef UNDER_CE
|
||||
int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
|
||||
#else
|
||||
int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
|
||||
#endif
|
||||
|
||||
Curl_thread_destroy(hnd);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,17 +24,13 @@
|
|||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_trc.h"
|
||||
#include "urldata.h"
|
||||
#include "easyif.h"
|
||||
#include "cfilters.h"
|
||||
#include "multiif.h"
|
||||
|
||||
#include "cf-socket.h"
|
||||
#include "connect.h"
|
||||
#include "doh.h"
|
||||
#include "http2.h"
|
||||
#include "http_proxy.h"
|
||||
#include "cf-h1-proxy.h"
|
||||
|
|
@ -42,15 +38,12 @@
|
|||
#include "cf-haproxy.h"
|
||||
#include "cf-https-connect.h"
|
||||
#include "cf-ip-happy.h"
|
||||
#include "progress.h"
|
||||
#include "socks.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "vquic/vquic.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static void trc_write(struct Curl_easy *data, curl_infotype type,
|
||||
const char *ptr, size_t size)
|
||||
{
|
||||
|
|
@ -276,7 +269,7 @@ struct curl_trc_feat Curl_trc_feat_timer = {
|
|||
CURL_LOG_LVL_NONE,
|
||||
};
|
||||
|
||||
static const char * const Curl_trc_timer_names[]={
|
||||
static const char * const Curl_trc_timer_names[] = {
|
||||
"100_TIMEOUT",
|
||||
"ASYNC_NAME",
|
||||
"CONNECTTIMEOUT",
|
||||
|
|
@ -318,25 +311,24 @@ void Curl_trc_easy_timers(struct Curl_easy *data)
|
|||
if(CURL_TRC_TIMER_is_verbose(data)) {
|
||||
struct Curl_llist_node *e = Curl_llist_head(&data->state.timeoutlist);
|
||||
if(e) {
|
||||
struct curltime now = curlx_now();
|
||||
const struct curltime *pnow = Curl_pgrs_now(data);
|
||||
while(e) {
|
||||
struct time_node *n = Curl_node_elem(e);
|
||||
e = Curl_node_next(e);
|
||||
CURL_TRC_TIMER(data, n->eid, "expires in %" FMT_TIMEDIFF_T "ns",
|
||||
curlx_timediff_us(n->time, now));
|
||||
curlx_ptimediff_us(&n->time, pnow));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char * const Curl_trc_mstate_names[]={
|
||||
static const char * const Curl_trc_mstate_names[] = {
|
||||
"INIT",
|
||||
"PENDING",
|
||||
"SETUP",
|
||||
"CONNECT",
|
||||
"RESOLVING",
|
||||
"CONNECTING",
|
||||
"TUNNELING",
|
||||
"PROTOCONNECT",
|
||||
"PROTOCONNECTING",
|
||||
"DO",
|
||||
|
|
@ -457,6 +449,24 @@ void Curl_trc_ssls(struct Curl_easy *data, const char *fmt, ...)
|
|||
}
|
||||
#endif /* USE_SSL */
|
||||
|
||||
#ifdef USE_SSH
|
||||
struct curl_trc_feat Curl_trc_feat_ssh = {
|
||||
"SSH",
|
||||
CURL_LOG_LVL_NONE,
|
||||
};
|
||||
|
||||
void Curl_trc_ssh(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
||||
if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssh)) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
trc_infof(data, &Curl_trc_feat_ssh, NULL, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#endif /* USE_SSH */
|
||||
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
struct curl_trc_feat Curl_trc_feat_ws = {
|
||||
"WS",
|
||||
|
|
@ -476,10 +486,10 @@ void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
|
|||
#endif /* !CURL_DISABLE_WEBSOCKETS && !CURL_DISABLE_HTTP */
|
||||
|
||||
#define TRC_CT_NONE (0)
|
||||
#define TRC_CT_PROTOCOL (1<<(0))
|
||||
#define TRC_CT_NETWORK (1<<(1))
|
||||
#define TRC_CT_PROXY (1<<(2))
|
||||
#define TRC_CT_INTERNALS (1<<(3))
|
||||
#define TRC_CT_PROTOCOL (1 << 0)
|
||||
#define TRC_CT_NETWORK (1 << 1)
|
||||
#define TRC_CT_PROXY (1 << 2)
|
||||
#define TRC_CT_INTERNALS (1 << 3)
|
||||
|
||||
struct trc_feat_def {
|
||||
struct curl_trc_feat *feat;
|
||||
|
|
@ -496,14 +506,15 @@ static struct trc_feat_def trc_feats[] = {
|
|||
#ifndef CURL_DISABLE_FTP
|
||||
{ &Curl_trc_feat_ftp, TRC_CT_PROTOCOL },
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
{ &Curl_trc_feat_smtp, TRC_CT_PROTOCOL },
|
||||
#endif
|
||||
#ifdef USE_SSL
|
||||
{ &Curl_trc_feat_ssls, TRC_CT_NETWORK },
|
||||
#endif
|
||||
#ifdef USE_SSH
|
||||
{ &Curl_trc_feat_ssh, TRC_CT_PROTOCOL },
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
{ &Curl_trc_feat_ws, TRC_CT_PROTOCOL },
|
||||
#endif
|
||||
|
|
@ -648,56 +659,75 @@ CURLcode Curl_trc_init(void)
|
|||
|
||||
void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_cf_infof(struct Curl_easy *data, const struct Curl_cfilter *cf,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)cf; (void)fmt;
|
||||
(void)data;
|
||||
(void)cf;
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_multi(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_dns(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_timer(struct Curl_easy *data, int tid, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)tid; (void)fmt;
|
||||
(void)data;
|
||||
(void)tid;
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SSH
|
||||
void Curl_trc_ssh(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SSL
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ void Curl_failf(struct Curl_easy *data,
|
|||
#define CURL_LOG_LVL_NONE 0
|
||||
#define CURL_LOG_LVL_INFO 1
|
||||
|
||||
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#define CURL_HAVE_C99
|
||||
#endif
|
||||
|
|
@ -117,6 +116,11 @@ extern struct curl_trc_feat Curl_trc_feat_ssls;
|
|||
void Curl_trc_ssls(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
#ifdef USE_SSH
|
||||
extern struct curl_trc_feat Curl_trc_feat_ssh;
|
||||
void Curl_trc_ssh(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
extern struct curl_trc_feat Curl_trc_feat_ws;
|
||||
void Curl_trc_ws(struct Curl_easy *data,
|
||||
|
|
@ -168,6 +172,11 @@ void Curl_trc_ws(struct Curl_easy *data,
|
|||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssls)) \
|
||||
Curl_trc_ssls(data, __VA_ARGS__); } while(0)
|
||||
#endif /* USE_SSL */
|
||||
#ifdef USE_SSH
|
||||
#define CURL_TRC_SSH(data, ...) \
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssh)) \
|
||||
Curl_trc_ssh(data, __VA_ARGS__); } while(0)
|
||||
#endif /* USE_SSH */
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
#define CURL_TRC_WS(data, ...) \
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) \
|
||||
|
|
@ -176,9 +185,9 @@ void Curl_trc_ws(struct Curl_easy *data,
|
|||
|
||||
#else /* CURL_HAVE_C99 */
|
||||
|
||||
#define infof Curl_infof
|
||||
#define CURL_TRC_M Curl_trc_multi
|
||||
#define CURL_TRC_CF Curl_trc_cf_infof
|
||||
#define infof Curl_infof
|
||||
#define CURL_TRC_M Curl_trc_multi
|
||||
#define CURL_TRC_CF Curl_trc_cf_infof
|
||||
#define CURL_TRC_WRITE Curl_trc_write
|
||||
#define CURL_TRC_READ Curl_trc_read
|
||||
#define CURL_TRC_DNS Curl_trc_dns
|
||||
|
|
@ -193,6 +202,9 @@ void Curl_trc_ws(struct Curl_easy *data,
|
|||
#ifdef USE_SSL
|
||||
#define CURL_TRC_SSLS Curl_trc_ssls
|
||||
#endif
|
||||
#ifdef USE_SSH
|
||||
#define CURL_TRC_SSH Curl_trc_ssh
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
#define CURL_TRC_WS Curl_trc_ws
|
||||
#endif
|
||||
|
|
@ -227,8 +239,8 @@ extern struct curl_trc_feat Curl_trc_feat_timer;
|
|||
/* 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)
|
||||
#define Curl_trc_cf_is_verbose(x, y) (FALSE)
|
||||
#define Curl_trc_ft_is_verbose(x, y) (FALSE)
|
||||
#define CURL_MSTATE_NAME(x) ((void)(x), "-")
|
||||
#define CURL_TRC_EASY_TIMERS(x) Curl_nop_stmt
|
||||
|
||||
|
|
|
|||
|
|
@ -26,31 +26,25 @@
|
|||
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "warnless.h"
|
||||
#include "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 --- */
|
||||
const char Curl_base64encdec[]=
|
||||
const char Curl_base64encdec[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648
|
||||
section 5 */
|
||||
static const char base64url[]=
|
||||
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 };
|
||||
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
|
||||
};
|
||||
/*
|
||||
* curlx_base64_decode()
|
||||
*
|
||||
|
|
@ -66,7 +60,7 @@ static const unsigned char decodetable[] =
|
|||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode curlx_base64_decode(const char *src,
|
||||
unsigned char **outptr, size_t *outlen)
|
||||
uint8_t **outptr, size_t *outlen)
|
||||
{
|
||||
size_t srclen = 0;
|
||||
size_t padding = 0;
|
||||
|
|
@ -103,7 +97,7 @@ CURLcode curlx_base64_decode(const char *src,
|
|||
rawlen = (numQuantums * 3) - padding;
|
||||
|
||||
/* Allocate our buffer including room for a null-terminator */
|
||||
newstr = malloc(rawlen + 1);
|
||||
newstr = curlx_malloc(rawlen + 1);
|
||||
if(!newstr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -165,13 +159,13 @@ CURLcode curlx_base64_decode(const char *src,
|
|||
|
||||
return CURLE_OK;
|
||||
bad:
|
||||
free(newstr);
|
||||
curlx_free(newstr);
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
static CURLcode base64_encode(const char *table64,
|
||||
unsigned char padbyte,
|
||||
const char *inputbuff, size_t insize,
|
||||
uint8_t padbyte,
|
||||
const uint8_t *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
char *output;
|
||||
|
|
@ -184,28 +178,28 @@ static CURLcode base64_encode(const char *table64,
|
|||
if(!insize)
|
||||
return CURLE_OK;
|
||||
|
||||
#if SIZEOF_SIZE_T == 4
|
||||
if(insize > UINT_MAX/4)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
/* safety precaution */
|
||||
DEBUGASSERT(insize <= CURL_MAX_BASE64_INPUT);
|
||||
if(insize > CURL_MAX_BASE64_INPUT)
|
||||
return CURLE_TOO_LARGE;
|
||||
|
||||
base64data = output = malloc((insize + 2) / 3 * 4 + 1);
|
||||
base64data = output = curlx_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 ];
|
||||
*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 ];
|
||||
*output++ = table64[in[0] >> 2];
|
||||
if(insize == 1) {
|
||||
*output++ = table64[ ((in[0] & 0x03) << 4) ];
|
||||
*output++ = table64[((in[0] & 0x03) << 4)];
|
||||
if(padbyte) {
|
||||
*output++ = padbyte;
|
||||
*output++ = padbyte;
|
||||
|
|
@ -213,8 +207,8 @@ static CURLcode base64_encode(const char *table64,
|
|||
}
|
||||
else {
|
||||
/* insize == 2 */
|
||||
*output++ = table64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4) ];
|
||||
*output++ = table64[ ((in[1] & 0x0F) << 2) ];
|
||||
*output++ = table64[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
|
||||
*output++ = table64[((in[1] & 0x0F) << 2)];
|
||||
if(padbyte)
|
||||
*output++ = padbyte;
|
||||
}
|
||||
|
|
@ -245,7 +239,7 @@ static CURLcode base64_encode(const char *table64,
|
|||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode curlx_base64_encode(const char *inputbuff, size_t insize,
|
||||
CURLcode curlx_base64_encode(const uint8_t *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
return base64_encode(Curl_base64encdec, '=',
|
||||
|
|
@ -267,7 +261,7 @@ CURLcode curlx_base64_encode(const char *inputbuff, size_t insize,
|
|||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode curlx_base64url_encode(const char *inputbuff, size_t insize,
|
||||
CURLcode curlx_base64url_encode(const uint8_t *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
return base64_encode(base64url, 0, inputbuff, insize, outptr, outlen);
|
||||
|
|
|
|||
|
|
@ -24,13 +24,17 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
CURLcode curlx_base64_encode(const char *inputbuff, size_t insize,
|
||||
CURLcode curlx_base64_encode(const uint8_t *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
CURLcode curlx_base64url_encode(const char *inputbuff, size_t insize,
|
||||
CURLcode curlx_base64url_encode(const uint8_t *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
CURLcode curlx_base64_decode(const char *src,
|
||||
unsigned char **outptr, size_t *outlen);
|
||||
uint8_t **outptr, size_t *outlen);
|
||||
|
||||
extern const char Curl_base64encdec[];
|
||||
|
||||
/* maximum input length acceptable to base64 encode, here to catch and prevent
|
||||
mistakes */
|
||||
#define CURL_MAX_BASE64_INPUT 16000000
|
||||
|
||||
#endif /* HEADER_CURL_BASE64_H */
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
curlx_convert_wchar_to_UTF8()
|
||||
curlx_convert_UTF8_to_tchar()
|
||||
curlx_convert_tchar_to_UTF8()
|
||||
curlx_unicodefree()
|
||||
*/
|
||||
|
||||
#include "version_win32.h"
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@
|
|||
#include "../curl_setup.h"
|
||||
#include "dynbuf.h"
|
||||
#include "../curl_printf.h"
|
||||
#ifdef BUILDING_LIBCURL
|
||||
#include "../curl_memory.h"
|
||||
#endif
|
||||
#include "../memdebug.h"
|
||||
|
||||
#define MIN_FIRST_ALLOC 32
|
||||
|
||||
|
|
@ -108,7 +104,7 @@ static CURLcode dyn_nappend(struct dynbuf *s,
|
|||
if(a != s->allc) {
|
||||
/* this logic is not using Curl_saferealloc() to make the tool not have to
|
||||
include that as well when it uses this code */
|
||||
void *p = realloc(s->bufr, a);
|
||||
void *p = curlx_realloc(s->bufr, a);
|
||||
if(!p) {
|
||||
curlx_dyn_free(s);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
|
@ -160,7 +156,6 @@ CURLcode curlx_dyn_tail(struct dynbuf *s, size_t trail)
|
|||
s->bufr[s->leng] = 0;
|
||||
}
|
||||
return CURLE_OK;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -212,7 +207,7 @@ CURLcode curlx_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap)
|
|||
|
||||
if(str) {
|
||||
CURLcode result = dyn_nappend(s, (const unsigned char *)str, strlen(str));
|
||||
free(str);
|
||||
curlx_free(str);
|
||||
return result;
|
||||
}
|
||||
/* If we failed, we cleanup the whole buffer and return error */
|
||||
|
|
|
|||
|
|
@ -24,15 +24,13 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct dynbuf {
|
||||
char *bufr; /* point to a null-terminated allocated buffer */
|
||||
size_t leng; /* number of bytes *EXCLUDING* the null-terminator */
|
||||
size_t allc; /* size of the current allocation */
|
||||
size_t toobig; /* size limit for the buffer */
|
||||
#ifdef DEBUGBUILD
|
||||
int init; /* detect API usage mistakes */
|
||||
int init; /* detect API usage mistakes */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -62,24 +60,24 @@ int curlx_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save);
|
|||
char *curlx_dyn_take(struct dynbuf *s, size_t *plen);
|
||||
|
||||
/* Dynamic buffer max sizes */
|
||||
#define MAX_DYNBUF_SIZE (SIZE_MAX/2)
|
||||
#define MAX_DYNBUF_SIZE (SIZE_MAX / 2)
|
||||
|
||||
#define DYN_DOH_RESPONSE 3000
|
||||
#define DYN_DOH_CNAME 256
|
||||
#define DYN_PAUSE_BUFFER (64 * 1024 * 1024)
|
||||
#define DYN_HAXPROXY 2048
|
||||
#define DYN_HTTP_REQUEST (1024*1024)
|
||||
#define DYN_HTTP_REQUEST (1024 * 1024)
|
||||
#define DYN_APRINTF 8000000
|
||||
#define DYN_RTSP_REQ_HEADER (64*1024)
|
||||
#define DYN_TRAILERS (64*1024)
|
||||
#define DYN_RTSP_REQ_HEADER (64 * 1024)
|
||||
#define DYN_TRAILERS (64 * 1024)
|
||||
#define DYN_PROXY_CONNECT_HEADERS 16384
|
||||
#define DYN_QLOG_NAME 1024
|
||||
#define DYN_H1_TRAILER 4096
|
||||
#define DYN_PINGPPONG_CMD (64*1024)
|
||||
#define DYN_IMAP_CMD (64*1024)
|
||||
#define DYN_MQTT_RECV (64*1024)
|
||||
#define DYN_PINGPPONG_CMD (64 * 1024)
|
||||
#define DYN_IMAP_CMD (64 * 1024)
|
||||
#define DYN_MQTT_RECV (64 * 1024)
|
||||
#define DYN_MQTT_SEND 0xFFFFFFF
|
||||
#define DYN_CRLFILE_SIZE (400*1024*1024) /* 400mb */
|
||||
#define DYN_CERTFILE_SIZE (100*1024) /* 100KiB */
|
||||
#define DYN_KEYFILE_SIZE (100*1024) /* 100KiB */
|
||||
#define DYN_CRLFILE_SIZE (400 * 1024 * 1024) /* 400MiB */
|
||||
#define DYN_CERTFILE_SIZE (100 * 1024) /* 100KiB */
|
||||
#define DYN_KEYFILE_SIZE (100 * 1024) /* 100KiB */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,21 +22,13 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This file is 'mem-include-scan' clean, which means its memory allocations
|
||||
* are not tracked by the curl memory tracker memdebug, so they must not use
|
||||
* `CURLDEBUG` macro replacements in memdebug.h for free, malloc, etc. To avoid
|
||||
* these macro replacements, wrap the names in parentheses to call the original
|
||||
* versions: `ptr = (malloc)(123)`, `(free)(ptr)`, etc.
|
||||
*/
|
||||
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#include "fopen.h"
|
||||
|
||||
int curlx_fseek(void *stream, curl_off_t offset, int whence)
|
||||
{
|
||||
#if defined(_WIN32) && defined(USE_WIN32_LARGE_FILES)
|
||||
#ifdef _WIN32
|
||||
return _fseeki64(stream, (__int64)offset, whence);
|
||||
#elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO)
|
||||
return fseeko(stream, (off_t)offset, whence);
|
||||
|
|
@ -47,9 +39,47 @@ int curlx_fseek(void *stream, curl_off_t offset, int whence)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <share.h> /* for _SH_DENYNO */
|
||||
|
||||
#include "multibyte.h"
|
||||
#include "timeval.h"
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/*
|
||||
* Use system allocators to avoid infinite recursion when called by curl's
|
||||
* memory tracker memdebug functions.
|
||||
*/
|
||||
#define CURLX_MALLOC(x) malloc(x)
|
||||
#define CURLX_FREE(x) free(x)
|
||||
#else
|
||||
#define CURLX_MALLOC(x) curlx_malloc(x)
|
||||
#define CURLX_FREE(x) curlx_free(x)
|
||||
#endif
|
||||
|
||||
#ifdef _UNICODE
|
||||
static wchar_t *fn_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 = CURLX_MALLOC(str_w_len * sizeof(wchar_t));
|
||||
if(str_w) {
|
||||
if(MultiByteToWideChar(CP_UTF8, 0,
|
||||
str_utf8, -1, str_w, str_w_len) == 0) {
|
||||
CURLX_FREE(str_w);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return str_w;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* declare GetFullPathNameW for mingw-w64 UWP builds targeting old windows */
|
||||
#if defined(CURL_WINDOWS_UWP) && defined(__MINGW32__) && \
|
||||
|
|
@ -97,15 +127,16 @@ static bool fix_excessive_path(const TCHAR *in, TCHAR **out)
|
|||
|
||||
#ifndef _UNICODE
|
||||
/* convert multibyte input to unicode */
|
||||
needed = mbstowcs(NULL, in, 0);
|
||||
if(needed == (size_t)-1 || needed >= max_path_len)
|
||||
if(mbstowcs_s(&needed, NULL, 0, in, 0))
|
||||
goto cleanup;
|
||||
++needed; /* for NUL */
|
||||
ibuf = (malloc)(needed * sizeof(wchar_t));
|
||||
if(!needed || needed >= max_path_len)
|
||||
goto cleanup;
|
||||
ibuf = CURLX_MALLOC(needed * sizeof(wchar_t));
|
||||
if(!ibuf)
|
||||
goto cleanup;
|
||||
count = mbstowcs(ibuf, in, needed);
|
||||
if(count == (size_t)-1 || count >= needed)
|
||||
if(mbstowcs_s(&count, ibuf, needed, in, needed - 1))
|
||||
goto cleanup;
|
||||
if(count != needed)
|
||||
goto cleanup;
|
||||
in_w = ibuf;
|
||||
#else
|
||||
|
|
@ -121,7 +152,7 @@ static bool fix_excessive_path(const TCHAR *in, TCHAR **out)
|
|||
/* skip paths that are not excessive and do not need modification */
|
||||
if(needed <= MAX_PATH)
|
||||
goto cleanup;
|
||||
fbuf = (malloc)(needed * sizeof(wchar_t));
|
||||
fbuf = CURLX_MALLOC(needed * sizeof(wchar_t));
|
||||
if(!fbuf)
|
||||
goto cleanup;
|
||||
count = (size_t)GetFullPathNameW(in_w, (DWORD)needed, fbuf, NULL);
|
||||
|
|
@ -142,7 +173,7 @@ static bool fix_excessive_path(const TCHAR *in, TCHAR **out)
|
|||
else if(!wcsncmp(fbuf, L"\\\\.\\", 4))
|
||||
fbuf[2] = '?';
|
||||
else if(!wcsncmp(fbuf, L"\\\\.", 3) || !wcsncmp(fbuf, L"\\\\?", 3)) {
|
||||
/* Unexpected, not UNC. The formatting doc doesn't allow this AFAICT. */
|
||||
/* Unexpected, not UNC. The formatting doc does not allow this AFAICT. */
|
||||
goto cleanup;
|
||||
}
|
||||
else {
|
||||
|
|
@ -154,12 +185,18 @@ static bool fix_excessive_path(const TCHAR *in, TCHAR **out)
|
|||
if(needed > max_path_len)
|
||||
goto cleanup;
|
||||
|
||||
temp = (malloc)(needed * sizeof(wchar_t));
|
||||
temp = CURLX_MALLOC(needed * sizeof(wchar_t));
|
||||
if(!temp)
|
||||
goto cleanup;
|
||||
|
||||
wcsncpy(temp, L"\\\\?\\UNC\\", 8);
|
||||
wcscpy(temp + 8, fbuf + 2);
|
||||
if(wcsncpy_s(temp, needed, L"\\\\?\\UNC\\", 8)) {
|
||||
CURLX_FREE(temp);
|
||||
goto cleanup;
|
||||
}
|
||||
if(wcscpy_s(temp + 8, needed, fbuf + 2)) {
|
||||
CURLX_FREE(temp);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* "\\?\" + full path + null */
|
||||
|
|
@ -167,29 +204,36 @@ static bool fix_excessive_path(const TCHAR *in, TCHAR **out)
|
|||
if(needed > max_path_len)
|
||||
goto cleanup;
|
||||
|
||||
temp = (malloc)(needed * sizeof(wchar_t));
|
||||
temp = CURLX_MALLOC(needed * sizeof(wchar_t));
|
||||
if(!temp)
|
||||
goto cleanup;
|
||||
|
||||
wcsncpy(temp, L"\\\\?\\", 4);
|
||||
wcscpy(temp + 4, fbuf);
|
||||
if(wcsncpy_s(temp, needed, L"\\\\?\\", 4)) {
|
||||
CURLX_FREE(temp);
|
||||
goto cleanup;
|
||||
}
|
||||
if(wcscpy_s(temp + 4, needed, fbuf)) {
|
||||
CURLX_FREE(temp);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
(free)(fbuf);
|
||||
CURLX_FREE(fbuf);
|
||||
fbuf = temp;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
/* convert unicode full path to multibyte output */
|
||||
needed = wcstombs(NULL, fbuf, 0);
|
||||
if(needed == (size_t)-1 || needed >= max_path_len)
|
||||
if(wcstombs_s(&needed, NULL, 0, fbuf, 0))
|
||||
goto cleanup;
|
||||
++needed; /* for NUL */
|
||||
obuf = (malloc)(needed);
|
||||
if(!needed || needed >= max_path_len)
|
||||
goto cleanup;
|
||||
obuf = CURLX_MALLOC(needed);
|
||||
if(!obuf)
|
||||
goto cleanup;
|
||||
count = wcstombs(obuf, fbuf, needed);
|
||||
if(count == (size_t)-1 || count >= needed)
|
||||
if(wcstombs_s(&count, obuf, needed, fbuf, needed - 1))
|
||||
goto cleanup;
|
||||
if(count != needed)
|
||||
goto cleanup;
|
||||
*out = obuf;
|
||||
obuf = NULL;
|
||||
|
|
@ -199,14 +243,57 @@ static bool fix_excessive_path(const TCHAR *in, TCHAR **out)
|
|||
#endif
|
||||
|
||||
cleanup:
|
||||
(free)(fbuf);
|
||||
CURLX_FREE(fbuf);
|
||||
#ifndef _UNICODE
|
||||
(free)(ibuf);
|
||||
(free)(obuf);
|
||||
CURLX_FREE(ibuf);
|
||||
CURLX_FREE(obuf);
|
||||
#endif
|
||||
return *out ? true : false;
|
||||
}
|
||||
|
||||
#ifndef CURL_WINDOWS_UWP
|
||||
HANDLE curlx_CreateFile(const char *filename,
|
||||
DWORD dwDesiredAccess,
|
||||
DWORD dwShareMode,
|
||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
DWORD dwCreationDisposition,
|
||||
DWORD dwFlagsAndAttributes,
|
||||
HANDLE hTemplateFile)
|
||||
{
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
#ifdef UNICODE
|
||||
TCHAR *filename_t = curlx_convert_UTF8_to_wchar(filename);
|
||||
#else
|
||||
const TCHAR *filename_t = filename;
|
||||
#endif
|
||||
|
||||
if(filename_t) {
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
if(fix_excessive_path(filename_t, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_t;
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
handle = CreateFile(target,
|
||||
dwDesiredAccess,
|
||||
dwShareMode,
|
||||
lpSecurityAttributes,
|
||||
dwCreationDisposition,
|
||||
dwFlagsAndAttributes,
|
||||
hTemplateFile);
|
||||
CURLX_FREE(fixed);
|
||||
#ifdef UNICODE
|
||||
curlx_free(filename_t);
|
||||
#endif
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
#endif /* !CURL_WINDOWS_UWP */
|
||||
|
||||
int curlx_win32_open(const char *filename, int oflag, ...)
|
||||
{
|
||||
int pmode = 0;
|
||||
|
|
@ -215,7 +302,7 @@ int curlx_win32_open(const char *filename, int oflag, ...)
|
|||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
wchar_t *filename_w = fn_convert_UTF8_to_wchar(filename);
|
||||
#endif
|
||||
|
||||
va_list param;
|
||||
|
|
@ -230,21 +317,21 @@ int curlx_win32_open(const char *filename, int oflag, ...)
|
|||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
result = _wopen(target, oflag, pmode);
|
||||
curlx_unicodefree(filename_w);
|
||||
errno = _wsopen_s(&result, target, oflag, _SH_DENYNO, pmode);
|
||||
CURLX_FREE(filename_w);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
CURL_SETERRNO(EINVAL);
|
||||
errno = EINVAL;
|
||||
#else
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
result = _open(target, oflag, pmode);
|
||||
errno = _sopen_s(&result, target, oflag, _SH_DENYNO, pmode);
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
CURLX_FREE(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -255,30 +342,67 @@ FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
|||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
|
||||
wchar_t *filename_w = fn_convert_UTF8_to_wchar(filename);
|
||||
wchar_t *mode_w = fn_convert_UTF8_to_wchar(mode);
|
||||
if(filename_w && mode_w) {
|
||||
if(fix_excessive_path(filename_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
result = _wfopen(target, mode_w);
|
||||
errno = _wfopen_s(&result, target, mode_w);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
CURL_SETERRNO(EINVAL);
|
||||
curlx_unicodefree(filename_w);
|
||||
curlx_unicodefree(mode_w);
|
||||
errno = EINVAL;
|
||||
CURLX_FREE(filename_w);
|
||||
CURLX_FREE(mode_w);
|
||||
#else
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
result = fopen(target, mode);
|
||||
errno = fopen_s(&result, target, mode);
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
CURLX_FREE(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR < 5)
|
||||
_CRTIMP errno_t __cdecl freopen_s(FILE **file, const char *filename,
|
||||
const char *mode, FILE *stream);
|
||||
#endif
|
||||
|
||||
FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fp)
|
||||
{
|
||||
FILE *result = NULL;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *filename_w = fn_convert_UTF8_to_wchar(filename);
|
||||
wchar_t *mode_w = fn_convert_UTF8_to_wchar(mode);
|
||||
if(filename_w && mode_w) {
|
||||
if(fix_excessive_path(filename_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
errno = _wfreopen_s(&result, target, mode_w, fp);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
errno = EINVAL;
|
||||
CURLX_FREE(filename_w);
|
||||
CURLX_FREE(mode_w);
|
||||
#else
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
errno = freopen_s(&result, target, mode, fp);
|
||||
#endif
|
||||
|
||||
CURLX_FREE(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -295,30 +419,91 @@ int curlx_win32_stat(const char *path, struct_stat *buffer)
|
|||
target = fixed;
|
||||
else
|
||||
target = path_w;
|
||||
#ifndef USE_WIN32_LARGE_FILES
|
||||
result = _wstat(target, buffer);
|
||||
#else
|
||||
result = _wstati64(target, buffer);
|
||||
#endif
|
||||
curlx_unicodefree(path_w);
|
||||
curlx_free(path_w);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
CURL_SETERRNO(EINVAL);
|
||||
errno = EINVAL;
|
||||
#else
|
||||
if(fix_excessive_path(path, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = path;
|
||||
#ifndef USE_WIN32_LARGE_FILES
|
||||
result = _stat(target, buffer);
|
||||
#else
|
||||
result = _stati64(target, buffer);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
CURLX_FREE(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 && !UNDER_CE */
|
||||
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_COOKIES) || \
|
||||
!defined(CURL_DISABLE_ALTSVC)
|
||||
/* rename() on Windows does not overwrite, so we cannot use it here.
|
||||
MoveFileEx() will overwrite and is usually atomic, however it fails
|
||||
when there are open handles to the file. */
|
||||
int curlx_win32_rename(const char *oldpath, const char *newpath)
|
||||
{
|
||||
int res = -1; /* fail */
|
||||
|
||||
#ifdef UNICODE
|
||||
TCHAR *tchar_oldpath = curlx_convert_UTF8_to_wchar(oldpath);
|
||||
TCHAR *tchar_newpath = curlx_convert_UTF8_to_wchar(newpath);
|
||||
#else
|
||||
const TCHAR *tchar_oldpath = oldpath;
|
||||
const TCHAR *tchar_newpath = newpath;
|
||||
#endif
|
||||
|
||||
if(tchar_oldpath && tchar_newpath) {
|
||||
const int max_wait_ms = 1000;
|
||||
struct curltime start;
|
||||
|
||||
TCHAR *oldpath_fixed = NULL;
|
||||
TCHAR *newpath_fixed = NULL;
|
||||
const TCHAR *target_oldpath;
|
||||
const TCHAR *target_newpath;
|
||||
|
||||
if(fix_excessive_path(tchar_oldpath, &oldpath_fixed))
|
||||
target_oldpath = oldpath_fixed;
|
||||
else
|
||||
target_oldpath = tchar_oldpath;
|
||||
|
||||
if(fix_excessive_path(tchar_newpath, &newpath_fixed))
|
||||
target_newpath = newpath_fixed;
|
||||
else
|
||||
target_newpath = tchar_newpath;
|
||||
|
||||
start = curlx_now();
|
||||
|
||||
for(;;) {
|
||||
timediff_t diff;
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
if(MoveFileEx(target_oldpath, target_newpath,
|
||||
MOVEFILE_REPLACE_EXISTING)) {
|
||||
res = 0; /* success */
|
||||
break;
|
||||
}
|
||||
diff = curlx_timediff_ms(curlx_now(), start);
|
||||
if(diff < 0 || diff > max_wait_ms) {
|
||||
break;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
CURLX_FREE(oldpath_fixed);
|
||||
CURLX_FREE(newpath_fixed);
|
||||
}
|
||||
|
||||
#ifdef UNICODE
|
||||
curlx_free(tchar_oldpath);
|
||||
curlx_free(tchar_newpath);
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef CURLX_MALLOC
|
||||
#undef CURLX_FREE
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
|
|
|||
|
|
@ -34,25 +34,44 @@
|
|||
|
||||
int curlx_fseek(void *stream, curl_off_t offset, int whence);
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
#ifdef _WIN32
|
||||
#ifndef CURL_WINDOWS_UWP
|
||||
HANDLE curlx_CreateFile(const char *filename,
|
||||
DWORD dwDesiredAccess,
|
||||
DWORD dwShareMode,
|
||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
DWORD dwCreationDisposition,
|
||||
DWORD dwFlagsAndAttributes,
|
||||
HANDLE hTemplateFile);
|
||||
#endif /* !CURL_WINDOWS_UWP */
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode);
|
||||
FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fh);
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer);
|
||||
int curlx_win32_open(const char *filename, int oflag, ...);
|
||||
#define CURLX_FOPEN_LOW(fname, mode) curlx_win32_fopen(fname, mode)
|
||||
#define curlx_stat(fname, stp) curlx_win32_stat(fname, stp)
|
||||
#define curlx_open curlx_win32_open
|
||||
int curlx_win32_rename(const char *oldpath, const char *newpath);
|
||||
#define CURLX_FOPEN_LOW(fname, mode) curlx_win32_fopen(fname, mode)
|
||||
#define CURLX_FREOPEN_LOW(fname, mode, fh) curlx_win32_freopen(fname, mode, fh)
|
||||
#define curlx_stat(fname, stp) curlx_win32_stat(fname, stp)
|
||||
#define curlx_open curlx_win32_open
|
||||
#define curlx_rename curlx_win32_rename
|
||||
#else
|
||||
#define CURLX_FOPEN_LOW fopen
|
||||
#define curlx_stat(fname, stp) stat(fname, stp)
|
||||
#define curlx_open open
|
||||
#define CURLX_FOPEN_LOW fopen
|
||||
#define CURLX_FREOPEN_LOW freopen
|
||||
#define curlx_stat(fname, stp) stat(fname, stp)
|
||||
#define curlx_open open
|
||||
#define curlx_rename rename
|
||||
#endif
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
#define curlx_fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__)
|
||||
#define curlx_fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__)
|
||||
#define curlx_fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__)
|
||||
#define curlx_fopen(file, mode) curl_dbg_fopen(file, mode, __LINE__, __FILE__)
|
||||
#define curlx_freopen(file, mode, fh) \
|
||||
curl_dbg_freopen(file, mode, fh, __LINE__, __FILE__)
|
||||
#define curlx_fdopen(file, mode) \
|
||||
curl_dbg_fdopen(file, mode, __LINE__, __FILE__)
|
||||
#define curlx_fclose(file) curl_dbg_fclose(file, __LINE__, __FILE__)
|
||||
#else
|
||||
#define curlx_fopen CURLX_FOPEN_LOW
|
||||
#define curlx_freopen CURLX_FREOPEN_LOW
|
||||
#define curlx_fdopen fdopen
|
||||
#define curlx_fclose fclose
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#endif
|
||||
|
||||
#include "inet_ntop.h"
|
||||
#include "snprintf.h"
|
||||
|
||||
#define IN6ADDRSZ 16
|
||||
/* #define INADDRSZ 4 */
|
||||
|
|
@ -61,20 +62,19 @@ static char *inet_ntop4(const unsigned char *src, char *dst, size_t size)
|
|||
|
||||
DEBUGASSERT(size >= 16);
|
||||
|
||||
/* this sprintf() does not overflow the buffer. Avoids snprintf to work more
|
||||
widely. Avoids the msnprintf family to work as a curlx function. */
|
||||
(void)(sprintf)(tmp, "%d.%d.%d.%d",
|
||||
((int)((unsigned char)src[0])) & 0xff,
|
||||
((int)((unsigned char)src[1])) & 0xff,
|
||||
((int)((unsigned char)src[2])) & 0xff,
|
||||
((int)((unsigned char)src[3])) & 0xff);
|
||||
/* this snprintf() does not overflow the buffer. */
|
||||
SNPRINTF(tmp, sizeof(tmp), "%d.%d.%d.%d",
|
||||
((int)((unsigned char)src[0])) & 0xff,
|
||||
((int)((unsigned char)src[1])) & 0xff,
|
||||
((int)((unsigned char)src[2])) & 0xff,
|
||||
((int)((unsigned char)src[3])) & 0xff);
|
||||
|
||||
len = strlen(tmp);
|
||||
if(len == 0 || len >= size) {
|
||||
#ifdef USE_WINSOCK
|
||||
CURL_SETERRNO(WSAEINVAL);
|
||||
errno = WSAEINVAL;
|
||||
#else
|
||||
CURL_SETERRNO(ENOSPC);
|
||||
errno = ENOSPC;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -109,17 +109,18 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
|||
*/
|
||||
memset(words, '\0', sizeof(words));
|
||||
for(i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i/2] |= ((unsigned int)src[i] << ((1 - (i % 2)) << 3));
|
||||
words[i / 2] |= ((unsigned int)src[i] << ((1 - (i % 2)) << 3));
|
||||
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
cur.base = -1;
|
||||
best.len = 0;
|
||||
cur.len = 0;
|
||||
|
||||
for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||
if(words[i] == 0) {
|
||||
if(cur.base == -1) {
|
||||
cur.base = i; cur.len = 1;
|
||||
cur.base = i;
|
||||
cur.len = 1;
|
||||
}
|
||||
else
|
||||
cur.len++;
|
||||
|
|
@ -152,7 +153,7 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
|||
/* Is this address an encapsulated IPv4?
|
||||
*/
|
||||
if(i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if(!inet_ntop4(src + 12, tp, sizeof(tmp) - (tp - tmp))) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -160,7 +161,7 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
|||
break;
|
||||
}
|
||||
else {
|
||||
/* Lower-case digits. Can't use the set from mprintf.c since this
|
||||
/* Lower-case digits. Cannot use the set from mprintf.c since this
|
||||
needs to work as a curlx function */
|
||||
static const unsigned char ldigits[] = "0123456789abcdef";
|
||||
|
||||
|
|
@ -186,9 +187,9 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
|||
*/
|
||||
if((size_t)(tp - tmp) > size) {
|
||||
#ifdef USE_WINSOCK
|
||||
CURL_SETERRNO(WSAEINVAL);
|
||||
errno = WSAEINVAL;
|
||||
#else
|
||||
CURL_SETERRNO(ENOSPC);
|
||||
errno = ENOSPC;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -215,8 +216,8 @@ char *curlx_inet_ntop(int af, const void *src, char *buf, size_t size)
|
|||
case AF_INET6:
|
||||
return inet_ntop6((const unsigned char *)src, buf, size);
|
||||
default:
|
||||
CURL_SETERRNO(SOCKEAFNOSUPPORT);
|
||||
errno = SOCKEAFNOSUPPORT;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_INET_NTOP */
|
||||
#endif /* HAVE_INET_NTOP */
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@
|
|||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef __AMIGA__
|
||||
#define curlx_inet_ntop(af,addr,buf,size) \
|
||||
#define curlx_inet_ntop(af, addr, buf, size) \
|
||||
(char *)inet_ntop(af, CURL_UNCONST(addr), (unsigned char *)buf, \
|
||||
(curl_socklen_t)(size))
|
||||
#else
|
||||
#define curlx_inet_ntop(af,addr,buf,size) \
|
||||
#define curlx_inet_ntop(af, addr, buf, size) \
|
||||
inet_ntop(af, addr, buf, (curl_socklen_t)(size))
|
||||
#endif
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "../curl_setup.h"
|
||||
#include "../curl_ctype.h"
|
||||
|
||||
#include "strparse.h"
|
||||
|
||||
#ifndef HAVE_INET_PTON
|
||||
|
|
@ -54,8 +54,8 @@
|
|||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4(const char *src, unsigned char *dst);
|
||||
static int inet_pton6(const char *src, unsigned char *dst);
|
||||
static int inet_pton4(const char *src, unsigned char *dst);
|
||||
static int inet_pton6(const char *src, unsigned char *dst);
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
|
|
@ -73,8 +73,7 @@ static int inet_pton6(const char *src, unsigned char *dst);
|
|||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
curlx_inet_pton(int af, const char *src, void *dst)
|
||||
int curlx_inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
|
|
@ -82,7 +81,7 @@ curlx_inet_pton(int af, const char *src, void *dst)
|
|||
case AF_INET6:
|
||||
return inet_pton6(src, (unsigned char *)dst);
|
||||
default:
|
||||
CURL_SETERRNO(SOCKEAFNOSUPPORT);
|
||||
errno = SOCKEAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
|
|
@ -98,8 +97,7 @@ curlx_inet_pton(int af, const char *src, void *dst)
|
|||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(const char *src, unsigned char *dst)
|
||||
static int inet_pton4(const char *src, unsigned char *dst)
|
||||
{
|
||||
int saw_digit, octets, ch;
|
||||
unsigned char tmp[INADDRSZ], *tp;
|
||||
|
|
@ -151,8 +149,7 @@ inet_pton4(const char *src, unsigned char *dst)
|
|||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6(const char *src, unsigned char *dst)
|
||||
static int inet_pton6(const char *src, unsigned char *dst)
|
||||
{
|
||||
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *curtok;
|
||||
|
|
@ -187,14 +184,14 @@ inet_pton6(const char *src, unsigned char *dst)
|
|||
}
|
||||
if(tp + INT16SZ > endp)
|
||||
return 0;
|
||||
*tp++ = (unsigned char) ((val >> 8) & 0xff);
|
||||
*tp++ = (unsigned char) (val & 0xff);
|
||||
*tp++ = (unsigned char)((val >> 8) & 0xff);
|
||||
*tp++ = (unsigned char)(val & 0xff);
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
|
|
@ -204,8 +201,8 @@ inet_pton6(const char *src, unsigned char *dst)
|
|||
if(saw_xdigit) {
|
||||
if(tp + INT16SZ > endp)
|
||||
return 0;
|
||||
*tp++ = (unsigned char) ((val >> 8) & 0xff);
|
||||
*tp++ = (unsigned char) (val & 0xff);
|
||||
*tp++ = (unsigned char)((val >> 8) & 0xff);
|
||||
*tp++ = (unsigned char)(val & 0xff);
|
||||
}
|
||||
if(colonp) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -37,9 +37,11 @@
|
|||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef __AMIGA__
|
||||
#define curlx_inet_pton(x,y,z) inet_pton(x,(unsigned char *)CURL_UNCONST(y),z)
|
||||
#define curlx_inet_pton(x, y, z) \
|
||||
inet_pton(x, (unsigned char *)CURL_UNCONST(y), z)
|
||||
#else
|
||||
#define curlx_inet_pton(x,y,z) inet_pton(x,y,z)
|
||||
#define curlx_inet_pton(x, y, z) \
|
||||
inet_pton(x, y, z)
|
||||
#endif
|
||||
#else
|
||||
int curlx_inet_pton(int, const char *, void *);
|
||||
|
|
|
|||
|
|
@ -22,17 +22,9 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This file is 'mem-include-scan' clean, which means its memory allocations
|
||||
* are not tracked by the curl memory tracker memdebug, so they must not use
|
||||
* `CURLDEBUG` macro replacements in memdebug.h for free, malloc, etc. To avoid
|
||||
* these macro replacements, wrap the names in parentheses to call the original
|
||||
* versions: `ptr = (malloc)(123)`, `(free)(ptr)`, etc.
|
||||
*/
|
||||
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && defined(UNICODE)
|
||||
|
||||
#include "multibyte.h"
|
||||
|
||||
|
|
@ -48,11 +40,11 @@ wchar_t *curlx_convert_UTF8_to_wchar(const char *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));
|
||||
str_w = curlx_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);
|
||||
curlx_free(str_w);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -70,11 +62,11 @@ char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
|
|||
int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1,
|
||||
NULL, 0, NULL, NULL);
|
||||
if(bytes > 0) {
|
||||
str_utf8 = (malloc)(bytes);
|
||||
str_utf8 = curlx_malloc(bytes);
|
||||
if(str_utf8) {
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes,
|
||||
NULL, NULL) == 0) {
|
||||
(free)(str_utf8);
|
||||
curlx_free(str_utf8);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -84,4 +76,4 @@ char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
|
|||
return str_utf8;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
#endif /* _WIN32 && UNICODE */
|
||||
|
|
|
|||
|
|
@ -26,35 +26,27 @@
|
|||
#include "../curl_setup.h"
|
||||
|
||||
#ifdef _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
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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 will notice that curlx
|
||||
* function-like macros call free and strdup in parentheses, eg (strdup)(ptr),
|
||||
* and that is to ensure that the curl memdebug override macros do not replace
|
||||
* them.
|
||||
*/
|
||||
|
||||
#if defined(UNICODE) && defined(_WIN32)
|
||||
#ifdef UNICODE
|
||||
|
||||
#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))
|
||||
/* 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);
|
||||
|
||||
#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;
|
||||
|
|
@ -63,10 +55,10 @@ typedef union {
|
|||
const unsigned short *const_tbyte_ptr;
|
||||
} xcharp_u;
|
||||
|
||||
#else
|
||||
#else /* !UNICODE */
|
||||
|
||||
#define curlx_convert_UTF8_to_tchar(ptr) (strdup)(ptr)
|
||||
#define curlx_convert_tchar_to_UTF8(ptr) (strdup)(ptr)
|
||||
#define curlx_convert_UTF8_to_tchar(ptr) curlx_strdup(ptr)
|
||||
#define curlx_convert_tchar_to_UTF8(ptr) curlx_strdup(ptr)
|
||||
|
||||
typedef union {
|
||||
char *tchar_ptr;
|
||||
|
|
@ -75,9 +67,7 @@ typedef union {
|
|||
const unsigned char *const_tbyte_ptr;
|
||||
} xcharp_u;
|
||||
|
||||
#endif /* UNICODE && _WIN32 */
|
||||
|
||||
/* the purpose of this macro is to free() without being traced by memdebug */
|
||||
#define curlx_unicodefree(ptr) (free)(CURL_UNCONST(ptr))
|
||||
#endif /* UNICODE */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* HEADER_CURL_MULTIBYTE_H */
|
||||
|
|
|
|||
|
|
@ -88,6 +88,6 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */
|
|||
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
|
||||
#else
|
||||
# error "no non-blocking method was found/used/set"
|
||||
#error "no non-blocking method was found/used/set"
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <curl/curl.h> /* for curl_socket_t */
|
||||
|
||||
int curlx_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
int nonblock /* TRUE or FALSE */);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,16 +22,15 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* Unset redefined system symbols. */
|
||||
/* Raw snprintf() for curlx */
|
||||
|
||||
#undef strdup
|
||||
#undef malloc
|
||||
#undef calloc
|
||||
#undef realloc
|
||||
#undef free
|
||||
#ifdef _WIN32
|
||||
#undef Curl_tcsdup
|
||||
#ifdef WITHOUT_LIBCURL /* when built for the test servers */
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900) /* adjust for old MSVC */
|
||||
#define SNPRINTF _snprintf
|
||||
#else
|
||||
#define SNPRINTF snprintf
|
||||
#endif
|
||||
|
||||
#undef HEADER_CURL_MEMORY_H
|
||||
#undef HEADER_CURL_MEMDEBUG_H
|
||||
#else /* !WITHOUT_LIBCURL */
|
||||
#include <curl/mprintf.h>
|
||||
#define SNPRINTF curl_msnprintf
|
||||
#endif /* WITHOUT_LIBCURL */
|
||||
|
|
@ -32,35 +32,16 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifndef WITHOUT_LIBCURL
|
||||
#include <curl/mprintf.h>
|
||||
#define SNPRINTF curl_msnprintf
|
||||
#else
|
||||
/* when built for the test servers */
|
||||
|
||||
/* adjust for old MSVC */
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
#define SNPRINTF _snprintf
|
||||
#else
|
||||
#define SNPRINTF snprintf
|
||||
#endif
|
||||
#endif /* !WITHOUT_LIBCURL */
|
||||
|
||||
#include "winapi.h"
|
||||
#include "snprintf.h"
|
||||
#include "strerr.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "../curl_memory.h"
|
||||
#include "../memdebug.h"
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
/* This is a helper function for curlx_strerror that converts Winsock error
|
||||
* codes (WSAGetLastError) to error messages.
|
||||
* Returns NULL if no error message was found for error code.
|
||||
*/
|
||||
static const char *
|
||||
get_winsock_error(int err, char *buf, size_t len)
|
||||
static const char *get_winsock_error(int err, char *buf, size_t len)
|
||||
{
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
const char *p;
|
||||
|
|
@ -287,20 +268,12 @@ const char *curlx_strerror(int err, char *buf, size_t buflen)
|
|||
*buf = '\0';
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef UNDER_CE
|
||||
/* 'sys_nerr' is the maximum errno number, it is not widely portable */
|
||||
if(err >= 0 && err < sys_nerr)
|
||||
SNPRINTF(buf, buflen, "%s", sys_errlist[err]);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(
|
||||
if((!strerror_s(buf, buflen, err) || !strcmp(buf, "Unknown error")) &&
|
||||
#ifdef USE_WINSOCK
|
||||
!get_winsock_error(err, buf, buflen) &&
|
||||
!get_winsock_error(err, buf, buflen) &&
|
||||
#endif
|
||||
!curlx_get_winapi_error((DWORD)err, buf, buflen))
|
||||
SNPRINTF(buf, buflen, "Unknown error %d (%#x)", err, err);
|
||||
}
|
||||
!curlx_get_winapi_error((DWORD)err, buf, buflen))
|
||||
SNPRINTF(buf, buflen, "Unknown error %d (%#x)", err, err);
|
||||
#else /* !_WIN32 */
|
||||
|
||||
#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
|
||||
|
|
@ -350,7 +323,7 @@ const char *curlx_strerror(int err, char *buf, size_t buflen)
|
|||
*p = '\0';
|
||||
|
||||
if(errno != old_errno)
|
||||
CURL_SETERRNO(old_errno);
|
||||
errno = old_errno;
|
||||
|
||||
#ifdef _WIN32
|
||||
if(old_win_err != GetLastError())
|
||||
|
|
|
|||
|
|
@ -24,10 +24,6 @@
|
|||
|
||||
#include "strparse.h"
|
||||
|
||||
#ifndef WITHOUT_LIBCURL
|
||||
#include <curl/curl.h> /* for curl_strnequal() */
|
||||
#endif
|
||||
|
||||
void curlx_str_init(struct Curl_str *out)
|
||||
{
|
||||
out->str = NULL;
|
||||
|
|
@ -66,8 +62,7 @@ int curlx_str_until(const char **linep, struct Curl_str *out,
|
|||
|
||||
/* Get a word until the first space or end of string. At least one byte long.
|
||||
return non-zero on error */
|
||||
int curlx_str_word(const char **linep, struct Curl_str *out,
|
||||
const size_t max)
|
||||
int curlx_str_word(const char **linep, struct Curl_str *out, const size_t max)
|
||||
{
|
||||
return curlx_str_until(linep, out, max, ' ');
|
||||
}
|
||||
|
|
@ -95,7 +90,6 @@ int curlx_str_untilnl(const char **linep, struct Curl_str *out,
|
|||
return STRE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Get a "quoted" word. No escaping possible.
|
||||
return non-zero on error */
|
||||
int curlx_str_quotedword(const char **linep, struct Curl_str *out,
|
||||
|
|
@ -141,8 +135,8 @@ int curlx_str_singlespace(const char **linep)
|
|||
}
|
||||
|
||||
/* given an ASCII character and max ascii, return TRUE if valid */
|
||||
#define valid_digit(x,m) \
|
||||
(((x) >= '0') && ((x) <= m) && Curl_hexasciitable[(x)-'0'])
|
||||
#define valid_digit(x, m) \
|
||||
(((x) >= '0') && ((x) <= m) && Curl_hexasciitable[(x) - '0'])
|
||||
|
||||
/* We use 16 for the zero index (and the necessary bitwise AND in the loop)
|
||||
to be able to have a non-zero value there to make valid_digit() able to
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ struct Curl_str {
|
|||
void curlx_str_init(struct Curl_str *out);
|
||||
void curlx_str_assign(struct Curl_str *out, const char *str, size_t len);
|
||||
|
||||
#define curlx_str(x) ((x)->str)
|
||||
#define curlx_str(x) ((x)->str)
|
||||
#define curlx_strlen(x) ((x)->len)
|
||||
|
||||
/* Get a word until the first space
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
|
||||
#include "timediff.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* Converts number of milliseconds into a timeval structure.
|
||||
*
|
||||
|
|
@ -84,5 +82,5 @@ struct timeval *curlx_mstotv(struct timeval *tv, timediff_t ms)
|
|||
*/
|
||||
timediff_t curlx_tvtoms(struct timeval *tv)
|
||||
{
|
||||
return (tv->tv_sec*1000) + (timediff_t)(tv->tv_usec/1000);
|
||||
return (tv->tv_sec * 1000) + (timediff_t)(tv->tv_usec / 1000);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "version_win32.h"
|
||||
#include "../system_win32.h"
|
||||
|
||||
|
|
@ -47,9 +46,8 @@ void curlx_now_init(void)
|
|||
}
|
||||
|
||||
/* In case of bug fix this function has a counterpart in tool_util.c */
|
||||
struct curltime curlx_now(void)
|
||||
void curlx_pnow(struct curltime *pnow)
|
||||
{
|
||||
struct curltime now;
|
||||
bool isVistaOrGreater;
|
||||
isVistaOrGreater = Curl_isVistaOrGreater;
|
||||
if(isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
|
||||
|
|
@ -58,8 +56,8 @@ struct curltime curlx_now(void)
|
|||
freq = Curl_freq;
|
||||
DEBUGASSERT(freq.QuadPart);
|
||||
QueryPerformanceCounter(&count);
|
||||
now.tv_sec = (time_t)(count.QuadPart / freq.QuadPart);
|
||||
now.tv_usec = (int)((count.QuadPart % freq.QuadPart) * 1000000 /
|
||||
pnow->tv_sec = (time_t)(count.QuadPart / freq.QuadPart);
|
||||
pnow->tv_usec = (int)((count.QuadPart % freq.QuadPart) * 1000000 /
|
||||
freq.QuadPart);
|
||||
}
|
||||
else {
|
||||
|
|
@ -73,16 +71,15 @@ struct curltime curlx_now(void)
|
|||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
now.tv_sec = (time_t)(milliseconds / 1000);
|
||||
now.tv_usec = (int)((milliseconds % 1000) * 1000);
|
||||
pnow->tv_sec = (time_t)(milliseconds / 1000);
|
||||
pnow->tv_usec = (int)((milliseconds % 1000) * 1000);
|
||||
}
|
||||
return now;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) || \
|
||||
#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) || \
|
||||
defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
|
||||
|
||||
struct curltime curlx_now(void)
|
||||
void curlx_pnow(struct curltime *pnow)
|
||||
{
|
||||
/*
|
||||
** clock_gettime() is granted to be increased monotonically when the
|
||||
|
|
@ -91,10 +88,6 @@ struct curltime curlx_now(void)
|
|||
** in any case the time starting point does not change once that the
|
||||
** system has started up.
|
||||
*/
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval now;
|
||||
#endif
|
||||
struct curltime cnow;
|
||||
struct timespec tsnow;
|
||||
|
||||
/*
|
||||
|
|
@ -103,7 +96,7 @@ struct curltime curlx_now(void)
|
|||
** called on unsupported OS version.
|
||||
*/
|
||||
#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
|
||||
(HAVE_BUILTIN_AVAILABLE == 1)
|
||||
(HAVE_BUILTIN_AVAILABLE == 1)
|
||||
bool have_clock_gettime = FALSE;
|
||||
if(__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *))
|
||||
have_clock_gettime = TRUE;
|
||||
|
|
@ -111,25 +104,25 @@ struct curltime curlx_now(void)
|
|||
|
||||
#ifdef HAVE_CLOCK_GETTIME_MONOTONIC_RAW
|
||||
if(
|
||||
#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
|
||||
(HAVE_BUILTIN_AVAILABLE == 1)
|
||||
#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
|
||||
(HAVE_BUILTIN_AVAILABLE == 1)
|
||||
have_clock_gettime &&
|
||||
#endif
|
||||
(clock_gettime(CLOCK_MONOTONIC_RAW, &tsnow) == 0)) {
|
||||
cnow.tv_sec = tsnow.tv_sec;
|
||||
cnow.tv_usec = (int)(tsnow.tv_nsec / 1000);
|
||||
pnow->tv_sec = tsnow.tv_sec;
|
||||
pnow->tv_usec = (int)(tsnow.tv_nsec / 1000);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if(
|
||||
#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
|
||||
(HAVE_BUILTIN_AVAILABLE == 1)
|
||||
(HAVE_BUILTIN_AVAILABLE == 1)
|
||||
have_clock_gettime &&
|
||||
#endif
|
||||
(clock_gettime(CLOCK_MONOTONIC, &tsnow) == 0)) {
|
||||
cnow.tv_sec = tsnow.tv_sec;
|
||||
cnow.tv_usec = (int)(tsnow.tv_nsec / 1000);
|
||||
pnow->tv_sec = tsnow.tv_sec;
|
||||
pnow->tv_usec = (int)(tsnow.tv_nsec / 1000);
|
||||
}
|
||||
/*
|
||||
** Even when the configure process has truly detected monotonic clock
|
||||
|
|
@ -138,17 +131,17 @@ struct curltime curlx_now(void)
|
|||
*/
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
else {
|
||||
struct timeval now;
|
||||
(void)gettimeofday(&now, NULL);
|
||||
cnow.tv_sec = now.tv_sec;
|
||||
cnow.tv_usec = (int)now.tv_usec;
|
||||
pnow->tv_sec = now.tv_sec;
|
||||
pnow->tv_usec = (int)now.tv_usec;
|
||||
}
|
||||
#else
|
||||
else {
|
||||
cnow.tv_sec = time(NULL);
|
||||
cnow.tv_usec = 0;
|
||||
pnow->tv_sec = time(NULL);
|
||||
pnow->tv_usec = 0;
|
||||
}
|
||||
#endif
|
||||
return cnow;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_MACH_ABSOLUTE_TIME)
|
||||
|
|
@ -156,7 +149,7 @@ struct curltime curlx_now(void)
|
|||
#include <stdint.h>
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
struct curltime curlx_now(void)
|
||||
void curlx_pnow(struct curltime *pnow)
|
||||
{
|
||||
/*
|
||||
** Monotonic timer on macOS is provided by mach_absolute_time(), which
|
||||
|
|
@ -165,7 +158,6 @@ struct curltime curlx_now(void)
|
|||
** mach_timebase_info().
|
||||
*/
|
||||
static mach_timebase_info_data_t timebase;
|
||||
struct curltime cnow;
|
||||
uint64_t usecs;
|
||||
|
||||
if(timebase.denom == 0)
|
||||
|
|
@ -176,15 +168,13 @@ struct curltime curlx_now(void)
|
|||
usecs /= timebase.denom;
|
||||
usecs /= 1000;
|
||||
|
||||
cnow.tv_sec = usecs / 1000000;
|
||||
cnow.tv_usec = (int)(usecs % 1000000);
|
||||
|
||||
return cnow;
|
||||
pnow->tv_sec = usecs / 1000000;
|
||||
pnow->tv_usec = (int)(usecs % 1000000);
|
||||
}
|
||||
|
||||
#elif defined(HAVE_GETTIMEOFDAY)
|
||||
|
||||
struct curltime curlx_now(void)
|
||||
void curlx_pnow(struct curltime *pnow)
|
||||
{
|
||||
/*
|
||||
** gettimeofday() is not granted to be increased monotonically, due to
|
||||
|
|
@ -192,68 +182,121 @@ struct curltime curlx_now(void)
|
|||
** forward or backward in time.
|
||||
*/
|
||||
struct timeval now;
|
||||
struct curltime ret;
|
||||
(void)gettimeofday(&now, NULL);
|
||||
ret.tv_sec = now.tv_sec;
|
||||
ret.tv_usec = (int)now.tv_usec;
|
||||
return ret;
|
||||
pnow->tv_sec = now.tv_sec;
|
||||
pnow->tv_usec = (int)now.tv_usec;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct curltime curlx_now(void)
|
||||
void curlx_pnow(struct curltime *pnow)
|
||||
{
|
||||
/*
|
||||
** time() returns the value of time in seconds since the Epoch.
|
||||
*/
|
||||
struct curltime now;
|
||||
now.tv_sec = time(NULL);
|
||||
now.tv_usec = 0;
|
||||
return now;
|
||||
pnow->tv_sec = time(NULL);
|
||||
pnow->tv_usec = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct curltime curlx_now(void)
|
||||
{
|
||||
struct curltime now;
|
||||
curlx_pnow(&now);
|
||||
return now;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns: time difference in number of milliseconds. For too large diffs it
|
||||
* returns max value.
|
||||
*
|
||||
* @unittest: 1323
|
||||
*/
|
||||
timediff_t curlx_timediff(struct curltime newer, struct curltime older)
|
||||
timediff_t curlx_ptimediff_ms(const struct curltime *newer,
|
||||
const struct curltime *older)
|
||||
{
|
||||
timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
|
||||
if(diff >= (TIMEDIFF_T_MAX/1000))
|
||||
timediff_t diff = (timediff_t)newer->tv_sec - older->tv_sec;
|
||||
if(diff >= (TIMEDIFF_T_MAX / 1000))
|
||||
return TIMEDIFF_T_MAX;
|
||||
else if(diff <= (TIMEDIFF_T_MIN/1000))
|
||||
else if(diff <= (TIMEDIFF_T_MIN / 1000))
|
||||
return TIMEDIFF_T_MIN;
|
||||
return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000;
|
||||
return diff * 1000 + (newer->tv_usec - older->tv_usec) / 1000;
|
||||
}
|
||||
|
||||
|
||||
timediff_t curlx_timediff_ms(struct curltime newer, struct curltime older)
|
||||
{
|
||||
return curlx_ptimediff_ms(&newer, &older);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns: time difference in number of milliseconds, rounded up.
|
||||
* For too large diffs it returns max value.
|
||||
*/
|
||||
timediff_t curlx_timediff_ceil(struct curltime newer, struct curltime older)
|
||||
timediff_t curlx_timediff_ceil_ms(struct curltime newer,
|
||||
struct curltime older)
|
||||
{
|
||||
timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
|
||||
if(diff >= (TIMEDIFF_T_MAX/1000))
|
||||
timediff_t diff = (timediff_t)newer.tv_sec - older.tv_sec;
|
||||
if(diff >= (TIMEDIFF_T_MAX / 1000))
|
||||
return TIMEDIFF_T_MAX;
|
||||
else if(diff <= (TIMEDIFF_T_MIN/1000))
|
||||
else if(diff <= (TIMEDIFF_T_MIN / 1000))
|
||||
return TIMEDIFF_T_MIN;
|
||||
return diff * 1000 + (newer.tv_usec - older.tv_usec + 999)/1000;
|
||||
return diff * 1000 + (newer.tv_usec - older.tv_usec + 999) / 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns: time difference in number of microseconds. For too large diffs it
|
||||
* returns max value.
|
||||
*/
|
||||
timediff_t curlx_ptimediff_us(const struct curltime *newer,
|
||||
const struct curltime *older)
|
||||
{
|
||||
timediff_t diff = (timediff_t)newer->tv_sec - older->tv_sec;
|
||||
if(diff >= (TIMEDIFF_T_MAX / 1000000))
|
||||
return TIMEDIFF_T_MAX;
|
||||
else if(diff <= (TIMEDIFF_T_MIN / 1000000))
|
||||
return TIMEDIFF_T_MIN;
|
||||
return diff * 1000000 + newer->tv_usec - older->tv_usec;
|
||||
}
|
||||
|
||||
timediff_t curlx_timediff_us(struct curltime newer, struct curltime older)
|
||||
{
|
||||
timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
|
||||
if(diff >= (TIMEDIFF_T_MAX/1000000))
|
||||
return TIMEDIFF_T_MAX;
|
||||
else if(diff <= (TIMEDIFF_T_MIN/1000000))
|
||||
return TIMEDIFF_T_MIN;
|
||||
return diff * 1000000 + newer.tv_usec-older.tv_usec;
|
||||
return curlx_ptimediff_us(&newer, &older);
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR <= 3)
|
||||
#include <sec_api/time_s.h> /* for _gmtime32_s(), _gmtime64_s() */
|
||||
#ifdef _USE_32BIT_TIME_T
|
||||
#define gmtime_s _gmtime32_s
|
||||
#else
|
||||
#define gmtime_s _gmtime64_s
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* curlx_gmtime() is a gmtime() replacement for portability. Do not use
|
||||
* the gmtime_s(), gmtime_r() or gmtime() functions anywhere else but here.
|
||||
*/
|
||||
CURLcode curlx_gmtime(time_t intime, struct tm *store)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if(gmtime_s(store, &intime)) /* thread-safe */
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
#elif defined(HAVE_GMTIME_R)
|
||||
const struct tm *tm;
|
||||
tm = gmtime_r(&intime, store); /* thread-safe */
|
||||
if(!tm)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
#else
|
||||
const struct tm *tm;
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
tm = gmtime(&intime); /* not thread-safe */
|
||||
if(tm)
|
||||
*store = *tm; /* copy the pointed struct to the local copy */
|
||||
else
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ void curlx_now_init(void);
|
|||
#endif
|
||||
|
||||
struct curltime curlx_now(void);
|
||||
void curlx_pnow(struct curltime *pnow);
|
||||
|
||||
/*
|
||||
* Make sure that the first argument (newer) is the more recent time and older
|
||||
|
|
@ -46,7 +47,9 @@ struct curltime curlx_now(void);
|
|||
*
|
||||
* Returns: the time difference in number of milliseconds.
|
||||
*/
|
||||
timediff_t curlx_timediff(struct curltime newer, struct curltime older);
|
||||
timediff_t curlx_timediff_ms(struct curltime newer, struct curltime older);
|
||||
timediff_t curlx_ptimediff_ms(const struct curltime *newer,
|
||||
const struct curltime *older);
|
||||
|
||||
/*
|
||||
* Make sure that the first argument (newer) is the more recent time and older
|
||||
|
|
@ -54,7 +57,8 @@ timediff_t curlx_timediff(struct curltime newer, struct curltime older);
|
|||
*
|
||||
* Returns: the time difference in number of milliseconds, rounded up.
|
||||
*/
|
||||
timediff_t curlx_timediff_ceil(struct curltime newer, struct curltime older);
|
||||
timediff_t curlx_timediff_ceil_ms(struct curltime newer,
|
||||
struct curltime older);
|
||||
|
||||
/*
|
||||
* Make sure that the first argument (newer) is the more recent time and older
|
||||
|
|
@ -63,5 +67,9 @@ timediff_t curlx_timediff_ceil(struct curltime newer, struct curltime older);
|
|||
* Returns: the time difference in number of microseconds.
|
||||
*/
|
||||
timediff_t curlx_timediff_us(struct curltime newer, struct curltime older);
|
||||
timediff_t curlx_ptimediff_us(const struct curltime *newer,
|
||||
const struct curltime *older);
|
||||
|
||||
CURLcode curlx_gmtime(time_t intime, struct tm *store);
|
||||
|
||||
#endif /* HEADER_CURL_TIMEVAL_H */
|
||||
|
|
|
|||
|
|
@ -26,14 +26,9 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "version_win32.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "../curl_memory.h"
|
||||
#include "../memdebug.h"
|
||||
|
||||
/* This Unicode version struct works for VerifyVersionInfoW (OSVERSIONINFOEXW)
|
||||
and RtlVerifyVersionInfo (RTLOSVERSIONINFOEXW) */
|
||||
struct OUR_OSVERSIONINFOEXW {
|
||||
|
|
@ -111,12 +106,6 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
|
|||
/* we are always running on PLATFORM_WINNT */
|
||||
matched = FALSE;
|
||||
}
|
||||
#elif defined(UNDER_CE)
|
||||
(void)majorVersion;
|
||||
(void)minorVersion;
|
||||
(void)buildVersion;
|
||||
(void)platform;
|
||||
(void)condition;
|
||||
#else
|
||||
ULONGLONG cm = 0;
|
||||
struct OUR_OSVERSIONINFOEXW osver;
|
||||
|
|
@ -139,7 +128,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
|
|||
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
|
||||
#endif
|
||||
pRtlVerifyVersionInfo = CURLX_FUNCTION_CAST(RTLVERIFYVERSIONINFO_FN,
|
||||
GetProcAddress(GetModuleHandleA("ntdll"), "RtlVerifyVersionInfo"));
|
||||
GetProcAddress(GetModuleHandle(TEXT("ntdll")), "RtlVerifyVersionInfo"));
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
#error "We cannot compile without select() support."
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#elif defined(HAVE_UNISTD_H)
|
||||
|
|
@ -74,7 +72,7 @@ int curlx_wait_ms(timediff_t timeout_ms)
|
|||
/* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */
|
||||
#if TIMEDIFF_T_MAX >= ULONG_MAX
|
||||
if(timeout_ms >= ULONG_MAX)
|
||||
timeout_ms = ULONG_MAX-1;
|
||||
timeout_ms = ULONG_MAX - 1;
|
||||
/* do not use ULONG_MAX, because that is equal to INFINITE */
|
||||
#endif
|
||||
Sleep((DWORD)timeout_ms);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue