Проблема с вызовом функции getaddrinfo() на платформе Linux

В последнее время я работаю над разработкой сетевого приложения, основанного на платформе Linux (2.6.32). Мой сценарий заключается в том, что устройству необходимо периодически отправлять данные на сервер. Каждый раз, когда сетевой код сначала вызывает функцию getaddinfo(), он возвращает IP-адрес сервера, а затем я передал это значение интерфейсу сокета или libcurl api.

Однако я обнаружил, что если для /etc/resolv.conf установлено недопустимое значение, например сервер имен 169.254.1.1, getaddrinfo() вернет значение ошибки (-3). Даже если я обновлю /etc/resolv.conf до действительного значения, getaddrinfo() все равно вернет ошибку.

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

Мое решение состоит в том, чтобы вызвать getaddrinfo() в независимом процессе (не в потоке). Я обнаружил, что это реальный способ решить вышеуказанную проблему.

Какова основная причина вышеуказанной проблемы?


person gtv    schedule 12.11.2013    source источник
comment
Основная причина заключается в том, что весь дизайн и реализация поиска DNS в стандартной среде выполнения Linux по-прежнему отстой. Это не только негибко, но и чертовски медленно (если вы выполняете много поисков) и тратит много ресурсов впустую.   -  person Lothar    schedule 10.05.2016


Ответы (1)


Похоже, это так задумано, сам glibc читает resolv.conf только один раз — если используется внутренний резолвер.

Я считаю, что вы можете запустить nscd для разрешения/кэширования, и это подхватит изменения resolv.conf. (Если запущен nscd, glibc автоматически связывается с этим демоном, вместо того, чтобы использовать его внутренний преобразователь)

Однако вы можете принудительно перечитать resolv.conf, вызвав res_init().

person nos    schedule 12.11.2013
comment
Спасибо, нз. На самом деле на устройстве не работала служба nscd. Мое решение состоит в том, чтобы вызвать getaddrinfo() в независимом процессе (не в потоке), кажется, что вышеуказанная проблема может быть решена. - person gtv; 14.11.2013
comment
Как уже упоминалось, вы также можете вызвать функцию res_init(). так что если например. getaddrinfo() не увенчался успехом, вызовите res_init() и попробуйте getaddrinfo() еще раз, чтобы, возможно, появился новый файл resolv.conf. - person nos; 14.11.2013