← Commit list

47f5b1a37f

Stefan Eissing
Stefan Eissing
2023-10-25
SUCCESS Duration: 164s

Subject

lib: introduce struct easy_poll_set for poll information

Binary

Download Binary (846 KB)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

$ git checkout -f 47f5b1a37f3e8055dfea446236c05478087858dc
Previous HEAD position was 6ec70a9dd3 autotools: update references to deleted `crypt-auth` option
HEAD is now at 47f5b1a37f lib: introduce struct easy_poll_set for poll information

$ git clean -fdx
Removing Makefile
Removing Makefile.in
Removing aclocal.m4
Removing autom4te.cache/
Removing compile
Removing config.guess
Removing config.log
Removing config.status
Removing config.sub
Removing configure
Removing curl-config
Removing depcomp
Removing docs/Makefile
Removing docs/Makefile.in
Removing docs/cmdline-opts/Makefile
Removing docs/cmdline-opts/Makefile.in
Removing docs/curl.1
Removing docs/examples/.deps/
Removing docs/examples/Makefile
Removing docs/examples/Makefile.in
Removing docs/libcurl/Makefile
Removing docs/libcurl/Makefile.in
Removing docs/libcurl/opts/Makefile
Removing docs/libcurl/opts/Makefile.in
Removing include/Makefile
Removing include/Makefile.in
Removing include/curl/Makefile
Removing include/curl/Makefile.in
Removing install-sh
Removing lib/.deps/
Removing lib/.dirstamp
Removing lib/.libs/
Removing lib/Makefile
Removing lib/Makefile.in
Removing lib/base64.o
Removing lib/curl_config.h
Removing lib/curl_config.h.in
Removing lib/curl_multibyte.o
Removing lib/dynbuf.o
Removing lib/libcurl.la
Removing lib/libcurl.plist
Removing lib/libcurl.vers
Removing lib/libcurl_la-altsvc.lo
Removing lib/libcurl_la-altsvc.o
Removing lib/libcurl_la-amigaos.lo
Removing lib/libcurl_la-amigaos.o
Removing lib/libcurl_la-asyn-ares.lo
Removing lib/libcurl_la-asyn-ares.o
Removing lib/libcurl_la-asyn-thread.lo
Removing lib/libcurl_la-asyn-thread.o
Removing lib/libcurl_la-base64.lo
Removing lib/libcurl_la-base64.o
Removing lib/libcurl_la-bufq.lo
Removing lib/libcurl_la-bufq.o
Removing lib/libcurl_la-bufref.lo
Removing lib/libcurl_la-bufref.o
Removing lib/libcurl_la-c-hyper.lo
Removing lib/libcurl_la-c-hyper.o
Removing lib/libcurl_la-cf-h1-proxy.lo
Removing lib/libcurl_la-cf-h1-proxy.o
Removing lib/libcurl_la-cf-h2-proxy.lo
Removing lib/libcurl_la-cf-h2-proxy.o
Removing lib/libcurl_la-cf-haproxy.lo
Removing lib/libcurl_la-cf-haproxy.o
Removing lib/libcurl_la-cf-https-connect.lo
Removing lib/libcurl_la-cf-https-connect.o
Removing lib/libcurl_la-cf-socket.lo
Removing lib/libcurl_la-cf-socket.o
Removing lib/libcurl_la-cfilters.lo
Removing lib/libcurl_la-cfilters.o
Removing lib/libcurl_la-conncache.lo
Removing lib/libcurl_la-conncache.o
Removing lib/libcurl_la-connect.lo
Removing lib/libcurl_la-connect.o
Removing lib/libcurl_la-content_encoding.lo
Removing lib/libcurl_la-content_encoding.o
Removing lib/libcurl_la-cookie.lo
Removing lib/libcurl_la-cookie.o
Removing lib/libcurl_la-curl_addrinfo.lo
Removing lib/libcurl_la-curl_addrinfo.o
Removing lib/libcurl_la-curl_des.lo
Removing lib/libcurl_la-curl_des.o
Removing lib/libcurl_la-curl_endian.lo
Removing lib/libcurl_la-curl_endian.o
Removing lib/libcurl_la-curl_fnmatch.lo
Removing lib/libcurl_la-curl_fnmatch.o
Removing lib/libcurl_la-curl_get_line.lo
Removing lib/libcurl_la-curl_get_line.o
Removing lib/libcurl_la-curl_gethostname.lo
Removing lib/libcurl_la-curl_gethostname.o
Removing lib/libcurl_la-curl_gssapi.lo
Removing lib/libcurl_la-curl_gssapi.o
Removing lib/libcurl_la-curl_memrchr.lo
Removing lib/libcurl_la-curl_memrchr.o
Removing lib/libcurl_la-curl_multibyte.lo
Removing lib/libcurl_la-curl_multibyte.o
Removing lib/libcurl_la-curl_ntlm_core.lo
Removing lib/libcurl_la-curl_ntlm_core.o
Removing lib/libcurl_la-curl_ntlm_wb.lo
Removing lib/libcurl_la-curl_ntlm_wb.o
Removing lib/libcurl_la-curl_path.lo
Removing lib/libcurl_la-curl_path.o
Removing lib/libcurl_la-curl_range.lo
Removing lib/libcurl_la-curl_range.o
Removing lib/libcurl_la-curl_rtmp.lo
Removing lib/libcurl_la-curl_rtmp.o
Removing lib/libcurl_la-curl_sasl.lo
Removing lib/libcurl_la-curl_sasl.o
Removing lib/libcurl_la-curl_sspi.lo
Removing lib/libcurl_la-curl_sspi.o
Removing lib/libcurl_la-curl_threads.lo
Removing lib/libcurl_la-curl_threads.o
Removing lib/libcurl_la-curl_trc.lo
Removing lib/libcurl_la-curl_trc.o
Removing lib/libcurl_la-dict.lo
Removing lib/libcurl_la-dict.o
Removing lib/libcurl_la-doh.lo
Removing lib/libcurl_la-doh.o
Removing lib/libcurl_la-dynbuf.lo
Removing lib/libcurl_la-dynbuf.o
Removing lib/libcurl_la-dynhds.lo
Removing lib/libcurl_la-dynhds.o
Removing lib/libcurl_la-easy.lo
Removing lib/libcurl_la-easy.o
Removing lib/libcurl_la-easygetopt.lo
Removing lib/libcurl_la-easygetopt.o
Removing lib/libcurl_la-easyoptions.lo
Removing lib/libcurl_la-easyoptions.o
Removing lib/libcurl_la-escape.lo
Removing lib/libcurl_la-escape.o
Removing lib/libcurl_la-file.lo
Removing lib/libcurl_la-file.o
Removing lib/libcurl_la-fileinfo.lo
Removing lib/libcurl_la-fileinfo.o
Removing lib/libcurl_la-fopen.lo
Removing lib/libcurl_la-fopen.o
Removing lib/libcurl_la-formdata.lo
Removing lib/libcurl_la-formdata.o
Removing lib/libcurl_la-ftp.lo
Removing lib/libcurl_la-ftp.o
Removing lib/libcurl_la-ftplistparser.lo
Removing lib/libcurl_la-ftplistparser.o
Removing lib/libcurl_la-getenv.lo
Removing lib/libcurl_la-getenv.o
Removing lib/libcurl_la-getinfo.lo
Removing lib/libcurl_la-getinfo.o
Removing lib/libcurl_la-gopher.lo
Removing lib/libcurl_la-gopher.o
Removing lib/libcurl_la-hash.lo
Removing lib/libcurl_la-hash.o
Removing lib/libcurl_la-headers.lo
Removing lib/libcurl_la-headers.o
Removing lib/libcurl_la-hmac.lo
Removing lib/libcurl_la-hmac.o
Removing lib/libcurl_la-hostasyn.lo
Removing lib/libcurl_la-hostasyn.o
Removing lib/libcurl_la-hostip.lo
Removing lib/libcurl_la-hostip.o
Removing lib/libcurl_la-hostip4.lo
Removing lib/libcurl_la-hostip4.o
Removing lib/libcurl_la-hostip6.lo
Removing lib/libcurl_la-hostip6.o
Removing lib/libcurl_la-hostsyn.lo
Removing lib/libcurl_la-hostsyn.o
Removing lib/libcurl_la-hsts.lo
Removing lib/libcurl_la-hsts.o
Removing lib/libcurl_la-http.lo
Removing lib/libcurl_la-http.o
Removing lib/libcurl_la-http1.lo
Removing lib/libcurl_la-http1.o
Removing lib/libcurl_la-http2.lo
Removing lib/libcurl_la-http2.o
Removing lib/libcurl_la-http_aws_sigv4.lo
Removing lib/libcurl_la-http_aws_sigv4.o
Removing lib/libcurl_la-http_chunks.lo
Removing lib/libcurl_la-http_chunks.o
Removing lib/libcurl_la-http_digest.lo
Removing lib/libcurl_la-http_digest.o
Removing lib/libcurl_la-http_negotiate.lo
Removing lib/libcurl_la-http_negotiate.o
Removing lib/libcurl_la-http_ntlm.lo
Removing lib/libcurl_la-http_ntlm.o
Removing lib/libcurl_la-http_proxy.lo
Removing lib/libcurl_la-http_proxy.o
Removing lib/libcurl_la-idn.lo
Removing lib/libcurl_la-idn.o
Removing lib/libcurl_la-if2ip.lo
Removing lib/libcurl_la-if2ip.o
Removing lib/libcurl_la-imap.lo
Removing lib/libcurl_la-imap.o
Removing lib/libcurl_la-inet_ntop.lo
Removing lib/libcurl_la-inet_ntop.o
Removing lib/libcurl_la-inet_pton.lo
Removing lib/libcurl_la-inet_pton.o
Removing lib/libcurl_la-krb5.lo
Removing lib/libcurl_la-krb5.o
Removing lib/libcurl_la-ldap.lo
Removing lib/libcurl_la-ldap.o
Removing lib/libcurl_la-llist.lo
Removing lib/libcurl_la-llist.o
Removing lib/libcurl_la-macos.lo
Removing lib/libcurl_la-macos.o
Removing lib/libcurl_la-md4.lo
Removing lib/libcurl_la-md4.o
Removing lib/libcurl_la-md5.lo
Removing lib/libcurl_la-md5.o
Removing lib/libcurl_la-memdebug.lo
Removing lib/libcurl_la-memdebug.o
Removing lib/libcurl_la-mime.lo
Removing lib/libcurl_la-mime.o
Removing lib/libcurl_la-mprintf.lo
Removing lib/libcurl_la-mprintf.o
Removing lib/libcurl_la-mqtt.lo
Removing lib/libcurl_la-mqtt.o
Removing lib/libcurl_la-multi.lo
Removing lib/libcurl_la-multi.o
Removing lib/libcurl_la-netrc.lo
Removing lib/libcurl_la-netrc.o
Removing lib/libcurl_la-nonblock.lo
Removing lib/libcurl_la-nonblock.o
Removing lib/libcurl_la-noproxy.lo
Removing lib/libcurl_la-noproxy.o
Removing lib/libcurl_la-openldap.lo
Removing lib/libcurl_la-openldap.o
Removing lib/libcurl_la-parsedate.lo
Removing lib/libcurl_la-parsedate.o
Removing lib/libcurl_la-pingpong.lo
Removing lib/libcurl_la-pingpong.o
Removing lib/libcurl_la-pop3.lo
Removing lib/libcurl_la-pop3.o
Removing lib/libcurl_la-progress.lo
Removing lib/libcurl_la-progress.o
Removing lib/libcurl_la-psl.lo
Removing lib/libcurl_la-psl.o
Removing lib/libcurl_la-rand.lo
Removing lib/libcurl_la-rand.o
Removing lib/libcurl_la-rename.lo
Removing lib/libcurl_la-rename.o
Removing lib/libcurl_la-rtsp.lo
Removing lib/libcurl_la-rtsp.o
Removing lib/libcurl_la-select.lo
Removing lib/libcurl_la-select.o
Removing lib/libcurl_la-sendf.lo
Removing lib/libcurl_la-sendf.o
Removing lib/libcurl_la-setopt.lo
Removing lib/libcurl_la-setopt.o
Removing lib/libcurl_la-sha256.lo
Removing lib/libcurl_la-sha256.o
Removing lib/libcurl_la-share.lo
Removing lib/libcurl_la-share.o
Removing lib/libcurl_la-slist.lo
Removing lib/libcurl_la-slist.o
Removing lib/libcurl_la-smb.lo
Removing lib/libcurl_la-smb.o
Removing lib/libcurl_la-smtp.lo
Removing lib/libcurl_la-smtp.o
Removing lib/libcurl_la-socketpair.lo
Removing lib/libcurl_la-socketpair.o
Removing lib/libcurl_la-socks.lo
Removing lib/libcurl_la-socks.o
Removing lib/libcurl_la-socks_gssapi.lo
Removing lib/libcurl_la-socks_gssapi.o
Removing lib/libcurl_la-socks_sspi.lo
Removing lib/libcurl_la-socks_sspi.o
Removing lib/libcurl_la-speedcheck.lo
Removing lib/libcurl_la-speedcheck.o
Removing lib/libcurl_la-splay.lo
Removing lib/libcurl_la-splay.o
Removing lib/libcurl_la-strcase.lo
Removing lib/libcurl_la-strcase.o
Removing lib/libcurl_la-strdup.lo
Removing lib/libcurl_la-strdup.o
Removing lib/libcurl_la-strerror.lo
Removing lib/libcurl_la-strerror.o
Removing lib/libcurl_la-strtok.lo
Removing lib/libcurl_la-strtok.o
Removing lib/libcurl_la-strtoofft.lo
Removing lib/libcurl_la-strtoofft.o
Removing lib/libcurl_la-system_win32.lo
Removing lib/libcurl_la-system_win32.o
Removing lib/libcurl_la-telnet.lo
Removing lib/libcurl_la-telnet.o
Removing lib/libcurl_la-tftp.lo
Removing lib/libcurl_la-tftp.o
Removing lib/libcurl_la-timediff.lo
Removing lib/libcurl_la-timediff.o
Removing lib/libcurl_la-timeval.lo
Removing lib/libcurl_la-timeval.o
Removing lib/libcurl_la-transfer.lo
Removing lib/libcurl_la-transfer.o
Removing lib/libcurl_la-url.lo
Removing lib/libcurl_la-url.o
Removing lib/libcurl_la-urlapi.lo
Removing lib/libcurl_la-urlapi.o
Removing lib/libcurl_la-version.lo
Removing lib/libcurl_la-version.o
Removing lib/libcurl_la-version_win32.lo
Removing lib/libcurl_la-version_win32.o
Removing lib/libcurl_la-warnless.lo
Removing lib/libcurl_la-warnless.o
Removing lib/libcurl_la-ws.lo
Removing lib/libcurl_la-ws.o
Removing lib/nonblock.o
Removing lib/stamp-h1
Removing lib/strtoofft.o
Removing lib/timediff.o
Removing lib/vauth/.deps/
Removing lib/vauth/.dirstamp
Removing lib/vauth/libcurl_la-cleartext.lo
Removing lib/vauth/libcurl_la-cleartext.o
Removing lib/vauth/libcurl_la-cram.lo
Removing lib/vauth/libcurl_la-cram.o
Removing lib/vauth/libcurl_la-digest.lo
Removing lib/vauth/libcurl_la-digest.o
Removing lib/vauth/libcurl_la-digest_sspi.lo
Removing lib/vauth/libcurl_la-digest_sspi.o
Removing lib/vauth/libcurl_la-gsasl.lo
Removing lib/vauth/libcurl_la-gsasl.o
Removing lib/vauth/libcurl_la-krb5_gssapi.lo
Removing lib/vauth/libcurl_la-krb5_gssapi.o
Removing lib/vauth/libcurl_la-krb5_sspi.lo
Removing lib/vauth/libcurl_la-krb5_sspi.o
Removing lib/vauth/libcurl_la-ntlm.lo
Removing lib/vauth/libcurl_la-ntlm.o
Removing lib/vauth/libcurl_la-ntlm_sspi.lo
Removing lib/vauth/libcurl_la-ntlm_sspi.o
Removing lib/vauth/libcurl_la-oauth2.lo
Removing lib/vauth/libcurl_la-oauth2.o
Removing lib/vauth/libcurl_la-spnego_gssapi.lo
Removing lib/vauth/libcurl_la-spnego_gssapi.o
Removing lib/vauth/libcurl_la-spnego_sspi.lo
Removing lib/vauth/libcurl_la-spnego_sspi.o
Removing lib/vauth/libcurl_la-vauth.lo
Removing lib/vauth/libcurl_la-vauth.o
Removing lib/version_win32.o
Removing lib/vquic/.deps/
Removing lib/vquic/.dirstamp
Removing lib/vquic/libcurl_la-curl_msh3.lo
Removing lib/vquic/libcurl_la-curl_msh3.o
Removing lib/vquic/libcurl_la-curl_ngtcp2.lo
Removing lib/vquic/libcurl_la-curl_ngtcp2.o
Removing lib/vquic/libcurl_la-curl_quiche.lo
Removing lib/vquic/libcurl_la-curl_quiche.o
Removing lib/vquic/libcurl_la-vquic.lo
Removing lib/vquic/libcurl_la-vquic.o
Removing lib/vssh/.deps/
Removing lib/vssh/.dirstamp
Removing lib/vssh/libcurl_la-libssh.lo
Removing lib/vssh/libcurl_la-libssh.o
Removing lib/vssh/libcurl_la-libssh2.lo
Removing lib/vssh/libcurl_la-libssh2.o
Removing lib/vssh/libcurl_la-wolfssh.lo
Removing lib/vssh/libcurl_la-wolfssh.o
Removing lib/vtls/.deps/
Removing lib/vtls/.dirstamp
Removing lib/vtls/libcurl_la-bearssl.lo
Removing lib/vtls/libcurl_la-bearssl.o
Removing lib/vtls/libcurl_la-gtls.lo
Removing lib/vtls/libcurl_la-gtls.o
Removing lib/vtls/libcurl_la-hostcheck.lo
Removing lib/vtls/libcurl_la-hostcheck.o
Removing lib/vtls/libcurl_la-keylog.lo
Removing lib/vtls/libcurl_la-keylog.o
Removing lib/vtls/libcurl_la-mbedtls.lo
Removing lib/vtls/libcurl_la-mbedtls.o
Removing lib/vtls/libcurl_la-mbedtls_threadlock.lo
Removing lib/vtls/libcurl_la-mbedtls_threadlock.o
Removing lib/vtls/libcurl_la-openssl.lo
Removing lib/vtls/libcurl_la-openssl.o
Removing lib/vtls/libcurl_la-rustls.lo
Removing lib/vtls/libcurl_la-rustls.o
Removing lib/vtls/libcurl_la-schannel.lo
Removing lib/vtls/libcurl_la-schannel.o
Removing lib/vtls/libcurl_la-schannel_verify.lo
Removing lib/vtls/libcurl_la-schannel_verify.o
Removing lib/vtls/libcurl_la-sectransp.lo
Removing lib/vtls/libcurl_la-sectransp.o
Removing lib/vtls/libcurl_la-vtls.lo
Removing lib/vtls/libcurl_la-vtls.o
Removing lib/vtls/libcurl_la-wolfssl.lo
Removing lib/vtls/libcurl_la-wolfssl.o
Removing lib/vtls/libcurl_la-x509asn1.lo
Removing lib/vtls/libcurl_la-x509asn1.o
Removing lib/warnless.o
Removing libcurl.pc
Removing libtool
Removing ltmain.sh
Removing m4/libtool.m4
Removing m4/ltoptions.m4
Removing m4/ltsugar.m4
Removing m4/ltversion.m4
Removing m4/lt~obsolete.m4
Removing missing
Removing packages/Makefile
Removing packages/Makefile.in
Removing packages/vms/Makefile
Removing packages/vms/Makefile.in
Removing scripts/Makefile
Removing scripts/Makefile.in
Removing src/.deps/
Removing src/.libs/
Removing src/Makefile
Removing src/Makefile.in
Removing src/curl
Removing src/slist_wc.o
Removing src/tool_binmode.o
Removing src/tool_bname.o
Removing src/tool_cb_dbg.o
Removing src/tool_cb_hdr.o
Removing src/tool_cb_prg.o
Removing src/tool_cb_rea.o
Removing src/tool_cb_see.o
Removing src/tool_cb_wrt.o
Removing src/tool_cfgable.o
Removing src/tool_dirhie.o
Removing src/tool_doswin.o
Removing src/tool_easysrc.o
Removing src/tool_filetime.o
Removing src/tool_findfile.o
Removing src/tool_formparse.o
Removing src/tool_getparam.o
Removing src/tool_getpass.o
Removing src/tool_help.o
Removing src/tool_helpers.o
Removing src/tool_hugehelp.c
Removing src/tool_hugehelp.o
Removing src/tool_libinfo.o
Removing src/tool_listhelp.o
Removing src/tool_main.o
Removing src/tool_msgs.o
Removing src/tool_operate.o
Removing src/tool_operhlp.o
Removing src/tool_paramhlp.o
Removing src/tool_parsecfg.o
Removing src/tool_progress.o
Removing src/tool_setopt.o
Removing src/tool_sleep.o
Removing src/tool_stderr.o
Removing src/tool_strdup.o
Removing src/tool_urlglob.o
Removing src/tool_util.o
Removing src/tool_vms.o
Removing src/tool_writeout.o
Removing src/tool_writeout_json.o
Removing src/tool_xattr.o
Removing src/var.o
Removing test-driver
Removing tests/Makefile
Removing tests/Makefile.in
Removing tests/certs/Makefile
Removing tests/certs/Makefile.in
Removing tests/certs/scripts/Makefile
Removing tests/certs/scripts/Makefile.in
Removing tests/config
Removing tests/configurehelp.pm
Removing tests/data/Makefile
Removing tests/data/Makefile.in
Removing tests/http/Makefile
Removing tests/http/Makefile.in
Removing tests/http/clients/.deps/
Removing tests/http/clients/Makefile
Removing tests/http/clients/Makefile.in
Removing tests/http/config.ini
Removing tests/libtest/.deps/
Removing tests/libtest/Makefile
Removing tests/libtest/Makefile.in
Removing tests/server/.deps/
Removing tests/server/Makefile
Removing tests/server/Makefile.in
Removing tests/unit/.deps/
Removing tests/unit/Makefile
Removing tests/unit/Makefile.in

$ autoreconf -fi
libtoolize: putting auxiliary files in '.'.
libtoolize: copying file './ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: copying file 'm4/libtool.m4'
libtoolize: copying file 'm4/ltoptions.m4'
libtoolize: copying file 'm4/ltsugar.m4'
libtoolize: copying file 'm4/ltversion.m4'
libtoolize: copying file 'm4/lt~obsolete.m4'
libtoolize: Remember to add 'LT_INIT' to configure.ac.
configure.ac:123: installing './compile'
configure.ac:424: installing './config.guess'
configure.ac:424: installing './config.sub'
configure.ac:123: installing './install-sh'
configure.ac:129: installing './missing'
docs/examples/Makefile.am: installing './depcomp'
parallel-tests: installing './test-driver'

$ bash -c find . -name config.guess -exec cp /usr/share/misc/config.guess {} \;

$ bash -c find . -name config.sub -exec cp /usr/share/misc/config.sub {} \;

$ chmod +x configure

$ ./configure --disable-shared --without-ssl --disable-docs
checking whether to enable maintainer-specific portions of Makefiles... no
checking whether make supports nested variables... yes
checking whether to enable debug build options... no
checking whether to enable compiler optimizer... (assumed) yes
checking whether to enable strict compiler warnings... no
checking whether to enable compiler warnings as errors... no
checking whether to enable curl debug memory tracking... no
checking whether to enable hiding of library internal symbols... yes
checking whether to enable c-ares for DNS lookups... no
checking whether to disable dependency on -lrt... (assumed no)
checking whether to enable ECH support... no
checking for path separator... :
checking for sed... /usr/bin/sed
checking for grep... /usr/bin/grep
checking that grep -E works... yes
checking for ar... /usr/bin/ar
checking for a BSD-compatible install... /usr/bin/install -c
checking for gcc... ccache gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether ccache gcc accepts -g... yes
checking for ccache gcc option to enable C11 features... none needed
checking whether ccache gcc understands -c and -o together... yes
checking how to run the C preprocessor... ccache gcc -E
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for strings.h... yes
checking for sys/stat.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for stdatomic.h... yes
checking if _Atomic is available... yes
checking for a sed that does not truncate output... (cached) /usr/bin/sed
checking for code coverage support... no
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports the include directive... yes (GNU style)
checking dependency style of ccache gcc... gcc3
checking curl version... 8.5.0-DEV
checking for httpd... no
checking for apache2... no
checking for apachectl... no
checking for apxs... no
configure: httpd/apache2 not in PATH, http tests disabled
configure: apxs not in PATH, http tests disabled
checking for nghttpx... no
checking for caddy... no
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking for grep that handles long lines and -e... (cached) /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking if OS is AIX (to define _ALL_SOURCE)... no
checking if _THREAD_SAFE is already defined... no
checking if _THREAD_SAFE is actually needed... no
checking if _THREAD_SAFE is onwards defined... no
checking if _REENTRANT is already defined... no
checking if _REENTRANT is actually needed... no
checking if _REENTRANT is onwards defined... no
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking how to print strings... printf
checking for a sed that does not truncate output... (cached) /usr/bin/sed
checking for fgrep... /usr/bin/grep -F
checking for ld used by ccache gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from ccache gcc object... ok
checking for sysroot... no
checking for a working dd... /usr/bin/dd
checking how to truncate binary pipes... /usr/bin/dd bs=4096 count=1
checking for mt... mt
checking if mt is a manifest tool... no
checking for dlfcn.h... yes
checking for objdir... .libs
checking if ccache gcc supports -fno-rtti -fno-exceptions... no
checking for ccache gcc option to produce PIC... -fPIC -DPIC
checking if ccache gcc PIC flag -fPIC -DPIC works... yes
checking if ccache gcc static flag -static works... yes
checking if ccache gcc supports -c -o file.o... yes
checking if ccache gcc supports -c -o file.o... (cached) yes
checking whether the ccache gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... no
checking whether to build static libraries... yes
checking whether to build shared libraries with -version-info... yes
checking whether to build shared libraries with -no-undefined... no
checking whether to build shared libraries with -mimpure-text... no
checking whether to build shared libraries with PIC... yes
checking whether to build static libraries with PIC... yes
checking whether to build shared libraries only... no
checking whether to build static libraries only... yes
checking for windres... no
checking for inline... inline
checking if cpp -P is needed... yes
checking if cpp -P works... yes
checking if compiler is DEC/Compaq/HP C... no
checking if compiler is HP-UX C... no
checking if compiler is IBM C... no
checking if compiler is Intel C... no
checking if compiler is clang... no
checking if compiler is GNU C... yes
checking if compiler is LCC... no
checking if compiler is SGI MIPSpro C... no
checking if compiler is SGI MIPS C... no
checking if compiler is SunPro C... no
checking if compiler is Tiny C... no
checking if compiler accepts some basic options... yes
configure: compiler options added: -Werror-implicit-function-declaration 
checking if compiler optimizer assumed setting might be used... yes
checking if compiler accepts optimizer enabling options... yes
configure: compiler options added: -O2
checking if compiler accepts strict warning options... yes
configure: compiler options added: -Wno-system-headers 
checking if compiler halts on compilation errors... yes
checking if compiler halts on negative sized arrays... yes
checking if compiler halts on function prototype mismatch... yes
checking if compiler supports hiding library internal symbols... yes
checking for windows.h... no
checking whether build target is a native Windows one... no
checking whether build target supports WIN32 file API... no
checking whether build target supports WIN32 crypto API... no
checking for good-to-use Darwin CFLAGS... no
checking whether to link macOS CoreFoundation, CoreServices, and SystemConfiguration frameworks... no
checking to see if the compiler supports __builtin_available()... no
checking whether to support http... yes
checking whether to support ftp... yes
checking whether to support file... yes
checking whether to support ldap... yes
checking whether to support ldaps... yes
checking whether to support rtsp... yes
checking whether to support proxies... yes
checking whether to support dict... yes
checking whether to support telnet... yes
checking whether to support tftp... yes
checking whether to support pop3... yes
checking whether to support imap... yes
checking whether to support smb... yes
checking whether to support smtp... yes
checking whether to support gopher... yes
checking whether to support mqtt... no
checking whether to provide built-in manual... yes
checking whether to enable generation of C code... yes
checking whether to use libgcc... no
checking if X/Open network library is required... no
checking for gethostbyname... yes
checking for windows.h... (cached) no
checking for winsock2.h... (cached) no
checking for proto/bsdsocket.h... no
checking for connect in libraries... yes
checking for sys/types.h... (cached) yes
checking for sys/time.h... yes
checking for monotonic clock_gettime... yes
checking for clock_gettime in libraries... no additional lib required
checking if monotonic clock_gettime works... yes
checking for sys/types.h... (cached) yes
checking for sys/time.h... (cached) yes
checking for raw monotonic clock_gettime... yes
checking for pkg-config... /usr/bin/pkg-config
checking for zlib options with pkg-config... found
checking for zlib.h... yes
configure: found both libz and libz.h header
checking for BrotliDecoderDecompress in -lbrotlidec... no
checking for brotli/decode.h... no
checking for ZSTD_createDStream in -lzstd... no
checking for zstd.h... no
checking for lber.h... no
checking for ldap.h... no
checking for ldap_ssl.h... no
checking for LDAP libraries... cannot find LDAP libraries
checking whether to enable IPv6... yes
checking if struct sockaddr_in6 has sin6_scope_id member... yes
checking if argv can be written to... yes
checking if GSS-API support is requested... no
checking whether to enable Windows native SSL/TLS... no
checking whether to enable Secure Transport... no
checking whether to enable Amiga native SSL/TLS (AmiSSL v5)... no
checking for library containing psl_builtin... -lpsl
checking for library containing gsasl_init... no
checking for RTMP_Init in -lrtmp... no
checking whether versioned symbols are wanted... no
checking whether to enable Windows native IDN (Windows native builds only)... no
checking whether to build with libidn2... (assumed) yes
checking for pkg-config... (cached) /usr/bin/pkg-config
checking for libidn2 options with pkg-config... no
configure: IDN_LIBS: "-lidn2"
configure: IDN_LDFLAGS: ""
configure: IDN_CPPFLAGS: ""
configure: IDN_DIR: ""
checking if idn2_lookup_ul can be linked... no
checking for idn2.h... no
checking for pkg-config... (cached) /usr/bin/pkg-config
checking for libnghttp2 options with pkg-config... no
checking for nghttp2_session_get_stream_local_window_size in -lnghttp2... no
checking for pkg-config... (cached) /usr/bin/pkg-config
checking for fish options with pkg-config... no
checking for sys/types.h... (cached) yes
checking for sys/time.h... (cached) yes
checking for sys/select.h... yes
checking for sys/socket.h... yes
checking for sys/ioctl.h... yes
checking for unistd.h... (cached) yes
checking for stdlib.h... (cached) yes
checking for arpa/inet.h... yes
checking for net/if.h... yes
checking for netinet/in.h... yes
checking for netinet/in6.h... no
checking for sys/un.h... yes
checking for linux/tcp.h... yes
checking for netinet/tcp.h... yes
checking for netinet/udp.h... yes
checking for netdb.h... yes
checking for sys/sockio.h... no
checking for sys/stat.h... (cached) yes
checking for sys/param.h... yes
checking for termios.h... yes
checking for termio.h... yes
checking for fcntl.h... yes
checking for io.h... no
checking for pwd.h... yes
checking for utime.h... yes
checking for sys/utime.h... no
checking for sys/poll.h... yes
checking for poll.h... yes
checking for socket.h... no
checking for sys/resource.h... yes
checking for libgen.h... yes
checking for locale.h... yes
checking for stdbool.h... yes
checking for sys/filio.h... no
checking for sys/wait.h... yes
checking for setjmp.h... yes
checking for an ANSI C-conforming const... yes
checking for compiler support of C99 variadic macro style... yes
checking for compiler support of old gcc variadic macro style... yes
checking for size_t... yes
checking for sys/types.h... (cached) yes
checking for sys/time.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for struct timeval... yes
checking run-time libs availability... fine
checking size of size_t... 8
checking size of long... 8
checking size of int... 4
checking size of time_t... 8
checking size of off_t... 8
checking size of curl_off_t... 8
checking size of curl_socket_t... 4
checking for long long... yes
checking for ssize_t... yes
checking for bool... yes
checking for sa_family_t... yes
checking for suseconds_t... yes
checking if time_t is unsigned... no
checking for sys/types.h... (cached) yes
checking for poll.h... (cached) yes
checking for sys/poll.h... (cached) yes
checking for in_addr_t... yes
checking for struct sockaddr_storage... yes
checking for sys/select.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for select... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for recv... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for send... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for MSG_NOSIGNAL... yes
checking for sys/types.h... (cached) yes
checking for unistd.h... (cached) yes
checking if alarm can be linked... yes
checking if alarm is prototyped... yes
checking if alarm is compilable... yes
checking if alarm usage allowed... yes
checking if alarm might be used... yes
checking for sys/types.h... (cached) yes
checking for strings.h... (cached) yes
checking for sys/types.h... (cached) yes
checking for libgen.h... (cached) yes
checking if basename can be linked... yes
checking if basename is prototyped... yes
checking if basename is compilable... yes
checking if basename usage allowed... yes
checking if basename might be used... yes
checking for sys/types.h... (cached) yes
checking for socket.h... (cached) no
checking if closesocket can be linked... no
checking if closesocket might be used... no
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking if CloseSocket can be linked... no
checking if CloseSocket might be used... no
checking for sys/types.h... (cached) yes
checking for unistd.h... (cached) yes
checking for fcntl.h... (cached) yes
checking if fcntl can be linked... yes
checking if fcntl is prototyped... yes
checking if fcntl is compilable... yes
checking if fcntl usage allowed... yes
checking if fcntl might be used... yes
checking if fcntl O_NONBLOCK is compilable... yes
checking if fcntl O_NONBLOCK usage allowed... yes
checking if fcntl O_NONBLOCK might be used... yes
checking for windows.h... (cached) no
checking for winsock2.h... (cached) no
checking for ws2tcpip.h... (cached) no
checking for sys/types.h... (cached) yes
checking for netdb.h... (cached) yes
checking if freeaddrinfo can be linked... yes
checking if freeaddrinfo is prototyped... yes
checking if freeaddrinfo is compilable... yes
checking if freeaddrinfo usage allowed... yes
checking if freeaddrinfo might be used... yes
checking for sys/types.h... (cached) yes
checking for sys/xattr.h... yes
checking if fsetxattr can be linked... yes
checking if fsetxattr is prototyped... yes
checking if fsetxattr takes 5 args.... yes
checking if fsetxattr is compilable... yes
checking if fsetxattr usage allowed... yes
checking if fsetxattr might be used... yes
checking if ftruncate can be linked... yes
checking if ftruncate is prototyped... yes
checking if ftruncate is compilable... yes
checking if ftruncate usage allowed... yes
checking if ftruncate might be used... yes
checking for sys/types.h... (cached) yes
checking if getaddrinfo can be linked... yes
checking if getaddrinfo is prototyped... yes
checking if getaddrinfo is compilable... yes
checking if getaddrinfo seems to work... yes
checking if getaddrinfo usage allowed... yes
checking if getaddrinfo might be used... yes
checking if getaddrinfo is threadsafe... yes
checking if gethostbyname can be linked... yes
checking if gethostbyname is prototyped... yes
checking if gethostbyname is compilable... yes
checking if gethostbyname usage allowed... yes
checking if gethostbyname might be used... yes
checking if gethostbyname_r can be linked... yes
checking if gethostbyname_r is prototyped... yes
checking if gethostbyname_r takes 3 args.... no
checking if gethostbyname_r takes 5 args.... no
checking if gethostbyname_r takes 6 args.... yes
checking if gethostbyname_r is compilable... yes
checking if gethostbyname_r usage allowed... yes
checking if gethostbyname_r might be used... yes
checking if gethostname can be linked... yes
checking if gethostname is prototyped... yes
checking if gethostname is compilable... yes
checking for gethostname arg 2 data type... size_t
checking if gethostname usage allowed... yes
checking if gethostname might be used... yes
checking if getpeername can be linked... yes
checking if getpeername is prototyped... yes
checking if getpeername is compilable... yes
checking if getpeername usage allowed... yes
checking if getpeername might be used... yes
checking if getsockname can be linked... yes
checking if getsockname is prototyped... yes
checking if getsockname is compilable... yes
checking if getsockname usage allowed... yes
checking if getsockname might be used... yes
checking for net/if.h... (cached) yes
checking if if_nametoindex can be linked... yes
checking if if_nametoindex is prototyped... yes
checking if if_nametoindex is compilable... yes
checking if if_nametoindex usage allowed... yes
checking if if_nametoindex might be used... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for netinet/in.h... (cached) yes
checking for ifaddrs.h... yes
checking if getifaddrs can be linked... yes
checking if getifaddrs is prototyped... yes
checking if getifaddrs is compilable... yes
checking if getifaddrs seems to work... yes
checking if getifaddrs usage allowed... yes
checking if getifaddrs might be used... yes
checking for sys/types.h... (cached) yes
checking for sys/time.h... (cached) yes
checking if gmtime_r can be linked... yes
checking if gmtime_r is prototyped... yes
checking if gmtime_r is compilable... yes
checking if gmtime_r seems to work... yes
checking if gmtime_r usage allowed... yes
checking if gmtime_r might be used... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for netinet/in.h... (cached) yes
checking for arpa/inet.h... (cached) yes
checking if inet_ntop can be linked... yes
checking if inet_ntop is prototyped... yes
checking if inet_ntop is compilable... yes
checking if inet_ntop seems to work... yes
checking if inet_ntop usage allowed... yes
checking if inet_ntop might be used... yes
checking if inet_pton can be linked... yes
checking if inet_pton is prototyped... yes
checking if inet_pton is compilable... yes
checking if inet_pton seems to work... yes
checking if inet_pton usage allowed... yes
checking if inet_pton might be used... yes
checking for sys/types.h... (cached) yes
checking for unistd.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for sys/ioctl.h... (cached) yes
checking for stropts.h... no
checking if ioctl can be linked... yes
checking if ioctl is prototyped... yes
checking if ioctl is compilable... yes
checking if ioctl usage allowed... yes
checking if ioctl might be used... yes
checking if ioctl FIONBIO is compilable... yes
checking if ioctl FIONBIO usage allowed... yes
checking if ioctl FIONBIO might be used... yes
checking if ioctl SIOCGIFADDR is compilable... yes
checking if ioctl SIOCGIFADDR usage allowed... yes
checking if ioctl SIOCGIFADDR might be used... yes
checking if ioctlsocket can be linked... no
checking if ioctlsocket might be used... no
checking if IoctlSocket can be linked... no
checking if IoctlSocket might be used... no
checking if memrchr can be linked... yes
checking if memrchr is prototyped... no
checking if memrchr might be used... no
checking if poll can be linked... yes
checking if poll is prototyped... yes
checking if poll is compilable... yes
checking if poll seems to work... yes
checking if poll usage allowed... yes
checking if poll might be used... yes
checking for sys/types.h... (cached) yes
checking if sigaction can be linked... yes
checking if sigaction is prototyped... yes
checking if sigaction is compilable... yes
checking if sigaction usage allowed... yes
checking if sigaction might be used... yes
checking if siginterrupt can be linked... yes
checking if siginterrupt is prototyped... yes
checking if siginterrupt is compilable... yes
checking if siginterrupt usage allowed... yes
checking if siginterrupt might be used... yes
checking if signal can be linked... yes
checking if signal is prototyped... yes
checking if signal is compilable... yes
checking if signal usage allowed... yes
checking if signal might be used... yes
checking for sys/types.h... (cached) yes
checking if sigsetjmp can be linked... no
checking if sigsetjmp seems a macro... yes
checking if sigsetjmp is compilable... yes
checking if sigsetjmp usage allowed... yes
checking if sigsetjmp might be used... yes
checking if socket can be linked... yes
checking if socket is prototyped... yes
checking if socket is compilable... yes
checking if socket usage allowed... yes
checking if socket might be used... yes
checking if socketpair can be linked... yes
checking if socketpair is prototyped... yes
checking if socketpair is compilable... yes
checking if socketpair usage allowed... yes
checking if socketpair might be used... yes
checking if strcasecmp can be linked... yes
checking if strcasecmp is prototyped... yes
checking if strcasecmp is compilable... yes
checking if strcasecmp usage allowed... yes
checking if strcasecmp might be used... yes
checking if strcmpi can be linked... no
checking if strcmpi might be used... no
checking if strdup can be linked... yes
checking if strdup is prototyped... yes
checking if strdup is compilable... yes
checking if strdup usage allowed... yes
checking if strdup might be used... yes
checking if strerror_r can be linked... yes
checking if strerror_r is prototyped... yes
checking if strerror_r is compilable... yes
checking if strerror_r is glibc like... no
checking if strerror_r is POSIX like... yes
checking if strerror_r seems to work... yes
checking if strerror_r usage allowed... yes
checking if strerror_r might be used... yes
checking if stricmp can be linked... no
checking if stricmp might be used... no
checking if strtok_r can be linked... yes
checking if strtok_r is prototyped... yes
checking if strtok_r is compilable... yes
checking if strtok_r usage allowed... yes
checking if strtok_r might be used... yes
checking if strtoll can be linked... yes
checking if strtoll is prototyped... yes
checking if strtoll is compilable... yes
checking if strtoll usage allowed... yes
checking if strtoll might be used... yes
checking for ccache gcc options needed to detect all undeclared functions... none needed
checking whether getpwuid_r is declared... yes
checking for _fseeki64... no
checking deeper for _fseeki64... but still no
checking for arc4random... no
checking deeper for arc4random... but still no
checking for fchmod... yes
checking for fnmatch... yes
checking for fseeko... yes
checking for geteuid... yes
checking for getpass_r... no
checking deeper for getpass_r... but still no
checking for getppid... yes
checking for getpwuid... yes
checking for getpwuid_r... yes
checking for getrlimit... yes
checking for gettimeofday... yes
checking for if_nametoindex... yes
checking for mach_absolute_time... no
checking deeper for mach_absolute_time... but still no
checking for pipe... yes
checking for sched_yield... yes
checking for sendmsg... yes
checking for setlocale... yes
checking for setmode... no
checking deeper for setmode... but still no
checking for setrlimit... yes
checking for snprintf... yes
checking for utime... yes
checking for utimes... yes
checking whether fseeko is declared... yes
checking how to set a socket into non-blocking mode... fcntl O_NONBLOCK
checking for perl... /usr/bin/perl
checking for gnroff... no
checking for nroff... /usr/bin/nroff
checking how to use *nroff to get plain text from man pages... -man
checking whether to enable the threaded resolver... yes
checking whether to use POSIX threads for threaded resolver... auto
checking for pthread.h... yes
checking for pthread_create... yes
checking convert -I options to -isystem... yes
checking whether to enable verbose strings... yes
checking whether to enable SSPI support (Windows native builds only)... no
checking whether to enable basic authentication method... yes
checking whether to enable bearer authentication method... yes
checking whether to enable digest authentication method... yes
checking whether to enable kerberos authentication method... yes
checking whether to enable negotiate authentication method... yes
checking whether to enable aws sig methods... yes
checking whether to support NTLM... yes
checking whether to enable NTLM delegation to winbind's helper... no
checking whether to enable TLS-SRP authentication... yes
checking whether to enable Unix domain sockets... auto
checking for struct sockaddr_un.sun_path... yes
checking whether to support cookies... yes
checking whether to support socketpair... yes
checking whether to support HTTP authentication... yes
checking whether to support DoH... yes
checking whether to support the MIME API... yes
checking whether to support binding connections locally... yes
checking whether to support the form API... yes
checking whether to support date parsing... yes
checking whether to support netrc parsing... yes
checking whether to support progress-meter... yes
checking whether to support DNS shuffling... yes
checking whether to support curl_easy_option*... yes
checking whether to support alt-svc... yes
checking whether to support headers-api... yes
configure: disables HSTS due to lack of SSL
checking whether to support WebSockets... no
checking whether hiding of library internal symbols will actually happen... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating docs/Makefile
config.status: creating docs/examples/Makefile
config.status: creating docs/libcurl/Makefile
config.status: creating docs/libcurl/opts/Makefile
config.status: creating docs/cmdline-opts/Makefile
config.status: creating include/Makefile
config.status: creating include/curl/Makefile
config.status: creating src/Makefile
config.status: creating lib/Makefile
config.status: creating scripts/Makefile
config.status: creating lib/libcurl.vers
config.status: creating lib/libcurl.plist
config.status: creating tests/Makefile
config.status: creating tests/config
config.status: creating tests/certs/Makefile
config.status: creating tests/certs/scripts/Makefile
config.status: creating tests/data/Makefile
config.status: creating tests/server/Makefile
config.status: creating tests/libtest/Makefile
config.status: creating tests/unit/Makefile
config.status: creating tests/http/config.ini
config.status: creating tests/http/Makefile
config.status: creating tests/http/clients/Makefile
config.status: creating packages/Makefile
config.status: creating packages/vms/Makefile
config.status: creating curl-config
config.status: creating libcurl.pc
config.status: creating lib/curl_config.h
config.status: executing depfiles commands
config.status: executing libtool commands
configure: Configured to build curl/libcurl:

  Host setup:       x86_64-pc-linux-gnu
  Install prefix:   /usr/local
  Compiler:         ccache gcc
   CFLAGS:          -Werror-implicit-function-declaration -O2 -Wno-system-headers
   CPPFLAGS:        
   LDFLAGS:         
   LIBS:            -lpsl -lz

  curl version:     8.5.0-DEV
  SSL:              no      (--with-{openssl,gnutls,mbedtls,wolfssl,schannel,secure-transport,amissl,bearssl,rustls} )
  SSH:              no      (--with-{libssh,libssh2})
  zlib:             enabled
  brotli:           no      (--with-brotli)
  zstd:             no      (--with-zstd)
  GSS-API:          no      (--with-gssapi)
  GSASL:            no      (libgsasl not found)
  TLS-SRP:          no      (--enable-tls-srp)
  resolver:         POSIX threaded
  IPv6:             enabled
  Unix sockets:     enabled
  IDN:              no      (--with-{libidn2,winidn})
  Build libcurl:    Shared=no, Static=yes
  Built-in manual:  enabled
  --libcurl option: enabled (--disable-libcurl-option)
  Verbose errors:   enabled (--disable-verbose)
  Code coverage:    disabled
  SSPI:             no      (--enable-sspi)
  ca cert bundle:   no
  ca cert path:     
  ca fallback:      
  LDAP:             no      (--enable-ldap / --with-ldap-lib / --with-lber-lib)
  LDAPS:            no      (--enable-ldaps)
  RTSP:             enabled
  RTMP:             no      (--with-librtmp)
  PSL:              enabled
  Alt-svc:          enabled (--disable-alt-svc)
  Headers API:      enabled (--disable-headers-api)
  HSTS:             no      (--enable-hsts)
  HTTP1:            enabled (internal)
  HTTP2:            no      (--with-nghttp2, --with-hyper)
  HTTP3:            no      (--with-ngtcp2 --with-nghttp3, --with-quiche, --with-msh3)
  ECH:              no      (--enable-ech)
  WebSockets:       no      (--enable-websockets)
  Protocols:        DICT FILE FTP GOPHER HTTP IMAP MQTT POP3 RTSP SMTP TELNET TFTP
  Features:         AsynchDNS IPv6 Largefile PSL UnixSockets alt-svc libz threadsafe

configure: WARNING: unrecognized options: --disable-docs
configure: WARNING: Cannot find libraries for LDAP support: LDAP disabled
configure: WARNING: libgsasl was not found
configure: WARNING: Cannot find libraries for IDN support: IDN disabled
configure: WARNING: unrecognized options: --disable-docs

$ make -j3
Making all in lib
make[1]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/lib'
make  all-am
make[2]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/lib'
  CC       libcurl_la-altsvc.lo
  CC       libcurl_la-amigaos.lo
  CC       libcurl_la-asyn-ares.lo
  CC       libcurl_la-asyn-thread.lo
  CC       libcurl_la-base64.lo
  CC       libcurl_la-bufq.lo
  CC       libcurl_la-bufref.lo
  CC       libcurl_la-c-hyper.lo
  CC       libcurl_la-cf-h1-proxy.lo
  CC       libcurl_la-cf-h2-proxy.lo
  CC       libcurl_la-cf-haproxy.lo
  CC       libcurl_la-cf-https-connect.lo
  CC       libcurl_la-cf-socket.lo
  CC       libcurl_la-cfilters.lo
  CC       libcurl_la-conncache.lo
  CC       libcurl_la-connect.lo
  CC       libcurl_la-content_encoding.lo
  CC       libcurl_la-cookie.lo
  CC       libcurl_la-curl_addrinfo.lo
  CC       libcurl_la-curl_des.lo
  CC       libcurl_la-curl_endian.lo
  CC       libcurl_la-curl_fnmatch.lo
  CC       libcurl_la-curl_get_line.lo
  CC       libcurl_la-curl_gethostname.lo
  CC       libcurl_la-curl_gssapi.lo
  CC       libcurl_la-curl_memrchr.lo
  CC       libcurl_la-curl_multibyte.lo
  CC       libcurl_la-curl_ntlm_core.lo
  CC       libcurl_la-curl_ntlm_wb.lo
  CC       libcurl_la-curl_path.lo
  CC       libcurl_la-curl_range.lo
  CC       libcurl_la-curl_rtmp.lo
  CC       libcurl_la-curl_sasl.lo
  CC       libcurl_la-curl_sspi.lo
  CC       libcurl_la-curl_threads.lo
  CC       libcurl_la-curl_trc.lo
  CC       libcurl_la-dict.lo
  CC       libcurl_la-doh.lo
  CC       libcurl_la-dynbuf.lo
  CC       libcurl_la-dynhds.lo
  CC       libcurl_la-easy.lo
  CC       libcurl_la-easygetopt.lo
  CC       libcurl_la-easyoptions.lo
  CC       libcurl_la-escape.lo
  CC       libcurl_la-file.lo
  CC       libcurl_la-fileinfo.lo
  CC       libcurl_la-fopen.lo
  CC       libcurl_la-formdata.lo
  CC       libcurl_la-ftp.lo
  CC       libcurl_la-ftplistparser.lo
  CC       libcurl_la-getenv.lo
  CC       libcurl_la-getinfo.lo
  CC       libcurl_la-gopher.lo
  CC       libcurl_la-hash.lo
  CC       libcurl_la-headers.lo
  CC       libcurl_la-hmac.lo
  CC       libcurl_la-hostasyn.lo
  CC       libcurl_la-hostip.lo
  CC       libcurl_la-hostip4.lo
  CC       libcurl_la-hostip6.lo
  CC       libcurl_la-hostsyn.lo
  CC       libcurl_la-hsts.lo
  CC       libcurl_la-http.lo
  CC       libcurl_la-http1.lo
  CC       libcurl_la-http2.lo
  CC       libcurl_la-http_aws_sigv4.lo
  CC       libcurl_la-http_chunks.lo
  CC       libcurl_la-http_digest.lo
  CC       libcurl_la-http_negotiate.lo
  CC       libcurl_la-http_ntlm.lo
  CC       libcurl_la-http_proxy.lo
  CC       libcurl_la-idn.lo
  CC       libcurl_la-if2ip.lo
  CC       libcurl_la-imap.lo
  CC       libcurl_la-inet_ntop.lo
  CC       libcurl_la-inet_pton.lo
  CC       libcurl_la-krb5.lo
  CC       libcurl_la-ldap.lo
  CC       libcurl_la-llist.lo
  CC       libcurl_la-macos.lo
  CC       libcurl_la-md4.lo
  CC       libcurl_la-md5.lo
  CC       libcurl_la-memdebug.lo
  CC       libcurl_la-mime.lo
  CC       libcurl_la-mprintf.lo
  CC       libcurl_la-mqtt.lo
  CC       libcurl_la-multi.lo
  CC       libcurl_la-netrc.lo
  CC       libcurl_la-nonblock.lo
  CC       libcurl_la-noproxy.lo
  CC       libcurl_la-openldap.lo
  CC       libcurl_la-parsedate.lo
  CC       libcurl_la-pingpong.lo
  CC       libcurl_la-pop3.lo
  CC       libcurl_la-progress.lo
  CC       libcurl_la-psl.lo
  CC       libcurl_la-rand.lo
  CC       libcurl_la-rename.lo
  CC       libcurl_la-select.lo
  CC       libcurl_la-rtsp.lo
  CC       libcurl_la-sendf.lo
  CC       libcurl_la-setopt.lo
  CC       libcurl_la-sha256.lo
  CC       libcurl_la-share.lo
  CC       libcurl_la-slist.lo
  CC       libcurl_la-smb.lo
  CC       libcurl_la-smtp.lo
  CC       libcurl_la-socketpair.lo
  CC       libcurl_la-socks.lo
  CC       libcurl_la-socks_gssapi.lo
  CC       libcurl_la-socks_sspi.lo
  CC       libcurl_la-speedcheck.lo
  CC       libcurl_la-splay.lo
  CC       libcurl_la-strcase.lo
  CC       libcurl_la-strdup.lo
  CC       libcurl_la-strerror.lo
  CC       libcurl_la-strtok.lo
  CC       libcurl_la-strtoofft.lo
  CC       libcurl_la-system_win32.lo
  CC       libcurl_la-telnet.lo
  CC       libcurl_la-tftp.lo
  CC       libcurl_la-timediff.lo
  CC       libcurl_la-timeval.lo
  CC       libcurl_la-transfer.lo
  CC       libcurl_la-url.lo
  CC       libcurl_la-urlapi.lo
  CC       libcurl_la-version.lo
  CC       libcurl_la-version_win32.lo
  CC       libcurl_la-warnless.lo
  CC       libcurl_la-ws.lo
  CC       vauth/libcurl_la-cram.lo
  CC       vauth/libcurl_la-cleartext.lo
  CC       vauth/libcurl_la-digest.lo
  CC       vauth/libcurl_la-digest_sspi.lo
  CC       vauth/libcurl_la-gsasl.lo
  CC       vauth/libcurl_la-krb5_gssapi.lo
  CC       vauth/libcurl_la-krb5_sspi.lo
  CC       vauth/libcurl_la-ntlm.lo
  CC       vauth/libcurl_la-ntlm_sspi.lo
  CC       vauth/libcurl_la-oauth2.lo
  CC       vauth/libcurl_la-spnego_gssapi.lo
  CC       vauth/libcurl_la-spnego_sspi.lo
  CC       vauth/libcurl_la-vauth.lo
  CC       vtls/libcurl_la-bearssl.lo
  CC       vtls/libcurl_la-gtls.lo
  CC       vtls/libcurl_la-hostcheck.lo
  CC       vtls/libcurl_la-keylog.lo
  CC       vtls/libcurl_la-mbedtls.lo
  CC       vtls/libcurl_la-mbedtls_threadlock.lo
  CC       vtls/libcurl_la-openssl.lo
  CC       vtls/libcurl_la-rustls.lo
  CC       vtls/libcurl_la-schannel.lo
  CC       vtls/libcurl_la-schannel_verify.lo
  CC       vtls/libcurl_la-sectransp.lo
  CC       vtls/libcurl_la-vtls.lo
  CC       vtls/libcurl_la-wolfssl.lo
  CC       vtls/libcurl_la-x509asn1.lo
  CC       vquic/libcurl_la-curl_msh3.lo
  CC       vquic/libcurl_la-curl_ngtcp2.lo
  CC       vquic/libcurl_la-curl_quiche.lo
  CC       vquic/libcurl_la-vquic.lo
  CC       vssh/libcurl_la-libssh.lo
  CC       vssh/libcurl_la-libssh2.lo
  CC       vssh/libcurl_la-wolfssh.lo
  CCLD     libcurl.la
make[2]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/lib'
make[1]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/lib'
Making all in src
make[1]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/src'
Making all in ../docs
make[2]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/docs'
Making all in .
make[3]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/docs'
if test "..x" != "..x" -a -e "./curl.1"; then \
	/usr/bin/install -c -m 644 "./curl.1" /root/asi_db/builds/curl/_worktrees/w0/docs/curl.1; fi
cd cmdline-opts && make
make[4]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/docs/cmdline-opts'
  GENERATE ../../docs/curl.1
make[4]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/docs/cmdline-opts'
make[3]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/docs'
Making all in cmdline-opts
make[3]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/docs/cmdline-opts'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/docs/cmdline-opts'
make[2]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/docs'
make[2]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/src'
  CC       slist_wc.o
  CC       tool_binmode.o
  CC       tool_bname.o
  CC       tool_cb_dbg.o
  CC       tool_cb_hdr.o
  CC       tool_cb_rea.o
  CC       tool_cb_prg.o
  CC       tool_cb_see.o
  CC       tool_cb_wrt.o
  CC       tool_cfgable.o
  CC       tool_dirhie.o
  CC       tool_doswin.o
  CC       tool_easysrc.o
  CC       tool_filetime.o
  CC       tool_findfile.o
  CC       tool_formparse.o
  CC       tool_getparam.o
  CC       tool_getpass.o
  CC       tool_help.o
  CC       tool_helpers.o
  HUGE     tool_hugehelp.c
  CC       tool_libinfo.o
  CC       tool_listhelp.o
  CC       tool_main.o
  CC       tool_msgs.o
  CC       tool_operate.o
  CC       tool_operhlp.o
  CC       tool_paramhlp.o
  CC       tool_parsecfg.o
  CC       tool_progress.o
  CC       tool_setopt.o
  CC       tool_sleep.o
  CC       tool_stderr.o
  CC       tool_strdup.o
  CC       tool_urlglob.o
  CC       tool_util.o
  CC       tool_vms.o
  CC       tool_writeout.o
  CC       tool_writeout_json.o
  CC       tool_xattr.o
  CC       var.o
  CC       ../lib/base64.o
  CC       ../lib/curl_multibyte.o
  CC       ../lib/dynbuf.o
  CC       ../lib/nonblock.o
  CC       ../lib/strtoofft.o
  CC       ../lib/timediff.o
  CC       ../lib/version_win32.o
  CC       ../lib/warnless.o
  CC       tool_hugehelp.o
  CCLD     curl
make[2]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/src'
make[1]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/src'
make[1]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0'
make[1]: Nothing to be done for 'all-am'.
make[1]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0'

Commit Diff GitHub →

lib/cf-h1-proxy.c+11 -13
@@ -1038,31 +1038,29 @@ out:
return result;
}
-static int cf_h1_proxy_get_select_socks(struct Curl_cfilter *cf,
+static void cf_h1_proxy_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
struct h1_tunnel_state *ts = cf->ctx;
- int fds;
- fds = cf->next->cft->get_select_socks(cf->next, data, socks);
- if(!fds && cf->next->connected && !cf->connected) {
+ if(!cf->connected) {
/* If we are not connected, but the filter "below" is
* and not waiting on something, we are tunneling. */
- socks[0] = Curl_conn_cf_get_socket(cf, data);
+ curl_socket_t sock = Curl_conn_cf_get_socket(cf, data);
if(ts) {
/* when we've sent a CONNECT to a proxy, we should rather either
wait for the socket to become readable to be able to get the
response headers or if we're still sending the request, wait
for write. */
- if(ts->CONNECT.sending == HTTPSEND_REQUEST) {
- return GETSOCK_WRITESOCK(0);
- }
- return GETSOCK_READSOCK(0);
+ if(ts->CONNECT.sending == HTTPSEND_REQUEST)
+ Curl_pollset_set_out_only(data, ps, sock);
+ else
+ Curl_pollset_set_in_only(data, ps, sock);
}
- return GETSOCK_WRITESOCK(0);
+ else
+ Curl_pollset_set_out_only(data, ps, sock);
}
- return fds;
}
static void cf_h1_proxy_destroy(struct Curl_cfilter *cf,
@@ -1093,7 +1091,7 @@ struct Curl_cftype Curl_cft_h1_proxy = {
cf_h1_proxy_connect,
cf_h1_proxy_close,
Curl_cf_http_proxy_get_host,
- cf_h1_proxy_get_select_socks,
+ cf_h1_proxy_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
lib/cf-h2-proxy.c+25 -27
@@ -688,12 +688,8 @@ static int proxy_h2_on_frame_recv(nghttp2_session *session,
* window and *assume* that we treat this like a WINDOW_UPDATE. Some
* servers send an explicit WINDOW_UPDATE, but not all seem to do that.
* To be safe, we UNHOLD a stream in order not to stall. */
- if((data->req.keepon & KEEP_SEND_HOLD) &&
- (data->req.keepon & KEEP_SEND)) {
- data->req.keepon &= ~KEEP_SEND_HOLD;
+ if(CURL_WANT_SEND(data)) {
drain_tunnel(cf, data, &ctx->tunnel);
- CURL_TRC_CF(data, cf, "[%d] un-holding after SETTINGS",
- stream_id);
}
break;
case NGHTTP2_GOAWAY:
@@ -727,12 +723,8 @@ static int proxy_h2_on_frame_recv(nghttp2_session *session,
}
break;
case NGHTTP2_WINDOW_UPDATE:
- if((data->req.keepon & KEEP_SEND_HOLD) &&
- (data->req.keepon & KEEP_SEND)) {
- data->req.keepon &= ~KEEP_SEND_HOLD;
- Curl_expire(data, 0, EXPIRE_RUN_NOW);
- CURL_TRC_CF(data, cf, "[%d] unpausing after win update",
- stream_id);
+ if(CURL_WANT_SEND(data)) {
+ drain_tunnel(cf, data, &ctx->tunnel);
}
break;
default:
@@ -1176,25 +1168,31 @@ static bool cf_h2_proxy_data_pending(struct Curl_cfilter *cf,
return cf->next? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
}
-static int cf_h2_proxy_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *sock)
+static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
- int bitmap = GETSOCK_BLANK;
- struct cf_call_data save;
-
- CF_DATA_SAVE(save, cf, data);
- sock[0] = Curl_conn_cf_get_socket(cf, data);
- bitmap |= GETSOCK_READSOCK(0);
+ curl_socket_t sock = Curl_conn_cf_get_socket(cf, data);
+ bool want_recv, want_send;
- /* HTTP/2 layer wants to send data) AND there's a window to send data in */
- if(nghttp2_session_want_write(ctx->h2) &&
- nghttp2_session_get_remote_window_size(ctx->h2))
- bitmap |= GETSOCK_WRITESOCK(0);
+ Curl_pollset_check(data, ps, sock, &want_recv, &want_send);
+ if(ctx->h2 && (want_recv || want_send)) {
+ struct cf_call_data save;
+ bool c_exhaust, s_exhaust;
- CF_DATA_RESTORE(cf, save);
- return bitmap;
+ CF_DATA_SAVE(save, cf, data);
+ 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);
+ want_recv = (want_recv || c_exhaust || s_exhaust);
+ want_send = (!s_exhaust && want_send) ||
+ (!c_exhaust && nghttp2_session_want_write(ctx->h2));
+
+ Curl_pollset_set(data, ps, sock, want_recv, want_send);
+ CF_DATA_RESTORE(cf, save);
+ }
}
static ssize_t h2_handle_tunnel_close(struct Curl_cfilter *cf,
@@ -1531,7 +1529,7 @@ struct Curl_cftype Curl_cft_h2_proxy = {
cf_h2_proxy_connect,
cf_h2_proxy_close,
Curl_cf_http_proxy_get_host,
- cf_h2_proxy_get_select_socks,
+ cf_h2_proxy_adjust_pollset,
cf_h2_proxy_data_pending,
cf_h2_proxy_send,
cf_h2_proxy_recv,
lib/cf-haproxy.c+6 -12
@@ -171,23 +171,17 @@ static void cf_haproxy_close(struct Curl_cfilter *cf,
cf->next->cft->do_close(cf->next, data);
}
-static int cf_haproxy_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *socks)
+static void cf_haproxy_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps)
{
- int fds;
-
- fds = cf->next->cft->get_select_socks(cf->next, data, socks);
- if(!fds && cf->next->connected && !cf->connected) {
+ if(cf->next->connected && !cf->connected) {
/* If we are not connected, but the filter "below" is
* and not waiting on something, we are sending. */
- socks[0] = Curl_conn_cf_get_socket(cf, data);
- return GETSOCK_WRITESOCK(0);
+ Curl_pollset_set_out_only(data, ps, Curl_conn_cf_get_socket(cf, data));
}
- return fds;
}
-
struct Curl_cftype Curl_cft_haproxy = {
"HAPROXY",
0,
@@ -196,7 +190,7 @@ struct Curl_cftype Curl_cft_haproxy = {
cf_haproxy_connect,
cf_haproxy_close,
Curl_cf_def_get_host,
- cf_haproxy_get_select_socks,
+ cf_haproxy_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
lib/cf-https-connect.c+16 -33
@@ -325,42 +325,25 @@ out:
return result;
}
-static int cf_hc_get_select_socks(struct Curl_cfilter *cf,
+static void cf_hc_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
- struct cf_hc_ctx *ctx = cf->ctx;
- size_t i, j, s;
- int brc, rc = GETSOCK_BLANK;
- curl_socket_t bsocks[MAX_SOCKSPEREASYHANDLE];
- struct cf_hc_baller *ballers[2];
-
- if(cf->connected)
- return cf->next->cft->get_select_socks(cf->next, data, socks);
-
- ballers[0] = &ctx->h3_baller;
- ballers[1] = &ctx->h21_baller;
- for(i = s = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
- struct cf_hc_baller *b = ballers[i];
- if(!cf_hc_baller_is_active(b))
- continue;
- brc = Curl_conn_cf_get_select_socks(b->cf, data, bsocks);
- CURL_TRC_CF(data, cf, "get_selected_socks(%s) -> %x", b->name, brc);
- if(!brc)
- continue;
- for(j = 0; j < MAX_SOCKSPEREASYHANDLE && s < MAX_SOCKSPEREASYHANDLE; ++j) {
- if((brc & GETSOCK_WRITESOCK(j)) || (brc & GETSOCK_READSOCK(j))) {
- socks[s] = bsocks[j];
- if(brc & GETSOCK_WRITESOCK(j))
- rc |= GETSOCK_WRITESOCK(s);
- if(brc & GETSOCK_READSOCK(j))
- rc |= GETSOCK_READSOCK(s);
- s++;
- }
+ if(!cf->connected) {
+ struct cf_hc_ctx *ctx = cf->ctx;
+ struct cf_hc_baller *ballers[2];
+ size_t i;
+
+ ballers[0] = &ctx->h3_baller;
+ ballers[1] = &ctx->h21_baller;
+ for(i = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
+ struct cf_hc_baller *b = ballers[i];
+ if(!cf_hc_baller_is_active(b))
+ continue;
+ Curl_conn_cf_adjust_pollset(b->cf, data, ps);
}
+ CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num);
}
- CURL_TRC_CF(data, cf, "get_selected_socks -> %x", rc);
- return rc;
}
static bool cf_hc_data_pending(struct Curl_cfilter *cf,
@@ -455,7 +438,7 @@ struct Curl_cftype Curl_cft_http_connect = {
cf_hc_connect,
cf_hc_close,
Curl_cf_def_get_host,
- cf_hc_get_select_socks,
+ cf_hc_adjust_pollset,
cf_hc_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
lib/cf-socket.c+12 -13
@@ -1252,20 +1252,19 @@ static void cf_socket_get_host(struct Curl_cfilter *cf,
*pport = cf->conn->port;
}
-static int cf_socket_get_select_socks(struct Curl_cfilter *cf,
+static void cf_socket_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
struct cf_socket_ctx *ctx = cf->ctx;
- int rc = GETSOCK_BLANK;
- (void)data;
- if(!cf->connected && ctx->sock != CURL_SOCKET_BAD) {
- socks[0] = ctx->sock;
- rc |= GETSOCK_WRITESOCK(0);
+ if(ctx->sock != CURL_SOCKET_BAD) {
+ if(!cf->connected)
+ Curl_pollset_set_out_only(data, ps, ctx->sock);
+ else
+ Curl_pollset_add_in(data, ps, ctx->sock);
+ CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num);
}
-
- return rc;
}
static bool cf_socket_data_pending(struct Curl_cfilter *cf,
@@ -1612,7 +1611,7 @@ struct Curl_cftype Curl_cft_tcp = {
cf_tcp_connect,
cf_socket_close,
cf_socket_get_host,
- cf_socket_get_select_socks,
+ cf_socket_adjust_pollset,
cf_socket_data_pending,
cf_socket_send,
cf_socket_recv,
@@ -1742,7 +1741,7 @@ struct Curl_cftype Curl_cft_udp = {
cf_udp_connect,
cf_socket_close,
cf_socket_get_host,
- cf_socket_get_select_socks,
+ cf_socket_adjust_pollset,
cf_socket_data_pending,
cf_socket_send,
cf_socket_recv,
@@ -1793,7 +1792,7 @@ struct Curl_cftype Curl_cft_unix = {
cf_tcp_connect,
cf_socket_close,
cf_socket_get_host,
- cf_socket_get_select_socks,
+ cf_socket_adjust_pollset,
cf_socket_data_pending,
cf_socket_send,
cf_socket_recv,
@@ -1857,7 +1856,7 @@ struct Curl_cftype Curl_cft_tcp_accept = {
cf_tcp_accept_connect,
cf_socket_close,
cf_socket_get_host, /* TODO: not accurate */
- cf_socket_get_select_socks,
+ cf_socket_adjust_pollset,
cf_socket_data_pending,
cf_socket_send,
cf_socket_recv,
lib/cfilters.c+166 -24
@@ -33,6 +33,7 @@
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "multiif.h"
#include "progress.h"
+#include "select.h"
#include "warnless.h"
/* The last 3 #include files should be in this order */
@@ -70,12 +71,14 @@ void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
}
}
-int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
+void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
- return cf->next?
- cf->next->cft->get_select_socks(cf->next, data, socks) : 0;
+ /* NOP */
+ (void)cf;
+ (void)data;
+ (void)ps;
}
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
@@ -303,15 +306,6 @@ void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data)
cf->cft->do_close(cf, data);
}
-int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *socks)
-{
- if(cf)
- return cf->cft->get_select_socks(cf, data, socks);
- return 0;
-}
-
ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
@@ -433,22 +427,31 @@ bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
return FALSE;
}
-int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
- curl_socket_t *socks)
+void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps)
{
- struct Curl_cfilter *cf;
+ /* Get the lowest not-connected filter, if there are any */
+ while(cf && !cf->connected && cf->next && !cf->next->connected)
+ cf = cf->next;
+ /* From there on, give all filters a chance to adjust the pollset.
+ * Lower filters are called later, so they may override */
+ while(cf) {
+ cf->cft->adjust_pollset(cf, data, ps);
+ cf = cf->next;
+ }
+}
+
+void Curl_conn_adjust_pollset(struct Curl_easy *data,
+ struct easy_pollset *ps)
+{
+ int i;
DEBUGASSERT(data);
DEBUGASSERT(data->conn);
- cf = data->conn->cfilter[sockindex];
-
- /* if the next one is not yet connected, that's the one we want */
- while(cf && cf->next && !cf->next->connected)
- cf = cf->next;
- if(cf) {
- return cf->cft->get_select_socks(cf, data, socks);
+ for(i = 0; i < 2; ++i) {
+ Curl_conn_cf_adjust_pollset(data->conn->cfilter[i], data, ps);
}
- return GETSOCK_BLANK;
}
void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
@@ -646,3 +649,142 @@ size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
&n, NULL) : CURLE_UNKNOWN_OPTION;
return (result || n <= 0)? 1 : (size_t)n;
}
+
+
+void Curl_pollset_reset(struct Curl_easy *data,
+ struct easy_pollset *ps)
+{
+ size_t i;
+ (void)data;
+ memset(ps, 0, sizeof(*ps));
+ for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
+ ps->sockets[i] = CURL_SOCKET_BAD;
+}
+
+/**
+ *
+ */
+void Curl_pollset_change(struct Curl_easy *data,
+ struct easy_pollset *ps, curl_socket_t sock,
+ int add_flags, int remove_flags)
+{
+ unsigned int i;
+
+ (void)data;
+ DEBUGASSERT(VALID_SOCK(sock));
+ if(!VALID_SOCK(sock))
+ return;
+
+ DEBUGASSERT(add_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
+ DEBUGASSERT(remove_flags <= (CURL_POLL_IN|CURL_POLL_OUT));
+ DEBUGASSERT((add_flags&remove_flags) == 0); /* no overlap */
+ for(i = 0; i < ps->num; ++i) {
+ if(ps->sockets[i] == sock) {
+ ps->actions[i] &= (unsigned char)(~remove_flags);
+ ps->actions[i] |= (unsigned char)add_flags;
+ /* all gone? remove socket */
+ if(!ps->actions[i]) {
+ if((i + 1) < ps->num) {
+ memmove(&ps->sockets[i], &ps->sockets[i + 1],
+ (ps->num - (i + 1)) * sizeof(ps->sockets[0]));
+ memmove(&ps->actions[i], &ps->actions[i + 1],
+ (ps->num - (i + 1)) * sizeof(ps->actions[0]));
+ }
+ --ps->num;
+ }
+ return;
+ }
+ }
+ /* not present */
+ if(add_flags) {
+ /* Having more SOCKETS per easy handle than what is defined
+ * is a programming error. This indicates that we need
+ * to raise this limit, making easy_pollset larger.
+ * Since we use this in tight loops, we do not want to make
+ * the pollset dynamic unnecessarily.
+ * The current maximum in practise is HTTP/3 eyeballing where
+ * we have up to 4 sockets involved in connection setup.
+ */
+ DEBUGASSERT(i < MAX_SOCKSPEREASYHANDLE);
+ if(i < MAX_SOCKSPEREASYHANDLE) {
+ ps->sockets[i] = sock;
+ ps->actions[i] = (unsigned char)add_flags;
+ ps->num = i + 1;
+ }
+ }
+}
+
+void Curl_pollset_set(struct Curl_easy *data,
+ struct easy_pollset *ps, curl_socket_t sock,
+ bool do_in, bool do_out)
+{
+ Curl_pollset_change(data, ps, sock,
+ (do_in?CURL_POLL_IN:0)|(do_out?CURL_POLL_OUT:0),
+ (!do_in?CURL_POLL_IN:0)|(!do_out?CURL_POLL_OUT:0));
+}
+
+static void ps_add(struct Curl_easy *data, struct easy_pollset *ps,
+ int bitmap, curl_socket_t *socks)
+{
+ if(bitmap) {
+ int i;
+ for(i = 0; i < MAX_SOCKSPEREASYHANDLE; ++i) {
+ if(!(bitmap & GETSOCK_MASK_RW(i)) || !VALID_SOCK((socks[i]))) {
+ break;
+ }
+ if(bitmap & GETSOCK_READSOCK(i)) {
+ if(bitmap & GETSOCK_WRITESOCK(i))
+ Curl_pollset_add_inout(data, ps, socks[i]);
+ else
+ /* is READ, since we checked MASK_RW above */
+ Curl_pollset_add_in(data, ps, socks[i]);
+ }
+ else
+ Curl_pollset_add_out(data, ps, socks[i]);
+ }
+ }
+}
+
+void Curl_pollset_add_socks(struct Curl_easy *data,
+ struct easy_pollset *ps,
+ int (*get_socks_cb)(struct Curl_easy *data,
+ struct connectdata *conn,
+ curl_socket_t *socks))
+{
+ curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
+ int bitmap;
+
+ DEBUGASSERT(data->conn);
+ bitmap = get_socks_cb(data, data->conn, socks);
+ ps_add(data, ps, bitmap, socks);
+}
+
+void Curl_pollset_add_socks2(struct Curl_easy *data,
+ struct easy_pollset *ps,
+ int (*get_socks_cb)(struct Curl_easy *data,
+ curl_socket_t *socks))
+{
+ curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
+ int bitmap;
+
+ bitmap = get_socks_cb(data, socks);
+ ps_add(data, ps, bitmap, socks);
+}
+
+void Curl_pollset_check(struct Curl_easy *data,
+ struct easy_pollset *ps, curl_socket_t sock,
+ bool *pwant_read, bool *pwant_write)
+{
+ unsigned int i;
+
+ (void)data;
+ DEBUGASSERT(VALID_SOCK(sock));
+ for(i = 0; i < ps->num; ++i) {
+ if(ps->sockets[i] == sock) {
+ *pwant_read = !!(ps->actions[i] & CURL_POLL_IN);
+ *pwant_write = !!(ps->actions[i] & CURL_POLL_OUT);
+ return;
+ }
+ }
+ *pwant_read = *pwant_write = FALSE;
+}
lib/cfilters.h+89 -18
@@ -60,14 +60,34 @@ typedef void Curl_cft_get_host(struct Curl_cfilter *cf,
const char **pdisplay_host,
int *pport);
-/* Filters may return sockets and fdset flags they are waiting for.
- * The passes array has room for up to MAX_SOCKSPEREASYHANDLE sockets.
- * @return read/write fdset for index in socks
- * or GETSOCK_BLANK when nothing to wait on
+struct easy_pollset;
+
+/* Passing in an easy_pollset for monitoring of sockets, let
+ * filters add or remove sockets actions (CURL_POLL_OUT, CURL_POLL_IN).
+ * This may add a socket or, in case no actions remain, remove
+ * a socket from the set.
+ *
+ * Filter implementations need to call filters "below" *after* they have
+ * made their adjustments. This allows lower filters to override "upper"
+ * actions. If a "lower" filter is unable to write, it needs to be able
+ * to disallow POLL_OUT.
+ *
+ * A filter without own restrictions/preferences should not modify
+ * the pollset. Filters, whose filter "below" is not connected, should
+ * also do no adjustments.
+ *
+ * Examples: a TLS handshake, while ongoing, might remove POLL_IN
+ * when it needs to write, or vice versa. A HTTP/2 filter might remove
+ * POLL_OUT when a stream window is exhausted and a WINDOW_UPDATE needs
+ * to be received first and add instead POLL_IN.
+ *
+ * @param cf the filter to ask
+ * @param data the easy handle the pollset is about
+ * @param ps the pollset (inout) for the easy handle
*/
-typedef int Curl_cft_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *socks);
+typedef void Curl_cft_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps);
typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data);
@@ -171,7 +191,7 @@ struct Curl_cftype {
Curl_cft_connect *do_connect; /* establish connection */
Curl_cft_close *do_close; /* close conn */
Curl_cft_get_host *get_host; /* host filter talks to */
- Curl_cft_get_select_socks *get_select_socks;/* sockets to select on */
+ 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 */
@@ -200,9 +220,9 @@ void Curl_cf_def_destroy_this(struct Curl_cfilter *cf,
void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
const char **phost, const char **pdisplay_host,
int *pport);
-int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *socks);
+void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps);
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data);
ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
@@ -279,9 +299,6 @@ CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done);
void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data);
-int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *socks);
ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err);
ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
@@ -364,11 +381,17 @@ bool Curl_conn_data_pending(struct Curl_easy *data,
curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex);
/**
- * Get any select fd flags and the socket filters at chain `sockindex`
- * at connection `conn` might be waiting for.
+ * Adjust the pollset for the filter chain startgin at `cf`.
*/
-int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
- curl_socket_t *socks);
+void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps);
+
+/**
+ * Adjust pollset from filters installed at transfer's connection.
+ */
+void Curl_conn_adjust_pollset(struct Curl_easy *data,
+ struct easy_pollset *ps);
/**
* Receive data through the filter chain at `sockindex` for connection
@@ -468,6 +491,54 @@ size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
int sockindex);
+void Curl_pollset_reset(struct Curl_easy *data,
+ struct easy_pollset *ps);
+
+/* Change the poll flags (CURL_POLL_IN/CURL_POLL_OUT) to the poll set for
+ * socket `sock`. If the socket is not already part of the poll set, it
+ * will be added.
+ * If the socket is present and all poll flags are cleared, it will be removed.
+ */
+void Curl_pollset_change(struct Curl_easy *data,
+ struct easy_pollset *ps, curl_socket_t sock,
+ int add_flags, int remove_flags);
+
+void Curl_pollset_set(struct Curl_easy *data,
+ struct easy_pollset *ps, curl_socket_t sock,
+ bool do_in, bool do_out);
+
+#define Curl_pollset_add_in(data, ps, sock) \
+ Curl_pollset_change((data), (ps), (sock), CURL_POLL_IN, 0)
+#define Curl_pollset_add_out(data, ps, sock) \
+ Curl_pollset_change((data), (ps), (sock), CURL_POLL_OUT, 0)
+#define Curl_pollset_add_inout(data, ps, sock) \
+ Curl_pollset_change((data), (ps), (sock), \
+ CURL_POLL_IN|CURL_POLL_OUT, 0)
+#define Curl_pollset_set_in_only(data, ps, sock) \
+ Curl_pollset_change((data), (ps), (sock), \
+ CURL_POLL_IN, CURL_POLL_OUT)
+#define Curl_pollset_set_out_only(data, ps, sock) \
+ Curl_pollset_change((data), (ps), (sock), \
+ CURL_POLL_OUT, CURL_POLL_IN)
+
+void Curl_pollset_add_socks(struct Curl_easy *data,
+ struct easy_pollset *ps,
+ int (*get_socks_cb)(struct Curl_easy *data,
+ struct connectdata *conn,
+ curl_socket_t *socks));
+void Curl_pollset_add_socks2(struct Curl_easy *data,
+ struct easy_pollset *ps,
+ int (*get_socks_cb)(struct Curl_easy *data,
+ curl_socket_t *socks));
+
+/**
+ * Check if the pollset, as is, wants to read and/or write regarding
+ * the given socket.
+ */
+void Curl_pollset_check(struct Curl_easy *data,
+ struct easy_pollset *ps, curl_socket_t sock,
+ bool *pwant_read, bool *pwant_write);
+
/**
* Types and macros used to keep the current easy handle in filter calls,
* allowing for nested invocations. See #10336.
lib/connect.c+22 -36
@@ -84,6 +84,9 @@
#include "curl_memory.h"
#include "memdebug.h"
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
+#endif
/*
* Curl_timeleft() returns the amount of milliseconds left allowed for the
@@ -595,7 +598,7 @@ evaluate:
*connected = FALSE; /* a very negative world view is best */
now = Curl_now();
ongoing = not_started = 0;
- for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) {
+ for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
if(!baller || baller->is_done)
@@ -656,7 +659,7 @@ evaluate:
if(not_started > 0) {
int added = 0;
- for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) {
+ for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
if(!baller || baller->has_started)
@@ -691,7 +694,7 @@ evaluate:
/* all ballers have failed to connect. */
CURL_TRC_CF(data, cf, "all eyeballers failed");
result = CURLE_COULDNT_CONNECT;
- for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) {
+ for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
if(!baller)
continue;
@@ -838,7 +841,7 @@ static void cf_he_ctx_clear(struct Curl_cfilter *cf, struct Curl_easy *data)
DEBUGASSERT(ctx);
DEBUGASSERT(data);
- for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) {
+ for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
baller_free(ctx->baller[i], data);
ctx->baller[i] = NULL;
}
@@ -846,35 +849,22 @@ static void cf_he_ctx_clear(struct Curl_cfilter *cf, struct Curl_easy *data)
ctx->winner = NULL;
}
-static int cf_he_get_select_socks(struct Curl_cfilter *cf,
+static void cf_he_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
struct cf_he_ctx *ctx = cf->ctx;
- size_t i, s;
- int wrc, rc = GETSOCK_BLANK;
- curl_socket_t wsocks[MAX_SOCKSPEREASYHANDLE];
-
- if(cf->connected)
- return cf->next->cft->get_select_socks(cf->next, data, socks);
-
- for(i = s = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) {
- struct eyeballer *baller = ctx->baller[i];
- if(!baller || !baller->cf)
- continue;
+ size_t i;
- wrc = Curl_conn_cf_get_select_socks(baller->cf, data, wsocks);
- if(wrc) {
- /* TODO: we assume we get at most one socket back */
- socks[s] = wsocks[0];
- if(wrc & GETSOCK_WRITESOCK(0))
- rc |= GETSOCK_WRITESOCK(s);
- if(wrc & GETSOCK_READSOCK(0))
- rc |= GETSOCK_READSOCK(s);
- s++;
+ if(!cf->connected) {
+ for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ struct eyeballer *baller = ctx->baller[i];
+ if(!baller || !baller->cf)
+ continue;
+ Curl_conn_cf_adjust_pollset(baller->cf, data, ps);
}
+ CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num);
}
- return rc;
}
static CURLcode cf_he_connect(struct Curl_cfilter *cf,
@@ -956,7 +946,7 @@ static bool cf_he_data_pending(struct Curl_cfilter *cf,
if(cf->connected)
return cf->next->cft->has_data_pending(cf->next, data);
- for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) {
+ for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
if(!baller || !baller->cf)
continue;
@@ -975,7 +965,7 @@ static struct curltime get_max_baller_time(struct Curl_cfilter *cf,
size_t i;
memset(&tmax, 0, sizeof(tmax));
- for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) {
+ for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
memset(&t, 0, sizeof(t));
@@ -1000,7 +990,7 @@ static CURLcode cf_he_query(struct Curl_cfilter *cf,
int reply_ms = -1;
size_t i;
- for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) {
+ for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
int breply_ms;
@@ -1055,7 +1045,7 @@ struct Curl_cftype Curl_cft_happy_eyeballs = {
cf_he_connect,
cf_he_close,
Curl_cf_def_get_host,
- cf_he_get_select_socks,
+ cf_he_adjust_pollset,
cf_he_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
@@ -1126,10 +1116,6 @@ struct transport_provider transport_providers[] = {
{ TRNSPRT_UNIX, Curl_cf_unix_create },
};
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
static cf_ip_connect_create *get_cf_create(int transport)
{
size_t i;
@@ -1319,7 +1305,7 @@ struct Curl_cftype Curl_cft_setup = {
cf_setup_connect,
cf_setup_close,
Curl_cf_def_get_host,
- Curl_cf_def_get_select_socks,
+ Curl_cf_def_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
lib/ftp.c+1 -1
@@ -819,7 +819,7 @@ static int ftp_domore_getsock(struct Curl_easy *data,
DEBUGF(infof(data, "ftp_domore_getsock()"));
if(conn->cfilter[SECONDARYSOCKET]
&& !Curl_conn_is_connected(conn, SECONDARYSOCKET))
- return Curl_conn_get_select_socks(data, SECONDARYSOCKET, socks);
+ return 0;
if(FTP_STOP == ftpc->state) {
int bits = GETSOCK_READSOCK(0);
lib/http2.c+26 -49
@@ -1081,16 +1081,11 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
stream->reset = TRUE;
}
stream->send_closed = TRUE;
- data->req.keepon &= ~KEEP_SEND_HOLD;
drain_stream(cf, data, stream);
break;
case NGHTTP2_WINDOW_UPDATE:
- if((data->req.keepon & KEEP_SEND_HOLD) &&
- (data->req.keepon & KEEP_SEND)) {
- data->req.keepon &= ~KEEP_SEND_HOLD;
+ if(CURL_WANT_SEND(data)) {
drain_stream(cf, data, stream);
- CURL_TRC_CF(data, cf, "[%d] un-holding after win update",
- stream_id);
}
break;
default:
@@ -1235,15 +1230,10 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
* window and *assume* that we treat this like a WINDOW_UPDATE. Some
* servers send an explicit WINDOW_UPDATE, but not all seem to do that.
* To be safe, we UNHOLD a stream in order not to stall. */
- if((data->req.keepon & KEEP_SEND_HOLD) &&
- (data->req.keepon & KEEP_SEND)) {
+ if(CURL_WANT_SEND(data)) {
struct stream_ctx *stream = H2_STREAM_CTX(data);
- data->req.keepon &= ~KEEP_SEND_HOLD;
- if(stream) {
+ if(stream)
drain_stream(cf, data, stream);
- CURL_TRC_CF(data, cf, "[%d] un-holding after SETTINGS",
- stream_id);
- }
}
}
break;
@@ -1343,7 +1333,6 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
stream->error = error_code;
if(stream->error)
stream->reset = TRUE;
- data_s->req.keepon &= ~KEEP_SEND_HOLD;
if(stream->error)
CURL_TRC_CF(data_s, cf, "[%d] RESET: %s (err %d)",
@@ -2267,14 +2256,6 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
* frame buffer or our network out buffer. */
size_t rwin = nghttp2_session_get_stream_remote_window_size(ctx->h2,
stream->id);
- if(rwin == 0) {
- /* H2 flow window exhaustion. We need to HOLD upload until we get
- * a WINDOW_UPDATE from the server. */
- data->req.keepon |= KEEP_SEND_HOLD;
- CURL_TRC_CF(data, cf, "[%d] holding send as remote flow "
- "window is exhausted", stream->id);
- }
-
/* Whatever the cause, we need to return CURL_EAGAIN for this call.
* We have unwritten state that needs us being invoked again and EAGAIN
* is the only way to ensure that. */
@@ -2326,38 +2307,34 @@ out:
return nwritten;
}
-static int cf_h2_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *sock)
+static void cf_h2_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps)
{
struct cf_h2_ctx *ctx = cf->ctx;
- struct SingleRequest *k = &data->req;
- struct stream_ctx *stream = H2_STREAM_CTX(data);
- int bitmap = GETSOCK_BLANK;
- struct cf_call_data save;
+ bool want_recv = CURL_WANT_RECV(data);
+ bool want_send = CURL_WANT_SEND(data);
- CF_DATA_SAVE(save, cf, data);
- sock[0] = Curl_conn_cf_get_socket(cf, data);
-
- if(!(k->keepon & (KEEP_RECV_PAUSE|KEEP_RECV_HOLD)))
- /* Unless paused - in an HTTP/2 connection we can basically always get a
- frame so we should always be ready for one */
- bitmap |= GETSOCK_READSOCK(0);
-
- /* we're (still uploading OR the HTTP/2 layer wants to send data) AND
- there's a window to send data in */
- if((((k->keepon & KEEP_SENDBITS) == KEEP_SEND) ||
- nghttp2_session_want_write(ctx->h2)) &&
- (nghttp2_session_get_remote_window_size(ctx->h2) &&
- nghttp2_session_get_stream_remote_window_size(ctx->h2,
- stream->id)))
- bitmap |= GETSOCK_WRITESOCK(0);
+ if(ctx->h2 && (want_recv || want_send)) {
+ struct stream_ctx *stream = H2_STREAM_CTX(data);
+ curl_socket_t sock = Curl_conn_cf_get_socket(cf, data);
+ struct cf_call_data save;
+ bool c_exhaust, s_exhaust;
- CF_DATA_RESTORE(cf, save);
- return bitmap;
+ CF_DATA_SAVE(save, cf, data);
+ c_exhaust = !nghttp2_session_get_remote_window_size(ctx->h2);
+ s_exhaust = stream && stream->id >= 0 &&
+ !nghttp2_session_get_stream_remote_window_size(ctx->h2,
+ stream->id);
+ want_recv = (want_recv || c_exhaust || s_exhaust);
+ want_send = (!s_exhaust && want_send) ||
+ (!c_exhaust && nghttp2_session_want_write(ctx->h2));
+
+ Curl_pollset_set(data, ps, sock, want_recv, want_send);
+ CF_DATA_RESTORE(cf, save);
+ }
}
-
static CURLcode cf_h2_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done)
@@ -2601,7 +2578,7 @@ struct Curl_cftype Curl_cft_nghttp2 = {
cf_h2_connect,
cf_h2_close,
Curl_cf_def_get_host,
- cf_h2_get_select_socks,
+ cf_h2_adjust_pollset,
cf_h2_data_pending,
cf_h2_send,
cf_h2_recv,
lib/http_proxy.c+1 -1
@@ -299,7 +299,7 @@ struct Curl_cftype Curl_cft_http_proxy = {
http_proxy_cf_connect,
http_proxy_cf_close,
Curl_cf_http_proxy_get_host,
- Curl_cf_def_get_select_socks,
+ Curl_cf_def_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
lib/multi.c+106 -143
@@ -1024,49 +1024,57 @@ static int protocol_getsock(struct Curl_easy *data,
{
if(conn->handler->proto_getsock)
return conn->handler->proto_getsock(data, conn, socks);
- return Curl_conn_get_select_socks(data, FIRSTSOCKET, socks);
+ return GETSOCK_BLANK;
}
-/* returns bitmapped flags for this handle and its sockets. The 'socks[]'
- array contains MAX_SOCKSPEREASYHANDLE entries. */
-static int multi_getsock(struct Curl_easy *data,
- curl_socket_t *socks)
+/* Initializes `poll_set` with the current socket poll actions needed
+ * for transfer `data`. */
+static void multi_getsock(struct Curl_easy *data,
+ struct easy_pollset *ps)
{
- struct connectdata *conn = data->conn;
/* The no connection case can happen when this is called from
curl_multi_remove_handle() => singlesocket() => multi_getsock().
*/
- if(!conn)
- return 0;
+ Curl_pollset_reset(data, ps);
+ if(!data->conn)
+ return;
switch(data->mstate) {
default:
- return 0;
+ break;
case MSTATE_RESOLVING:
- return Curl_resolv_getsock(data, socks);
+ Curl_pollset_add_socks2(data, ps, Curl_resolv_getsock);
+ /* connection filters are not involved in this phase */
+ return;
case MSTATE_PROTOCONNECTING:
case MSTATE_PROTOCONNECT:
- return protocol_getsock(data, conn, socks);
+ Curl_pollset_add_socks(data, ps, protocol_getsock);
+ break;
case MSTATE_DO:
case MSTATE_DOING:
- return doing_getsock(data, conn, socks);
+ Curl_pollset_add_socks(data, ps, doing_getsock);
+ break;
case MSTATE_TUNNELING:
case MSTATE_CONNECTING:
- return Curl_conn_get_select_socks(data, FIRSTSOCKET, socks);
+ break;
case MSTATE_DOING_MORE:
- return domore_getsock(data, conn, socks);
+ Curl_pollset_add_socks(data, ps, domore_getsock);
+ break;
case MSTATE_DID: /* since is set after DO is completed, we switch to
waiting for the same as the PERFORMING state */
case MSTATE_PERFORMING:
- return Curl_single_getsock(data, conn, socks);
+ Curl_pollset_add_socks(data, ps, Curl_single_getsock);
+ break;
}
+ /* Let connection filters add/remove as needed */
+ Curl_conn_adjust_pollset(data, ps);
}
CURLMcode curl_multi_fdset(struct Curl_multi *multi,
@@ -1078,8 +1086,8 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
and then we must make sure that is done. */
struct Curl_easy *data;
int this_max_fd = -1;
- curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
- int i;
+ struct easy_pollset ps;
+ unsigned int i;
(void)exc_fd_set; /* not used */
if(!GOOD_MULTI_HANDLE(multi))
@@ -1088,29 +1096,20 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
if(multi->in_callback)
return CURLM_RECURSIVE_API_CALL;
+ memset(&ps, 0, sizeof(ps));
for(data = multi->easyp; data; data = data->next) {
- int bitmap;
-#ifdef __clang_analyzer_
- /* to prevent "The left operand of '>=' is a garbage value" warnings */
- memset(sockbunch, 0, sizeof(sockbunch));
-#endif
- bitmap = multi_getsock(data, sockbunch);
-
- for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
- if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) {
- if(!FDSET_SOCK(sockbunch[i]))
- /* pretend it doesn't exist */
- continue;
- if(bitmap & GETSOCK_READSOCK(i))
- FD_SET(sockbunch[i], read_fd_set);
- if(bitmap & GETSOCK_WRITESOCK(i))
- FD_SET(sockbunch[i], write_fd_set);
- if((int)sockbunch[i] > this_max_fd)
- this_max_fd = (int)sockbunch[i];
- }
- else {
- break;
- }
+ multi_getsock(data, &ps);
+
+ for(i = 0; i < ps.num; i++) {
+ if(!FDSET_SOCK(ps.sockets[i]))
+ /* pretend it doesn't exist */
+ continue;
+ if(ps.actions[i] & CURL_POLL_IN)
+ FD_SET(ps.sockets[i], read_fd_set);
+ if(ps.actions[i] & CURL_POLL_OUT)
+ FD_SET(ps.sockets[i], write_fd_set);
+ if((int)ps.sockets[i] > this_max_fd)
+ this_max_fd = (int)ps.sockets[i];
}
}
@@ -1146,9 +1145,8 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
bool use_wakeup)
{
struct Curl_easy *data;
- curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
- int bitmap;
- unsigned int i;
+ struct easy_pollset ps;
+ size_t i;
unsigned int nfds = 0;
unsigned int curlfds;
long timeout_internal;
@@ -1174,17 +1172,10 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
return CURLM_BAD_FUNCTION_ARGUMENT;
/* Count up how many fds we have from the multi handle */
+ memset(&ps, 0, sizeof(ps));
for(data = multi->easyp; data; data = data->next) {
- bitmap = multi_getsock(data, sockbunch);
-
- for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
- if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) {
- ++nfds;
- }
- else {
- break;
- }
- }
+ multi_getsock(data, &ps);
+ nfds += ps.num;
}
/* If the internally desired timeout is actually shorter than requested from
@@ -1225,40 +1216,35 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
if(curlfds) {
/* Add the curl handles to our pollfds first */
for(data = multi->easyp; data; data = data->next) {
- bitmap = multi_getsock(data, sockbunch);
+ multi_getsock(data, &ps);
- for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
- if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) {
- struct pollfd *ufd = &ufds[nfds++];
-#ifdef USE_WINSOCK
- long mask = 0;
-#endif
- ufd->fd = sockbunch[i];
- ufd->events = 0;
- if(bitmap & GETSOCK_READSOCK(i)) {
+ for(i = 0; i < ps.num; i++) {
+ struct pollfd *ufd = &ufds[nfds++];
#ifdef USE_WINSOCK
- mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
+ long mask = 0;
#endif
- ufd->events |= POLLIN;
- }
- if(bitmap & GETSOCK_WRITESOCK(i)) {
+ ufd->fd = ps.sockets[i];
+ ufd->events = 0;
+ if(ps.actions[i] & CURL_POLL_IN) {
#ifdef USE_WINSOCK
- mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
- reset_socket_fdwrite(sockbunch[i]);
+ mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
#endif
- ufd->events |= POLLOUT;
- }
+ ufd->events |= POLLIN;
+ }
+ if(ps.actions[i] & CURL_POLL_OUT) {
#ifdef USE_WINSOCK
- if(WSAEventSelect(sockbunch[i], multi->wsa_event, mask) != 0) {
- if(ufds_malloc)
- free(ufds);
- return CURLM_INTERNAL_ERROR;
- }
+ mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
+ reset_socket_fdwrite(ps.sockets[i]);
#endif
+ ufd->events |= POLLOUT;
}
- else {
- break;
+#ifdef USE_WINSOCK
+ if(WSAEventSelect(ps.sockets[i], multi->wsa_event, mask) != 0) {
+ if(ufds_malloc)
+ free(ufds);
+ return CURLM_INTERNAL_ERROR;
}
+#endif
}
}
}
@@ -1370,21 +1356,16 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
if(curlfds) {
for(data = multi->easyp; data; data = data->next) {
- bitmap = multi_getsock(data, sockbunch);
-
- for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
- if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) {
- wsa_events.lNetworkEvents = 0;
- if(WSAEnumNetworkEvents(sockbunch[i], NULL, &wsa_events) == 0) {
- if(ret && !pollrc && wsa_events.lNetworkEvents)
- retcode++;
- }
- WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
- }
- else {
- /* break on entry not checked for being readable or writable */
- break;
+ multi_getsock(data, &ps);
+
+ for(i = 0; i < ps.num; i++) {
+ wsa_events.lNetworkEvents = 0;
+ if(WSAEnumNetworkEvents(ps.sockets[i], NULL,
+ &wsa_events) == 0) {
+ if(ret && !pollrc && wsa_events.lNetworkEvents)
+ retcode++;
}
+ WSAEventSelect(ps.sockets[i], multi->wsa_event, 0);
}
}
}
@@ -2879,53 +2860,36 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
static CURLMcode singlesocket(struct Curl_multi *multi,
struct Curl_easy *data)
{
- curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
- int i;
+ struct easy_pollset cur_poll;
+ unsigned int i;
struct Curl_sh_entry *entry;
curl_socket_t s;
- int num;
- unsigned int curraction;
- unsigned char actions[MAX_SOCKSPEREASYHANDLE];
int rc;
- for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
- socks[i] = CURL_SOCKET_BAD;
-
/* Fill in the 'current' struct with the state as it is now: what sockets to
supervise and for what actions */
- curraction = multi_getsock(data, socks);
+ multi_getsock(data, &cur_poll);
/* We have 0 .. N sockets already and we get to know about the 0 .. M
sockets we should have from now on. Detect the differences, remove no
longer supervised ones and add new ones */
/* walk over the sockets we got right now */
- for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) &&
- (curraction & GETSOCK_MASK_RW(i));
- i++) {
- unsigned char action = CURL_POLL_NONE;
- unsigned char prevaction = 0;
+ for(i = 0; i < cur_poll.num; i++) {
+ unsigned char cur_action = cur_poll.actions[i];
+ unsigned char last_action = 0;
int comboaction;
- bool sincebefore = FALSE;
- s = socks[i];
+ s = cur_poll.sockets[i];
/* get it from the hash */
entry = sh_getentry(&multi->sockhash, s);
-
- if(curraction & GETSOCK_READSOCK(i))
- action |= CURL_POLL_IN;
- if(curraction & GETSOCK_WRITESOCK(i))
- action |= CURL_POLL_OUT;
-
- actions[i] = action;
if(entry) {
/* check if new for this transfer */
- int j;
- for(j = 0; j< data->numsocks; j++) {
- if(s == data->sockets[j]) {
- prevaction = data->actions[j];
- sincebefore = TRUE;
+ unsigned int j;
+ for(j = 0; j< data->last_poll.num; j++) {
+ if(s == data->last_poll.sockets[j]) {
+ last_action = data->last_poll.actions[j];
break;
}
}
@@ -2937,23 +2901,23 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
/* fatal */
return CURLM_OUT_OF_MEMORY;
}
- if(sincebefore && (prevaction != action)) {
+ if(last_action && (last_action != cur_action)) {
/* Socket was used already, but different action now */
- if(prevaction & CURL_POLL_IN)
+ if(last_action & CURL_POLL_IN)
entry->readers--;
- if(prevaction & CURL_POLL_OUT)
+ if(last_action & CURL_POLL_OUT)
entry->writers--;
- if(action & CURL_POLL_IN)
+ if(cur_action & CURL_POLL_IN)
entry->readers++;
- if(action & CURL_POLL_OUT)
+ if(cur_action & CURL_POLL_OUT)
entry->writers++;
}
- else if(!sincebefore) {
- /* a new user */
+ else if(!last_action) {
+ /* a new transfer using this socket */
entry->users++;
- if(action & CURL_POLL_IN)
+ if(cur_action & CURL_POLL_IN)
entry->readers++;
- if(action & CURL_POLL_OUT)
+ if(cur_action & CURL_POLL_OUT)
entry->writers++;
/* add 'data' to the transfer hash on this socket! */
@@ -2968,7 +2932,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
(entry->readers ? CURL_POLL_IN : 0);
/* socket existed before and has the same action set as before */
- if(sincebefore && ((int)entry->action == comboaction))
+ if(last_action && ((int)entry->action == comboaction))
/* same, continue */
continue;
@@ -2976,6 +2940,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
set_in_callback(multi, TRUE);
rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
entry->socketp);
+
set_in_callback(multi, FALSE);
if(rc == -1) {
multi->dead = TRUE;
@@ -2986,16 +2951,15 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
entry->action = comboaction; /* store the current action state */
}
- num = i; /* number of sockets */
-
- /* when we've walked over all the sockets we should have right now, we must
- make sure to detect sockets that are removed */
- for(i = 0; i< data->numsocks; i++) {
- int j;
+ /* Check for last_poll.sockets that no longer appear in cur_poll.sockets.
+ * Need to remove the easy handle from the multi->sockhash->transfers and
+ * remove multi->sockhash entry when this was the last transfer */
+ for(i = 0; i< data->last_poll.num; i++) {
+ unsigned int j;
bool stillused = FALSE;
- s = data->sockets[i];
- for(j = 0; j < num; j++) {
- if(s == socks[j]) {
+ s = data->last_poll.sockets[i];
+ for(j = 0; j < cur_poll.num; j++) {
+ if(s == cur_poll.sockets[j]) {
/* this is still supervised */
stillused = TRUE;
break;
@@ -3008,7 +2972,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
/* if this is NULL here, the socket has been closed and notified so
already by Curl_multi_closed() */
if(entry) {
- unsigned char oldactions = data->actions[i];
+ unsigned char oldactions = data->last_poll.actions[i];
/* this socket has been removed. Decrease user count */
entry->users--;
if(oldactions & CURL_POLL_OUT)
@@ -3036,11 +3000,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
}
}
}
- } /* for loop over numsocks */
+ } /* for loop over num */
- memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
- memcpy(data->actions, actions, num*sizeof(char));
- data->numsocks = num;
+ /* Remember for next time */
+ memcpy(&data->last_poll, &cur_poll, sizeof(data->last_poll));
return CURLM_OK;
}
lib/socks.c+7 -10
@@ -1170,32 +1170,29 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf,
return result;
}
-static int socks_cf_get_select_socks(struct Curl_cfilter *cf,
+static void socks_cf_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
struct socks_state *sx = cf->ctx;
- int fds;
- fds = cf->next->cft->get_select_socks(cf->next, data, socks);
- if(!fds && cf->next->connected && !cf->connected && sx) {
+ if(!cf->connected && sx) {
/* If we are not connected, the filter below is and has nothing
* to wait on, we determine what to wait for. */
- socks[0] = Curl_conn_cf_get_socket(cf, data);
+ curl_socket_t sock = Curl_conn_cf_get_socket(cf, data);
switch(sx->state) {
case CONNECT_RESOLVING:
case CONNECT_SOCKS_READ:
case CONNECT_AUTH_READ:
case CONNECT_REQ_READ:
case CONNECT_REQ_READ_MORE:
- fds = GETSOCK_READSOCK(0);
+ Curl_pollset_set_in_only(data, ps, sock);
break;
default:
- fds = GETSOCK_WRITESOCK(0);
+ Curl_pollset_set_out_only(data, ps, sock);
break;
}
}
- return fds;
}
static void socks_proxy_cf_close(struct Curl_cfilter *cf,
@@ -1240,7 +1237,7 @@ struct Curl_cftype Curl_cft_socks_proxy = {
socks_proxy_cf_connect,
socks_proxy_cf_close,
socks_cf_get_host,
- socks_cf_get_select_socks,
+ socks_cf_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
lib/urldata.h+17 -4
@@ -571,6 +571,13 @@ struct hostname {
#define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE)
#define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE)
+/* transfer wants to send is not PAUSE or HOLD */
+#define CURL_WANT_SEND(data) \
+ (((data)->req.keepon & KEEP_SENDBITS) == KEEP_SEND)
+/* transfer receive is not on PAUSE or HOLD */
+#define CURL_WANT_RECV(data) \
+ (!((data)->req.keepon & (KEEP_RECV_PAUSE|KEEP_RECV_HOLD)))
+
#if defined(CURLRES_ASYNCH) || !defined(CURL_DISABLE_DOH)
#define USE_CURL_ASYNC
struct Curl_async {
@@ -589,6 +596,15 @@ struct Curl_async {
#define FIRSTSOCKET 0
#define SECONDARYSOCKET 1
+/* Polling requested by an easy handle.
+ * `action` is CURL_POLL_IN, CURL_POLL_OUT or CURL_POLL_INOUT.
+ */
+struct easy_pollset {
+ curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
+ unsigned int num;
+ unsigned char actions[MAX_SOCKSPEREASYHANDLE];
+};
+
enum expect100 {
EXP100_SEND_DATA, /* enough waiting, just send the body now */
EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */
@@ -1974,10 +1990,7 @@ struct Curl_easy {
particular order. Note that all sockets are added to the sockhash, where
the state etc are also kept. This array is mostly used to detect when a
socket is to be removed from the hash. See singlesocket(). */
- curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
- unsigned char actions[MAX_SOCKSPEREASYHANDLE]; /* action for each socket in
- sockets[] */
- int numsocks;
+ struct easy_pollset last_poll;
struct Names dns;
struct Curl_multi *multi; /* if non-NULL, points to the multi handle
lib/vquic/curl_msh3.c+6 -12
@@ -672,31 +672,25 @@ out:
return nwritten;
}
-static int cf_msh3_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *socks)
+static void cf_msh3_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps)
{
struct cf_msh3_ctx *ctx = cf->ctx;
struct stream_ctx *stream = H3_STREAM_CTX(data);
- int bitmap = GETSOCK_BLANK;
struct cf_call_data save;
CF_DATA_SAVE(save, cf, data);
if(stream && ctx->sock[SP_LOCAL] != CURL_SOCKET_BAD) {
- socks[0] = ctx->sock[SP_LOCAL];
-
if(stream->recv_error) {
- bitmap |= GETSOCK_READSOCK(0);
+ Curl_pollset_add_in(data, ps, ctx->sock[SP_LOCAL]);
drain_stream(cf, data);
}
else if(stream->req) {
- bitmap |= GETSOCK_READSOCK(0);
+ Curl_pollset_add_out(data, ps, ctx->sock[SP_LOCAL]);
drain_stream(cf, data);
}
}
- CURL_TRC_CF(data, cf, "select_sock -> %d", bitmap);
- CF_DATA_RESTORE(cf, save);
- return bitmap;
}
static bool cf_msh3_data_pending(struct Curl_cfilter *cf,
@@ -1025,7 +1019,7 @@ struct Curl_cftype Curl_cft_http3 = {
cf_msh3_connect,
cf_msh3_close,
Curl_cf_def_get_host,
- cf_msh3_get_select_socks,
+ cf_msh3_adjust_pollset,
cf_msh3_data_pending,
cf_msh3_send,
cf_msh3_recv,
lib/vquic/curl_ngtcp2.c+76 -48
@@ -191,6 +191,7 @@ struct h3_stream_ctx {
bool closed; /* TRUE on stream close */
bool reset; /* TRUE on stream reset */
bool send_closed; /* stream is local closed */
+ BIT(quic_flow_blocked); /* stream is blocked by QUIC flow control */
};
#define H3_STREAM_CTX(d) ((struct h3_stream_ctx *)(((d) && (d)->req.p.http)? \
@@ -249,6 +250,43 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
}
}
+static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int64_t stream_id)
+{
+ struct Curl_easy *sdata;
+
+ (void)cf;
+ if(H3_STREAM_ID(data) == stream_id) {
+ return data;
+ }
+ else {
+ DEBUGASSERT(data->multi);
+ for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
+ if((sdata->conn == data->conn) && H3_STREAM_ID(sdata) == stream_id) {
+ return sdata;
+ }
+ }
+ }
+ return NULL;
+}
+
+static void h3_drain_stream(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
+ unsigned char bits;
+
+ (void)cf;
+ bits = CURL_CSELECT_IN;
+ if(stream && stream->upload_left && !stream->send_closed)
+ bits |= CURL_CSELECT_OUT;
+ if(data->state.dselect_bits != bits) {
+ data->state.dselect_bits = bits;
+ Curl_expire(data, 0, EXPIRE_RUN_NOW);
+ }
+}
+
/* ngtcp2 default congestion controller does not perform pacing. Limit
the maximum packet burst to MAX_PKT_BURST packets. */
#define MAX_PKT_BURST 10
@@ -915,6 +953,9 @@ static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id,
{
struct Curl_cfilter *cf = user_data;
struct cf_ngtcp2_ctx *ctx = cf->ctx;
+ struct Curl_easy *data = CF_DATA_CURRENT(cf);
+ struct Curl_easy *s_data;
+ struct h3_stream_ctx *stream;
int rv;
(void)tconn;
(void)max_data;
@@ -924,7 +965,13 @@ static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id,
if(rv) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
-
+ s_data = get_stream_easy(cf, data, stream_id);
+ stream = H3_STREAM_CTX(s_data);
+ if(stream && stream->quic_flow_blocked) {
+ CURL_TRC_CF(data, cf, "[%" PRId64 "] unblock quic flow", stream_id);
+ stream->quic_flow_blocked = FALSE;
+ h3_drain_stream(cf, data);
+ }
return 0;
}
@@ -1077,46 +1124,29 @@ static CURLcode check_and_set_expiry(struct Curl_cfilter *cf,
return CURLE_OK;
}
-static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
+static void cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct SingleRequest *k = &data->req;
- int rv = GETSOCK_BLANK;
- struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
- struct cf_call_data save;
-
- CF_DATA_SAVE(save, cf, data);
- socks[0] = ctx->q.sockfd;
-
- /* in HTTP/3 we can always get a frame, so check read */
- rv |= GETSOCK_READSOCK(0);
-
- /* we're still uploading or the HTTP/2 layer wants to send data */
- if((k->keepon & KEEP_SENDBITS) == KEEP_SEND &&
- ngtcp2_conn_get_cwnd_left(ctx->qconn) &&
- ngtcp2_conn_get_max_data_left(ctx->qconn) &&
- stream && nghttp3_conn_is_stream_writable(ctx->h3conn, stream->id))
- rv |= GETSOCK_WRITESOCK(0);
+ bool want_recv = CURL_WANT_RECV(data);
+ bool want_send = CURL_WANT_SEND(data);
- CF_DATA_RESTORE(cf, save);
- return rv;
-}
-
-static void h3_drain_stream(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
- unsigned char bits;
+ if(ctx->qconn && (want_recv || want_send)) {
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
+ struct cf_call_data save;
+ bool c_exhaust, s_exhaust;
- (void)cf;
- bits = CURL_CSELECT_IN;
- if(stream && stream->upload_left && !stream->send_closed)
- bits |= CURL_CSELECT_OUT;
- if(data->state.dselect_bits != bits) {
- data->state.dselect_bits = bits;
- Curl_expire(data, 0, EXPIRE_RUN_NOW);
+ CF_DATA_SAVE(save, cf, data);
+ c_exhaust = !ngtcp2_conn_get_cwnd_left(ctx->qconn) ||
+ !ngtcp2_conn_get_max_data_left(ctx->qconn);
+ s_exhaust = stream && stream->id >= 0 && stream->quic_flow_blocked;
+ want_recv = (want_recv || c_exhaust || s_exhaust);
+ want_send = (!s_exhaust && want_send) ||
+ !Curl_bufq_is_empty(&ctx->q.sendbuf);
+
+ Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send);
+ CF_DATA_RESTORE(cf, save);
}
}
@@ -1145,7 +1175,6 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
else {
CURL_TRC_CF(data, cf, "[%" PRId64 "] CLOSED", stream->id);
}
- data->req.keepon &= ~KEEP_SEND_HOLD;
h3_drain_stream(cf, data);
return 0;
}
@@ -1577,12 +1606,6 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
if(rv) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
- if((data->req.keepon & KEEP_SEND_HOLD) &&
- (data->req.keepon & KEEP_SEND)) {
- data->req.keepon &= ~KEEP_SEND_HOLD;
- h3_drain_stream(cf, data);
- CURL_TRC_CF(data, cf, "[%" PRId64 "] unpausing acks", stream_id);
- }
}
return 0;
}
@@ -1864,15 +1887,13 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
if(stream && sent > 0 && stream->sendbuf_len_in_flight) {
/* We have unacknowledged DATA and cannot report success to our
* caller. Instead we EAGAIN and remember how much we have already
- * "written" into our various internal connection buffers.
- * We put the stream upload on HOLD, until this gets ACKed. */
+ * "written" into our various internal connection buffers. */
stream->upload_blocked_len = sent;
CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_send(len=%zu), "
"%zu bytes in flight -> EGAIN", stream->id, len,
stream->sendbuf_len_in_flight);
*err = CURLE_AGAIN;
sent = -1;
- data->req.keepon |= KEEP_SEND_HOLD;
}
out:
@@ -2085,11 +2106,18 @@ static ssize_t read_pkt_to_send(void *userp,
}
else if(n < 0) {
switch(n) {
- case NGTCP2_ERR_STREAM_DATA_BLOCKED:
+ case NGTCP2_ERR_STREAM_DATA_BLOCKED: {
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(x->data);
DEBUGASSERT(ndatalen == -1);
nghttp3_conn_block_stream(ctx->h3conn, stream_id);
+ CURL_TRC_CF(x->data, x->cf, "[%" PRId64 "] block quic flow",
+ stream_id);
+ DEBUGASSERT(stream);
+ if(stream)
+ stream->quic_flow_blocked = TRUE;
n = 0;
break;
+ }
case NGTCP2_ERR_STREAM_SHUT_WR:
DEBUGASSERT(ndatalen == -1);
nghttp3_conn_shutdown_stream_write(ctx->h3conn, stream_id);
@@ -2714,7 +2742,7 @@ struct Curl_cftype Curl_cft_http3 = {
cf_ngtcp2_connect,
cf_ngtcp2_close,
Curl_cf_def_get_host,
- cf_ngtcp2_get_select_socks,
+ cf_ngtcp2_adjust_pollset,
cf_ngtcp2_data_pending,
cf_ngtcp2_send,
cf_ngtcp2_recv,
lib/vquic/curl_quiche.c+34 -75
@@ -105,7 +105,6 @@ struct cf_quiche_ctx {
struct bufc_pool stream_bufcp; /* chunk pool for streams */
curl_off_t data_recvd;
uint64_t max_idle_ms; /* max idle time for QUIC conn */
- size_t sends_on_hold; /* # of streams with SEND_HOLD set */
BIT(goaway); /* got GOAWAY from server */
BIT(got_first_byte); /* if first byte was received */
BIT(x509_store_setup); /* if x509 store has been set up */
@@ -240,6 +239,7 @@ struct stream_ctx {
bool send_closed; /* stream is locally closed */
bool resp_hds_complete; /* complete, final response has been received */
bool resp_got_header; /* TRUE when h3 stream has recvd some HEADER */
+ BIT(quic_flow_blocked); /* stream is blocked by QUIC flow control */
};
#define H3_STREAM_CTX(d) ((struct stream_ctx *)(((d) && (d)->req.p.http)? \
@@ -249,56 +249,20 @@ struct stream_ctx {
#define H3_STREAM_ID(d) (H3_STREAM_CTX(d)? \
H3_STREAM_CTX(d)->id : -2)
-static bool stream_send_is_suspended(struct Curl_easy *data)
-{
- return (data->req.keepon & KEEP_SEND_HOLD);
-}
-
-static void stream_send_suspend(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct cf_quiche_ctx *ctx = cf->ctx;
-
- if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) {
- data->req.keepon |= KEEP_SEND_HOLD;
- ++ctx->sends_on_hold;
- if(H3_STREAM_ID(data) >= 0)
- CURL_TRC_CF(data, cf, "[%"PRId64"] suspend sending",
- H3_STREAM_ID(data));
- else
- CURL_TRC_CF(data, cf, "[%s] suspend sending", data->state.url);
- }
-}
-
-static void stream_send_resume(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct cf_quiche_ctx *ctx = cf->ctx;
-
- if(stream_send_is_suspended(data)) {
- data->req.keepon &= ~KEEP_SEND_HOLD;
- --ctx->sends_on_hold;
- if(H3_STREAM_ID(data) >= 0)
- CURL_TRC_CF(data, cf, "[%"PRId64"] resume sending",
- H3_STREAM_ID(data));
- else
- CURL_TRC_CF(data, cf, "[%s] resume sending", data->state.url);
- Curl_expire(data, 0, EXPIRE_RUN_NOW);
- }
-}
-
static void check_resumes(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
- struct cf_quiche_ctx *ctx = cf->ctx;
struct Curl_easy *sdata;
-
- if(ctx->sends_on_hold) {
- DEBUGASSERT(data->multi);
- for(sdata = data->multi->easyp;
- sdata && ctx->sends_on_hold; sdata = sdata->next) {
- if(stream_send_is_suspended(sdata)) {
- stream_send_resume(cf, sdata);
+ struct stream_ctx *stream;
+
+ DEBUGASSERT(data->multi);
+ for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
+ if(sdata->conn == data->conn) {
+ stream = H3_STREAM_CTX(sdata);
+ if(stream && stream->quic_flow_blocked) {
+ stream->quic_flow_blocked = FALSE;
+ Curl_expire(data, 0, EXPIRE_RUN_NOW);
+ CURL_TRC_CF(data, cf, "[%"PRId64"] unblock", stream->id);
}
}
}
@@ -327,16 +291,11 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct cf_quiche_ctx *ctx = cf->ctx;
struct stream_ctx *stream = H3_STREAM_CTX(data);
(void)cf;
if(stream) {
CURL_TRC_CF(data, cf, "[%"PRId64"] easy handle is done", stream->id);
- if(stream_send_is_suspended(data)) {
- data->req.keepon &= ~KEEP_SEND_HOLD;
- --ctx->sends_on_hold;
- }
Curl_bufq_free(&stream->recvbuf);
Curl_h1_req_parse_free(&stream->h1);
free(stream);
@@ -590,7 +549,6 @@ static CURLcode h3_process_event(struct Curl_cfilter *cf,
}
stream->closed = TRUE;
streamclose(cf->conn, "End of stream");
- data->req.keepon &= ~KEEP_SEND_HOLD;
break;
case QUICHE_H3_EVENT_GOAWAY:
@@ -1037,9 +995,8 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf,
if(QUICHE_H3_ERR_STREAM_BLOCKED == stream3_id) {
/* quiche seems to report this error if the connection window is
* exhausted. Which happens frequently and intermittent. */
- CURL_TRC_CF(data, cf, "send_request(%s) rejected with BLOCKED",
- data->state.url);
- stream_send_suspend(cf, data);
+ CURL_TRC_CF(data, cf, "[%"PRId64"] blocked", stream->id);
+ stream->quic_flow_blocked = TRUE;
*err = CURLE_AGAIN;
nwritten = -1;
goto out;
@@ -1108,7 +1065,7 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data,
if(!quiche_conn_stream_writable(ctx->qconn, stream->id, len)) {
CURL_TRC_CF(data, cf, "[%" PRId64 "] send_body(len=%zu) "
"-> window exhausted", stream->id, len);
- stream_send_suspend(cf, data);
+ stream->quic_flow_blocked = TRUE;
}
*err = CURLE_AGAIN;
nwritten = -1;
@@ -1177,30 +1134,32 @@ static bool stream_is_writeable(struct Curl_cfilter *cf,
struct cf_quiche_ctx *ctx = cf->ctx;
struct stream_ctx *stream = H3_STREAM_CTX(data);
- return stream &&
- quiche_conn_stream_writable(ctx->qconn, (uint64_t)stream->id, 1);
+ return stream && (quiche_conn_stream_writable(ctx->qconn,
+ (uint64_t)stream->id, 1) > 0);
}
-static int cf_quiche_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *socks)
+static void cf_quiche_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps)
{
struct cf_quiche_ctx *ctx = cf->ctx;
- struct SingleRequest *k = &data->req;
- int rv = GETSOCK_BLANK;
+ bool want_recv = CURL_WANT_RECV(data);
+ bool want_send = CURL_WANT_SEND(data);
- socks[0] = ctx->q.sockfd;
-
- /* in an HTTP/3 connection we can basically always get a frame so we should
- always be ready for one */
- rv |= GETSOCK_READSOCK(0);
+ if(ctx->qconn && (want_recv || want_send)) {
+ struct stream_ctx *stream = H3_STREAM_CTX(data);
+ bool c_exhaust, s_exhaust;
- /* we're still uploading or the HTTP/3 layer wants to send data */
- if(((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
- && stream_is_writeable(cf, data))
- rv |= GETSOCK_WRITESOCK(0);
+ c_exhaust = FALSE; /* Have not found any call in quiche that tells
+ us if the connection itself is blocked */
+ s_exhaust = stream && stream->id >= 0 &&
+ (stream->quic_flow_blocked || !stream_is_writeable(cf, data));
+ want_recv = (want_recv || c_exhaust || s_exhaust);
+ want_send = (!s_exhaust && want_send) ||
+ !Curl_bufq_is_empty(&ctx->q.sendbuf);
- return rv;
+ Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send);
+ }
}
/*
@@ -1674,7 +1633,7 @@ struct Curl_cftype Curl_cft_http3 = {
cf_quiche_connect,
cf_quiche_close,
Curl_cf_def_get_host,
- cf_quiche_get_select_socks,
+ cf_quiche_adjust_pollset,
cf_quiche_data_pending,
cf_quiche_send,
cf_quiche_recv,
lib/vtls/bearssl.c+18 -18
@@ -749,26 +749,26 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf,
return CURLE_OK;
}
-static int bearssl_get_select_socks(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- curl_socket_t *socks)
+static void bearssl_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps)
{
- struct ssl_connect_data *connssl = cf->ctx;
- curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data);
-
- if(sock == CURL_SOCKET_BAD)
- return GETSOCK_BLANK;
- else {
- struct bearssl_ssl_backend_data *backend =
- (struct bearssl_ssl_backend_data *)connssl->backend;
- unsigned state = br_ssl_engine_current_state(&backend->ctx.eng);
- if(state & BR_SSL_SENDREC) {
- socks[0] = sock;
- return GETSOCK_WRITESOCK(0);
+ if(!cf->connected) {
+ curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data);
+ if(sock != CURL_SOCKET_BAD) {
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
+ unsigned state = br_ssl_engine_current_state(&backend->ctx.eng);
+
+ if(state & BR_SSL_SENDREC) {
+ Curl_pollset_set_out_only(data, ps, sock);
+ }
+ else {
+ Curl_pollset_set_in_only(data, ps, sock);
+ }
}
}
- socks[0] = sock;
- return GETSOCK_READSOCK(0);
}
static CURLcode bearssl_run_until(struct Curl_cfilter *cf,
@@ -1210,7 +1210,7 @@ const struct Curl_ssl Curl_ssl_bearssl = {
Curl_none_cert_status_request, /* cert_status_request */
bearssl_connect, /* connect */
bearssl_connect_nonblocking, /* connect_nonblocking */
- bearssl_get_select_socks, /* getsock */
+ bearssl_adjust_pollset, /* adjust_pollset */
bearssl_get_internals, /* get_internals */
bearssl_close, /* close_one */
Curl_none_close_all, /* close_all */
lib/vtls/gtls.c+1 -1
@@ -1672,7 +1672,7 @@ const struct Curl_ssl Curl_ssl_gnutls = {
gtls_cert_status_request, /* cert_status_request */
gtls_connect, /* connect */
gtls_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_get_select_socks, /* getsock */
+ Curl_ssl_adjust_pollset, /* adjust_pollset */
gtls_get_internals, /* get_internals */
gtls_close, /* close_one */
Curl_none_close_all, /* close_all */
lib/vtls/mbedtls.c+1 -1
@@ -1274,7 +1274,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
Curl_none_cert_status_request, /* cert_status_request */
mbedtls_connect, /* connect */
mbedtls_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_get_select_socks, /* getsock */
+ Curl_ssl_adjust_pollset, /* adjust_pollset */
mbedtls_get_internals, /* get_internals */
mbedtls_close, /* close_one */
mbedtls_close_all, /* close_all */
lib/vtls/openssl.c+1 -1
@@ -4915,7 +4915,7 @@ const struct Curl_ssl Curl_ssl_openssl = {
ossl_cert_status_request, /* cert_status_request */
ossl_connect, /* connect */
ossl_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_get_select_socks,/* getsock */
+ Curl_ssl_adjust_pollset, /* adjust_pollset */
ossl_get_internals, /* get_internals */
ossl_close, /* close_one */
ossl_close_all, /* close_all */
lib/vtls/rustls.c+21 -25
@@ -589,32 +589,28 @@ cr_connect_nonblocking(struct Curl_cfilter *cf,
DEBUGASSERT(false);
}
-/* returns a bitmap of flags for this connection's first socket indicating
- whether we want to read or write */
-static int
-cr_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
- curl_socket_t *socks)
+static void cr_adjust_pollset(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct easy_pollset *ps)
{
- struct ssl_connect_data *const connssl = cf->ctx;
- curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
- struct rustls_ssl_backend_data *const backend =
- (struct rustls_ssl_backend_data *)connssl->backend;
- struct rustls_connection *rconn = NULL;
-
- (void)data;
- DEBUGASSERT(backend);
- rconn = backend->conn;
-
- if(rustls_connection_wants_write(rconn)) {
- socks[0] = sockfd;
- return GETSOCK_WRITESOCK(0);
- }
- if(rustls_connection_wants_read(rconn)) {
- socks[0] = sockfd;
- return GETSOCK_READSOCK(0);
+ if(!cf->connected) {
+ curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data);
+ struct ssl_connect_data *const connssl = cf->ctx;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
+ struct rustls_connection *rconn = NULL;
+
+ (void)data;
+ DEBUGASSERT(backend);
+ rconn = backend->conn;
+
+ if(rustls_connection_wants_write(rconn)) {
+ Curl_pollset_add_out(data, ps, sock);
+ }
+ if(rustls_connection_wants_read(rconn)) {
+ Curl_pollset_add_in(data, ps, sock);
+ }
}
-
- return GETSOCK_BLANK;
}
static void *
@@ -677,7 +673,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
Curl_none_cert_status_request, /* cert_status_request */
cr_connect, /* connect */
cr_connect_nonblocking, /* connect_nonblocking */
- cr_get_select_socks, /* get_select_socks */
+ cr_adjust_pollset, /* adjust_pollset */
cr_get_internals, /* get_internals */
cr_close, /* close_one */
Curl_none_close_all, /* close_all */
lib/vtls/schannel.c+1 -1
@@ -2777,7 +2777,7 @@ const struct Curl_ssl Curl_ssl_schannel = {
Curl_none_cert_status_request, /* cert_status_request */
schannel_connect, /* connect */
schannel_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_get_select_socks, /* getsock */
+ Curl_ssl_adjust_pollset, /* adjust_pollset */
schannel_get_internals, /* get_internals */
schannel_close, /* close_one */
Curl_none_close_all, /* close_all */
lib/vtls/sectransp.c+1 -1
@@ -3483,7 +3483,7 @@ const struct Curl_ssl Curl_ssl_sectransp = {
Curl_none_cert_status_request, /* cert_status_request */
sectransp_connect, /* connect */
sectransp_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_get_select_socks, /* getsock */
+ Curl_ssl_adjust_pollset, /* adjust_pollset */
sectransp_get_internals, /* get_internals */
sectransp_close, /* close_one */
Curl_none_close_all, /* close_all */
lib/vtls/vtls.c+25 -31
@@ -629,22 +629,21 @@ void Curl_ssl_close_all(struct Curl_easy *data)
Curl_ssl->close_all(data);
}
-int Curl_ssl_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
- curl_socket_t *socks)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data);
-
- if(sock == CURL_SOCKET_BAD)
- return GETSOCK_BLANK;
-
- if(connssl->connecting_state == ssl_connect_2_writing) {
- /* we are only interested in writing */
- socks[0] = sock;
- return GETSOCK_WRITESOCK(0);
+void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data,
+ struct easy_pollset *ps)
+{
+ if(!cf->connected) {
+ struct ssl_connect_data *connssl = cf->ctx;
+ curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data);
+ if(sock != CURL_SOCKET_BAD) {
+ if(connssl->connecting_state == ssl_connect_2_writing) {
+ Curl_pollset_set_out_only(data, ps, sock);
+ }
+ else {
+ Curl_pollset_set_in_only(data, ps, sock);
+ }
+ }
}
- socks[0] = sock;
- return GETSOCK_READSOCK(0);
}
/* Selects an SSL crypto engine
@@ -1156,13 +1155,13 @@ static CURLcode multissl_connect_nonblocking(struct Curl_cfilter *cf,
return Curl_ssl->connect_nonblocking(cf, data, done);
}
-static int multissl_get_select_socks(struct Curl_cfilter *cf,
+static void multissl_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
if(multissl_setup(NULL))
- return 0;
- return Curl_ssl->get_select_socks(cf, data, socks);
+ return;
+ Curl_ssl->adjust_pollset(cf, data, ps);
}
static void *multissl_get_internals(struct ssl_connect_data *connssl,
@@ -1214,7 +1213,7 @@ static const struct Curl_ssl Curl_ssl_multi = {
Curl_none_cert_status_request, /* cert_status_request */
multissl_connect, /* connect */
multissl_connect_nonblocking, /* connect_nonblocking */
- multissl_get_select_socks, /* getsock */
+ multissl_adjust_pollset, /* adjust_pollset */
multissl_get_internals, /* get_internals */
multissl_close, /* close_one */
Curl_none_close_all, /* close_all */
@@ -1599,22 +1598,17 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
return nread;
}
-static int ssl_cf_get_select_socks(struct Curl_cfilter *cf,
+static void ssl_cf_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
struct cf_call_data save;
- int fds = GETSOCK_BLANK;
- if(!cf->next->connected) {
- fds = cf->next->cft->get_select_socks(cf->next, data, socks);
- }
- else if(!cf->connected) {
+ if(!cf->connected) {
CF_DATA_SAVE(save, cf, data);
- fds = Curl_ssl->get_select_socks(cf, data, socks);
+ Curl_ssl->adjust_pollset(cf, data, ps);
CF_DATA_RESTORE(cf, save);
}
- return fds;
}
static CURLcode ssl_cf_cntrl(struct Curl_cfilter *cf,
@@ -1705,7 +1699,7 @@ struct Curl_cftype Curl_cft_ssl = {
ssl_cf_connect,
ssl_cf_close,
Curl_cf_def_get_host,
- ssl_cf_get_select_socks,
+ ssl_cf_adjust_pollset,
ssl_cf_data_pending,
ssl_cf_send,
ssl_cf_recv,
@@ -1723,7 +1717,7 @@ struct Curl_cftype Curl_cft_ssl_proxy = {
ssl_cf_connect,
ssl_cf_close,
Curl_cf_def_get_host,
- ssl_cf_get_select_socks,
+ ssl_cf_adjust_pollset,
ssl_cf_data_pending,
ssl_cf_send,
ssl_cf_recv,
lib/vtls/vtls_int.h+7 -10
@@ -118,14 +118,11 @@ struct Curl_ssl {
struct Curl_easy *data,
bool *done);
- /* If the SSL backend wants to read or write on this connection during a
- handshake, set socks[0] to the connection's FIRSTSOCKET, and return
- a bitmap indicating read or write with GETSOCK_WRITESOCK(0) or
- GETSOCK_READSOCK(0). Otherwise return GETSOCK_BLANK.
- Mandatory. */
- int (*get_select_socks)(struct Curl_cfilter *cf, struct Curl_easy *data,
- curl_socket_t *socks);
-
+ /* During handshake, adjust the pollset to include the socket
+ * for POLLOUT or POLLIN as needed.
+ * Mandatory. */
+ void (*adjust_pollset)(struct Curl_cfilter *cf, struct Curl_easy *data,
+ struct easy_pollset *ps);
void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info);
void (*close)(struct Curl_cfilter *cf, struct Curl_easy *data);
void (*close_all)(struct Curl_easy *data);
@@ -169,8 +166,8 @@ CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine);
CURLcode Curl_none_set_engine_default(struct Curl_easy *data);
struct curl_slist *Curl_none_engines_list(struct Curl_easy *data);
bool Curl_none_false_start(void);
-int Curl_ssl_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
- curl_socket_t *socks);
+void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data,
+ struct easy_pollset *ps);
/**
* Get the ssl_config_data in `data` that is relevant for cfilter `cf`.
lib/vtls/wolfssl.c+1 -1
@@ -1398,7 +1398,7 @@ const struct Curl_ssl Curl_ssl_wolfssl = {
Curl_none_cert_status_request, /* cert_status_request */
wolfssl_connect, /* connect */
wolfssl_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_get_select_socks, /* getsock */
+ Curl_ssl_adjust_pollset, /* adjust_pollset */
wolfssl_get_internals, /* get_internals */
wolfssl_close, /* close_one */
Curl_none_close_all, /* close_all */
tests/http/testenv/curl.py+2 -2
@@ -504,8 +504,8 @@ class CurlClient:
args = [self._curl, "-s", "--path-as-is"]
if with_headers:
args.extend(["-D", self._headerfile])
- if def_tracing is not False:
- args.extend(['-v', '--trace-config', 'ids,time'])
+ if def_tracing is not False and not self._silent:
+ args.extend(['-v', '--trace-ids', '--trace-time'])
if self.env.verbose > 1:
args.extend(['--trace-config', 'http/2,http/3,h2-proxy,h1-proxy'])
pass
tests/unit/unit2600.c+1 -1
@@ -162,7 +162,7 @@ static struct Curl_cftype cft_test = {
cf_test_connect,
Curl_cf_def_close,
Curl_cf_def_get_host,
- Curl_cf_def_get_select_socks,
+ Curl_cf_def_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,