Closed
Description
I did this
- Send an http3 request first and set
CURLOPT_FRESH_CONNECT
andCURLOPT_FORBID_REUSE
to 1, for avoid reusing http3 connection - After that, send an http(tcp) request. This will not reuse the http3 connection, but will use the dns cache
- However, the second request return fail because of error 7(Couldn't connect to server)
- The demo code is demo.cpp.txt, and major output info:
New Request[0]: https://www.google.com
curl_debug[0]: STATE: INIT => CONNECT handle 0x13c2a68; line 1833 (connection #-5000)
curl_debug[0]: Added connection 0. The cache now contains 1 members
curl_debug[0]: STATE: CONNECT => RESOLVING handle 0x13c2a68; line 1879 (connection #0)
curl_debug[0]: family0 == v4, family1 == v6
curl_debug[0]: Trying 142.251.42.228:443...
curl_debug[0]: CAfile: /etc/pki/tls/certs/ca-bundle.crt
curl_debug[0]: CApath: none
curl_debug[0]: Connect socket 5 over QUIC to 142.251.42.228:443
curl_debug[0]: Sent QUIC client Initial, ALPN: h3,h3-29,h3-28,h3-27
...
curl_debug[0]: multi_done: status: 0 prem: 0 done: 0
curl_debug[0]: The cache now contains 0 members
curl_debug[0]: Closing connection 2
curl_debug[0]: Expire cleared (transfer 0x13c2a68)
mycurl_process: https://www.google.com.hk/, curl_code: 0(No error), http_version: 30, total_time: 0.760068, connect_time: 0.618590, download_bytes: 49727, download_speed: 65424
New Request[1]: https://www.google.com
curl_debug[0]: STATE: INIT => CONNECT handle 0x13c2a68; line 1833 (connection #-5000)
curl_debug[0]: Added connection 3. The cache now contains 1 members
curl_debug[0]: Hostname www.google.com was found in DNS cache
curl_debug[0]: family0 == v4, family1 == v6
curl_debug[0]: The cache now contains 0 members
curl_debug[0]: Closing connection 3
curl_debug[0]: Expire cleared (transfer 0x13c2a68)
mycurl_process: https://www.google.com/, curl_code: 7(Couldn't connect to server), http_version: 0, total_time: 0.000000, connect_time: 0.000000, download_bytes: 0, download_speed: 0
I expected the following
- I add some output and find the error occured in
Curl_socket()
:
if(*sockfd == CURL_SOCKET_BAD) {
int err = errno;
const char* errinfo = strerror(err);
//output is 'error socket: 93, Protocol not supported'
infof(conn->data, "error socket: %d, %s\n", err, errinfo);
/* no socket, no connection */
return CURLE_COULDNT_CONNECT;
}
- Then output the dns cache info in
Curl_resolv()
andCurl_socket()
//in Curl_resolv()
if(dns) {
infof(data, "Hostname %s was found in DNS cache\n", hostname);
dns->inuse++; /* we use it! */
rc = CURLRESOLV_RESOLVED;
const struct Curl_addrinfo *ai = dns->addr;
while(ai)
{
char buf[INET6_ADDRSTRLEN];
Curl_printable_address(ai, buf, sizeof(buf));
//output is 'dns cache ai_info[111.206.72.219] - flags: 0, family: 2, socktype: 2, protocol: 17'
infof(data, "dns cache ai_info[%s] - flags: %d, family: %d, socktype: %d, protocol: %d\n", buf, ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol);
ai = ai->ai_next;
}
}
//in Curl_socket()
memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen);
{
char ipaddress[MAX_IPADR_LEN];
long port;
Curl_addr2string((struct sockaddr*)&addr->sa_addr, addr->addrlen, ipaddress, &port);
//output is 'create socket[111.206.72.219] - ai_family: 2, socktype: 1, protocol: 17'
infof(conn->data, "create socket[%s] - ai_family: %d, socktype: %d, protocol: %d\n", ipaddress, addr->family, addr->socktype, addr->protocol);
}
if(data->set.fopensocket) {
- It seems that when send an http3 request firstly, the dns result is
ai_socktype=1(SOCK_DGRAM)
andai_protocol=17(IPPROTO_UDP)
and was cached. Then use this dns cache to create a tcp socket, the params isai_socktype=1(SOCK_STREAM)
andai_protocol=17(IPPROTO_UDP)
, which is an error input(a stream socket can't use for udp protocol). So system return error - Protocol not supported.
curl/libcurl version
curl 7.83.0 (x86_64-pc-linux-gnu) libcurl/7.83.0 BoringSSL zlib/1.2.7 brotli/1.0.9 nghttp2/1.41.0 quiche/0.12.0 OpenLDAP/2.4.44
Release-Date: 2022-04-27
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli Debug HSTS HTTP2 HTTP3 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL TrackMemory UnixSockets
operating system
Linux mylinux 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux