gethostbyname/getaddrinfo продолжает сбой, даже когда интернет-соединение установлено

Фон

У нас есть небольшой безголовый бокс с ядром Linux 2.6.35 и некоторым вариантом дистрибутива Open Embedded на оборудовании ARM.

Насколько мы можем судить, мы используем glibc 2.10.1.

Коробка имеет неподключенный Ethernet и последовательный модем GSM/3G. Мы настроили PPP, чтобы обеспечить постоянное подключение к Интернету. Эта часть работает без проблем.

У нас есть программа, написанная на c (на самом деле C++), которая устанавливает соединение с использованием сокетов. Программа сильно многопоточная с использованием pthreads.

Для поиска IP-адреса для подключения мы используем gethostbyname().

Когда нет подключения к Интернету, например, во время начальной загрузки или когда SIM-карта извлечена из модема, gethostbyname() возвращает NULL, как и должно быть.

Симптом

Но иногда gethostbyname () продолжает возвращать NULL, даже если интернет-соединение установлено.

Код ошибки от getaddrinfo() при использовании, это EAI_NONAME ~ "Имя или служба неизвестна". У нас нет кода ошибки из gethostbyname (), но он был эквивалентен.

Наш анализ

Мы убедились, что интернет-соединение в порядке (через последовательную консоль)

  • Элемент списка
  • Просматривая /var/log/messages и убедившись, что pppd говорит, что все в порядке
  • ping имя хоста (переводит в IP и отвечает нормально)
  • подключиться к коробке через ssh через публичный IP

У нас есть два потока в процессе, которые используют gethostbyname () для одного хоста. Они имеют слегка отличающиеся пути кода и функции, но используют общий код для функций сокета, включая часть, которая вызывает gethostbyname().

В ситуациях, когда gethostbyname () продолжает возвращать NULL, это обычно верно только для ОДНОГО из потоков, а не один и тот же каждый раз. Другой делает поиск идеально.

Кроме того, поток с ошибкой gethostbyname () может быть легко приведен в действие путем простого контролируемого останова этого потока и перезапуска функции, что в результате приведет к созданию нового потока в обратном порядке.

В целом мы убеждены, что трансляция DNS и подключение к интернету работают нормально на уровне ОС.

Чтобы исключить проблемы с многопоточностью, мы повторно реализовали код поиска, используя getaddrinfo(), который повторно вводится в соответствии со страницей руководства. И с точно таким же результатом.

Нам кажется, что выход из потока приводит к некоторой очистке, которая влияет на способность gethostbyname()/getaddrinfo() выполнять поиск.

Обходным путем может быть принудительное завершение выходящего из строя потока, но это будет означать существенное изменение структуры приложения и на самом деле не вариант.

Вопрос

Итак, вопрос: есть ли у вас какие-либо указания, где искать решение или где может быть настоящая проблема?

1 ответ

    char *hostname = "www.example.com";
    struct hostent *a_server;
    a_server=gethostbyname(hostname);
    while (a_server == NULL) {
            a_server=gethostbyname(hostname);
            sleep(1);
    }
Другие вопросы по тегам