blu*_*oon 5 curl tcp libcurl julia
我正在使用curl_easylibcurl 接口编写代码,但很难让它重用连接。详细信息如下。
curl --version
curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.1 zlib/1.2.11
libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3
Release-Date: 2018-01-24
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3
pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB
SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL
Run Code Online (Sandbox Code Playgroud)
我的代码运行了一系列单元测试,所有这些单元测试都必须通过 H2 连接到同一主机,因此我设置了持久连接。我调用一次curl_easy_init,然后调用所有全局curl_easy_setopt值,然后在一个循环中,我通过调用curl_easy_setopt设置post字段、url、内容长度,然后调用curl_easy_perform. 我只curl_easy_cleanup在所有请求提出后才打电话。我设置了以下选项:
CURLOPT_FOLLOWLOCATION => 1
CURLOPT_SSL_VERIFYPEER => 1
CURLOPT_SSL_VERIFYHOST => 2
CURLOPT_SSLVERSION 7<<16
CURLOPT_HTTP_VERSION = 4
CURLOPT_TCP_FASTOPEN = 1
CURLOPT_TCP_KEEPALIVE = 1
CURLOPT_ACCEPT_ENCODING = ""
CURLOPT_TRANSFER_ENCODING = 1
CURLOPT_POST = 1
CURLOPT_DNS_CACHE_TIMEOUT = 0
CURLOPT_VERBOSE = 1
CURLOPT_SSLCERT
CURLOPT_SSLKEY
CURLOPT_CAINFO
Run Code Online (Sandbox Code Playgroud)
详细输出如下所示:
* TCP_NODELAY set
* TCP_FASTOPEN_CONNECT set
* Connected to XYZ () port 443 (#0)
* found 3 certificates in /data/certs/ca_chain.pem
* found 401 certificates in /etc/ssl/certs
* ALPN, offering h2
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* error fetching CN from cert:The requested data were not available.
* common name: (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject:
* start date: Mon, 13 Jul 2020 08:04:30 GMT
* expire date: Mon, 20 Jul 2020 08:05:00 GMT
* issuer: C=US,ST=MA,L=Cambridge,O=XXXXX,CN=YYYYY
* compression: NULL
* ALPN, server accepted to use h2
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade:
len=0
* Using Stream ID: 1 (easy handle 0x9036570)
> POST /foo/ HTTP/2
<Request>
* We are completely uploaded and fine
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
<Response>
* Connection #0 to host XYZ left intact
Run Code Online (Sandbox Code Playgroud)
* Found bundle for host XYZ: 0xe141520 [can multiplex]
* Connection #0 is still name resolving, can't reuse
* Trying IP...
* TCP_NODELAY set
* TCP_FASTOPEN_CONNECT set
* Connected to XYZ () port 443 (#1)
* found 3 certificates in /data/certs/ca_chain.pem
* found 401 certificates in /etc/ssl/certs
* ALPN, offering h2
* ALPN, offering http/1.1
* SSL re-using session ID
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* error fetching CN from cert:The requested data were not available.
* common name: (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject:
* start date: Mon, 13 Jul 2020 08:04:30 GMT
* expire date: Mon, 20 Jul 2020 08:05:00 GMT
* issuer: C=US,ST=MA,L=Cambridge,O=XXXXX,CN=YYYYY
* compression: NULL
* ALPN, server accepted to use h2
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade:
len=0
* Using Stream ID: 1 (easy handle 0x9036570)
<Request>
* We are completely uploaded and fine
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< vary: accept-encoding
< content-encoding: gzip
< content-type: text/plain
< date: Mon, 13 Jul 2020 19:30:36 GMT
< server: abcdefg
<Response>
* Connection #1 to host XYZ left intact
Run Code Online (Sandbox Code Playgroud)
* Found bundle for host XYZ: 0xe141520 [can multiplex]
* Connection #0 is still name resolving, can't reuse
* Connection #1 is still name resolving, can't reuse
Run Code Online (Sandbox Code Playgroud)
等等...
很快就到了这个:
* Connection cache is full, closing the oldest one.
* Closing connection 0
* Connection #5 to host XYZ left intact
Run Code Online (Sandbox Code Playgroud)
最旧连接的关闭从现在开始继续,直到一切完成,或者 TLS 握手错误使连接进入不一致状态。
知道我可以做什么来让curl 重用与主机的H2 连接吗?
谢谢你的时间。
问题在于CURLOPT_TCP_FASTOPEN. 关闭该选项将允许连接重用。仅当使用多个 TCP 连接以避免握手期间的往返时才需要 FAST_OPEN。
传统的 TCP 握手是一种三向协议。
发送ACK后,发起者发送第一个数据包。总共有 4 个数据包发送数据。
使用 FAST_OPEN,数据传输(在第一个连接之后的连接上)可以从第一个数据包开始。它使用 TCP Cookie (TFO) 来确定两台主机最近已成功相互连接。
请参阅https://en.wikipedia.org/wiki/TCP_Fast_Open了解更多信息。