ITADN
curl/curl/Issues

For Explicit FTPS mode, libcurl incorrectly reports connect timing.

#22587ClosedGLaDOS-418 创建于 8 天前
FTPconnecting & proxieslibcurl API
G
GLaDOS-418commented
### I did this Here's a simple program that can reproduce this: ```cpp #include <curl/curl.h> #include <cstdio> void version(); void print_duration(CURL* curl); int main(int argc, char **argv) { if (argc != 4) { std::fprintf(stderr, "Usage: %s URL USER PWD\n", argv[0]); return 1; } curl_global_init(CURL_GLOBAL_DEFAULT); version(); CURL *curl = curl_easy_init(); if (!curl) { curl_global_cleanup(); return 1; } curl_easy_setopt(curl, CURLOPT_URL, argv[1]); curl_easy_setopt(curl, CURLOPT_USERNAME, argv[2]); curl_easy_setopt(curl, CURLOPT_PASSWORD, argv[3]); // explicit ftps: connect using ftp://, then issue AUTH TLS. curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); CURLcode rc = curl_easy_perform(curl); if (rc != CURLE_OK) std::fprintf(stderr, "curl: %s\n", curl_easy_strerror(rc)); print_duration(curl); curl_easy_cleanup(curl); curl_global_cleanup(); return 0; } void version() { const curl_version_info_data* const info = curl_version_info(CURLVERSION_NOW); std::fprintf(stderr, "\nlibcurl metadata:\n" " version: %s\n" " host: %s\n" " ssl_version: %s\n", info->version ? info->version : "(none)", info->host ? info->host : "(none)", info->ssl_version ? info->ssl_version : "(none)"); std::fprintf(stderr, "\n"); } void print_duration(CURL* curl) { curl_off_t dns_us = 0; curl_off_t connect_us = 0; curl_off_t tls_us = 0; curl_off_t total_us = 0; curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME_T, &dns_us); curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME_T, &connect_us); curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME_T, &tls_us); curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &total_us); const curl_off_t dns_duration_us = dns_us; const curl_off_t connect_duration_us = connect_us - dns_us; const curl_off_t tls_duration_us = tls_us > connect_us ? tls_us - connect_us : 0; std::fprintf(stderr, "\nTimings:\n" " DNS: %.3f ms\n" " Connect: %.3f ms\n" " TLS: %.3f ms\n" " Total: %.3f ms\n", dns_duration_us / 1000.0, connect_duration_us / 1000.0, tls_duration_us / 1000.0, total_us / 1000.0); } ``` Now I compiled this against two libcurl versions 8.20 and 7.61 and tested against a public FTPS server: ``` url: ftp://demo.wftpserver.com uname/pwd: demo demo ``` ## libcurl v8.20 Here's what it reported with 8.20: ```bash $ ./eftps.new ftp://demo.wftpserver.com demo demo libcurl metadata: version: 8.20.0 host: x86_64-pc-linux-gnu ssl_version: OpenSSL/3.5.5 drwxr-xr-x 2 user group 0 Aug 14 16:29 upload drwxr-xr-x 2 user group 0 Jun 18 05:42 download Timings: DNS: 5.916 ms Connect: 260.026 ms TLS: 58.061 ms Total: 316.231 ms ``` which is wildly off from what was reported in wireshark (`6ms`): <img width="3224" height="222" alt="Image" src="https://github.com/user-attachments/assets/34983c89-3d55-4c9f-8f12-7b37cd3bb6ba" /> See this capture (remove the `.txt` from the end): [eftps.new.pcapng.txt](https://github.com/user-attachments/files/31082720/eftps.new.pcapng.txt). ## libcurl v7.61.1 Interestingly, when I tried out on a way older libcurl + openssl build, I did not see that issue: ```bash $ ./eftps.old ftp://demo.wftpserver.com demo demo libcurl metadata: version: 7.61.1 host: x86_64-redhat-linux-gnu ssl_version: OpenSSL/1.1.1k drwxr-xr-x 2 user group 0 Aug 14 16:28 upload drwxr-xr-x 2 user group 0 Jun 18 05:42 download Timings: DNS: 2.504 ms Connect: 28.325 ms TLS: 731.917 ms Total: 698.976 ms ``` The wireshark timings for this are accurate enough (`27ms`): <img width="3346" height="190" alt="Image" src="https://github.com/user-attachments/assets/94ed64ab-a96a-445a-9637-5cc4ab9f3a28" /> see the wireshark capture below (remove the `.txt`). [eftps.old.pcapng.txt](https://github.com/user-attachments/files/31082721/eftps.old.pcapng.txt) ## libcurl 8.18.0 I do have a bigger program that's compiled with `8.18.0` with openssl `3.6.x` which has the same issue. But, it was consistently producing 2x the connect time at the time _(or so I believed but, 8.20 breaks that assumption so please ignore the annotations in the screenshot below)_. It's on the same platform, unfortunately I lost the wireshark file for that. Here's the screenshot: <img width="1999" height="1038" alt="Image" src="https://github.com/user-attachments/assets/32ba144e-d545-4818-a6db-7758bdcd9a13" /> ## Note - both the wireshark captures are recorded using the command: ```bash $ sudo tshark -i any -f 'tcp port 21' -w /tmp/eftps.pcapng ``` - I did not find this deviation in Implicit FTPS (or Active/Passive FTP). - _MY GUESS_ is that for some reason it's "accumulating" connect time over various operations. Maybe because Explicit FTPS establishes the TCP connection, does a request-response round (`AUTH SSL`/`AUTH TLS`) with the server and THEN it starts the TLS connection. This is (afaik) a unique behaviour to Explicit FTPS alone. Coupled with the 8.18.0 analysis, I thought that was double counting only. --- Let me know if my understanding is incorrect or what am I doing wrong. ### I expected the following I expect the connect time to accurately report the TCP connection time for Explicit FTPS mode (closely matching the Wireshark). ### curl/libcurl version ``` libcurl 8.20.0 + OpenSSL 3.5.5 libcurl 8.18.0 + OpenSSL 3.6.x ``` ### operating system ``` $ uname -a Linux <host_name> 5.15.0-322.203.3.4.el8uek.x86_64 #2 SMP Mon Jul 13 18:18:42 PDT 2026 x86_64 x86_64 x86_64 GNU/Linux ``` ``` $ cat /etc/os-release NAME="Oracle Linux Server" VERSION="8.10" ID="ol" ID_LIKE="fedora" VARIANT="Server" VARIANT_ID="server" VERSION_ID="8.10" PLATFORM_ID="platform:el8" PRETTY_NAME="Oracle Linux Server 8.10" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:oracle:linux:8:10:server" HOME_URL="https://linux.oracle.com/" BUG_REPORT_URL="https://github.com/oracle/oracle-linux" ORACLE_BUGZILLA_PRODUCT="Oracle Linux 8" ORACLE_BUGZILLA_PRODUCT_VERSION=8.10 ORACLE_SUPPORT_PRODUCT="Oracle Linux" ORACLE_SUPPORT_PRODUCT_VERSION=8.10 ```
关闭于 7 天前 7 条评论