即使互联网连接正常,gethostbyname / getaddrinfo也会一直失败

时间:2014-02-03 16:41:31

标签: c linux getaddrinfo gethostbyname

背景

我们有一个运行Linux内核2.6.35的小型无头盒和ARM硬件上的一些Open Embedded发行版。

据我们所知,我们正在使用glibc 2.10.1。

该盒子有一个未连接的以太网和一个串行连接的GSM / 3G调制解调器。我们配置PPP以确保继续连接到互联网。这部分没有问题。

我们有一个用c(实际上是c ++)编码的程序,它使用套接字建立连接。该程序使用pthreads进行了大量多线程。

要查找要连接的IP地址,我们使用gethostbyname()。

当没有连接到互联网时,例如在初始启动期间或从调制解调器中移除SIM卡时,gethostbyname()将返回NULL。

症状

但是,即使互联网连接已启动并运行,gethostbyname()也会继续返回NULL。

使用时getaddrinfo()的错误代码是EAI_NONAME~“名称或服务未知”。我们没有来自gethostbyname()的错误代码,但它是等效的。

我们的分析

我们通过(通过串行控制台)确保互联网连接正常

  • 列表项
  • 查看/ var / log / messages并确保pppd表示一切正常
  • ping主机名(转换为IP并回复确定)
  • 通过公共IP
  • 通过ssh连接到该框

我们在进程中有两个线程,它们对同一主机使用gethostbyname()。它们具有稍微不同的代码路径和函数,但使用通用代码来实现套接字函数,包括调用gethostbyname()的部分。

在gethostbyname()保持返回NULL的情况下,这通常仅适用于其中一个线程,而不是每次都是相同的线程。另一个使查找完美。

此外,具有失败的gethostbyname()的线程可以通过该线程的简单受控停止和函数重新启动来轻松实现,然后导致新的线程pthread.

总的来说,我们确信DNS转换和互联网连接在操作系统级别运行良好。

为了排除线程问题,我们使用getaddrinfo()重新实现了查找代码,getaddrinfo()根据手册页可重入。并得到完全相同的结果。

对我们来说似乎线程的退出会导致某种类型的清理,这会影响gethostbyname()/ getaddrinfo()执行查找的能力。

解决方法的原因是强制退出失败的线程,但这意味着应用程序结构发生重大变化,并不是真正的选择。

问题

所以问题是:你有什么指针可以找到解决方案或真正的问题吗?

1 个答案:

答案 0 :(得分:-2)

    char *hostname = "www.example.com";
    struct hostent *a_server;
    a_server=gethostbyname(hostname);
    while (a_server == NULL) {
            a_server=gethostbyname(hostname);
            sleep(1);
    }