For Explicit FTPS mode, libcurl incorrectly reports connect timing.
FTPconnecting & proxieslibcurl API
### 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 条评论