2013-05-24 17 views
10

Se ottengo un "Nome o servizio sconosciuto" iniziale (EAI_NONAME), la prossima chiamata a getaddrinfo() sembra andare direttamente al DNS invece di controllare prima la cache (i log nscd non mostrano tentativi di ricerca, tcpdump mostra il traffico al server DNS). Se la prima chiamata riesce a ottenere un indirizzo, da quel momento in poi tutte le chiamate getaddrinfo() andranno prima su nscd, come previsto.utilizzando getaddrinfo() controlla solo la cache nscd la prima volta se DNS scade

Sto compilando contro glibc-2.13 per arm linux. Nel mio rc.d, nscd viene avviato prima del mio demone. nscd è impostato per disabilitare le cache condivise e mantenere una cache dell'host. Sto usando il nscd da busybox (0.47). nsswitch.conf è impostato in modo che l'host controlli cache/files/dns. hosts.conf è impostato per controllare i file/bind.

Il mio demone chiama getaddrinfo().

Ho registri di debug per nscd in esecuzione, e mostrano che il client ha iniziato a leggere la risposta DNS si chiude con un errore "Broken Pipe".

Dopodiché mostrerà i tentativi GAI da altri demoni che tentano di utilizzare la cache (quindi so che non è nscd bloccato o altro), ma il daemon che ha ottenuto EAI_NONAME non contatta mai nscd per eseguire una ricerca nella cache.

Se riavvio il daemon, ottengo lo stesso comportamento, se la prima query DNS scade di nuovo.

C'è qualcosa in glibc che sta invalidando il collegamento del mio demone alla cache? C'è un modo per ricollegare il mio demone alla cache senza riavviarlo (simile a forzare il caricamento di un resolv.conf tramite res_init())?

+1

"* ... c'è un modo per ricollegare il mio demone alla cache senza riavviarlo ... *" hai provato a far sì che il demone chiamasse 'getaddrinfo()' "** really **" spesso. Diciamo 100 ++ volte? Provalo e monitora l'accesso a 'nscd'. Non posso testarlo qui, ma ci potrebbe essere una possibilità che il tuo demone decida di testare nuovamente la connessione 'nscd' e se da quel momento in poi lo utilizzerà. – alk

+0

"* Se riavvio il demone, ottengo lo stesso comportamento ... *" ti stai riferendo al tuo demone qui, non a 'nscd', vero? – alk

+0

Btw: Ho ricevuto l'idea sopra menzionata dall'ispezione delle fonti di eglibc. – alk

risposta

4

Come alk mentions in his comment, riprovare getaddrinfo() più di 100 volte dovrebbe forzare una query nscd.


Per capire perché, diamo una rapida occhiata nel flusso di esecuzione all'internogetaddrinfo().

  1. getaddrinfo() calls gaih_inet.

  2. gaih_inet() esegue le seguenti operazioni su __nss_not_use_nscd_hosts:

    • controlla se è un numero intero positivo?
    • Incrementa.
    • Controlla se supera il numero di tentativi NSS_NSCD_RETRY?

      - Tenta di interrogare nscd SOLO se entrambe le condizioni sopra sono soddisfatte.

    anche su di tentare una query per nscd, il conteggio viene azzerato immediatamente a zero nscd ignorando in tal modo per i prossimi NSS_NSCD_RETRY volte getaddrinfo() viene chiamato.

  3. anche __nss_not_use_nscd_hosts viene modificato internamente da nscd nei seguenti luoghi

Sulla base di quanto sopra esposto, si può concludere che getaddrinfo() non interroga nscd ogni singola volta. Anche lo stato interno di nscd (determinato da __nss_not_use_nscd_hosts) decide se getaddrinfo() finisce per chiamare nscd o meno.

Per imporre davvero uno di modo per aggirare la limitazione 100 retry, si potrebbe modificare NSS_NSCD_RETRY e ricostruire libc deviare dal comportamento standard. Ma non sono proprio sicuro che questo NON porterà a nessuna regressione non intenzionale nello .

Riferimento: Patch che illustra la logica __nss_not_use_nscd_hosts in getaddrinfo().

Problemi correlati