【发布时间】:2018-04-15 03:03:42
【问题描述】:
我通过 ppp 打开一个 GSM 连接并尝试使用 curl 从 URL 下载文件。
对于少数设备,我从curl 和getaddrinfo 收到 CURLE_COULDNT_RESOLVE_HOST 错误,导致 EAI_AGAIN。
在route 我的ppp0 接口注册正确。 resolv.conf 包含谷歌 DNS 并且在终端中手动执行 nslookup 正在工作。
我不知道为什么它不起作用。我唯一知道的是:IPv6 是不可能的。
这是我的getaddrinfo代码
int checkINet(std::string address)
{
struct addrinfo hints, *servinfo, *p;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
char ip_addr[INET6_ADDRSTRLEN];
int s = getaddrinfo(address.c_str(), NULL, &hints, &servinfo);
if (s != 0)
{
std::cout << "No connection possible: " << address << "\n";
std::cout << "getaddrinfo: " << s << " " << gai_strerror(s) << "\n";
return -1;
}
else
{
std::cout << "Conection successful: " << address << "\n";
for (p = servinfo; p != NULL; p = p->ai_next)
{
void *addr;
if (p->ai_family == AF_INET)
{
struct sockaddr_in *ipv4 =(struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
}
else
{
struct sockaddr_in6 *ipv6 =(struct sockaddr_in6 *)p->ai_addr;
addr = &(ipv6->sin6_addr);
}
inet_ntop(p->ai_family, addr, ip_addr, sizeof ip_addr);
std::cout << addr << "\n";
}
}
freeaddrinfo(servinfo);
return 0;
}
对于卷曲:
CURL *curl;
FILE *fp;
CURLcode res;
// initialise a connection to the server
curl = curl_easy_init();
if (curl)
{
fp = fopen(UPDATE_ZIP, "wb");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
if (CURLE_OK != res)
{
std::out << "curl failed with: " << res << "\n";
return res;
}
return 0;
}
return -1;
【问题讨论】:
-
nslookup绕过 NSS 并连接到 DNS 服务器本身。假设 Glibc,getaddrinfo确实通过 NSS。你能和getent hosts $address的行为和/etc/nsswitch.conf的内容比较吗? -
另外,您说 IPv6 是不可能的,所以您将
getaddrinfo()限制为 IPv4,但您的其余代码正在寻找 IPv6。您是否计划在未来启用 IPv6?此外,您可以将inet_ntop()替换为getnameinfo()并删除您的addr变量:getnameinfo(p->ai_addr, p->ai_addrlen, ip_addr, sizeof ip_addr, NULL, 0, NI_NUMERICHOST); -
IPv6 在我发现之前是剩余的,GSM 提供商只提供 IPv4。我认为 NSS 是我搜索的提示。我会保持更新
标签: c++ linux curl getaddrinfo