当坏ip提供给CURLOPT_DNS_SERVERS时,Curl返回all ok

Curl returns all ok when bad ip supplied to CURLOPT_DNS_SERVERS

本文关键字:Curl 返回 ok all SERVERS DNS ip CURLOPT 当坏      更新时间:2023-10-16

我制作了一个多线程(pthread)c++程序,该程序被配置为使用自定义dns列表。在我的测试中,我使用了谷歌的8.8.8.8来测试好的ex,并使用了一些随机ip,如113.65.12.138、13.23.123.87来测试失败。但在这两种情况下,一切都一样,都很成功。

Curl是在C-ares支持下构建的,我已经测试过了:

curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
cout<<endl<<"Curl version: "<< data->version <<endl
    <<"AsyncDNS: "<<( data->features | CURL_VERSION_ASYNCHDNS ? "YES" : "NO"  ) <<endl;
//output: Curl version: 7.30.0 n AsyncDNS: YES

代码的其余部分:

curl_easy_setopt(curl, CURLOPT_DNS_SERVERS, thisThreadData->current_dns->dns_str.c_str()); 
curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE,false); //thread safety 
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, CONNECT_TIMEOUT);    
curl_easy_setopt(curl, CURLOPT_TIMEOUT, CONNECTION_TIMEOUT);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5);   
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_to_string);
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &getUrlOutput->header);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &getUrlOutput->html);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip,deflate");
status=curl_easy_perform(curl);

我测试了随机IP(以防万一我偶然发现了一些有效的DNS):

$ host google.com 113.65.123.138
;; connection timed out; no servers could be reached
$ host google.com 13.23.123.87
;; connection timed out; no servers could be reached

我错过了什么?

更新

我试过libcurl的最新版本(7.33.0)和c-ares(1.10.0),结果都是一样的。

此外,如果我为url提供了错误的域,它将返回CURLE_HTTP_RETURNED_ERROR (22),而不是CURLE_COULDNT_RESOLVE_HOST (6)

更新2

忘了提一下我使用了HTML_PROXY进行连接,这似乎是一个重要的方面,请参阅答案。

根据curl论坛,当dns由代理处理时,这是预期的行为。

当我使用代理时,我(或可以)如何控制目标url是本地解析还是由代理解析?我有我需要两种选择的条件。

使用HTTP代理,客户端(curl)将完整URL交给代理,代理将解析主机名
如果真的想在客户端执行,那么您需要首先解析名称,然后"重新排列"URL以使用IP仅限数字,并将Host:标头设置为包含您要使用的主机名解决。

在我的情况下,当代理的DNS发现错误时,它会返回一个html格式的错误页面,并显示消息"未找到主机",html_status 503,这就是为什么curl通过了DNS检查并表示域正常,但CURLE_HTTP_RETURNED_ERROR失败的原因。