Passa al contenuto principale

7. Resolver Implementation (Implementazione del resolver)

I livelli superiori dell'algoritmo del resolver raccomandato sono discussi in RFC-1034. Questa sezione tratta i dettagli di implementazione assumendo la struttura del database suggerita nella sezione di implementazione del name server di questo memo.


7.1. Transforming a User Request into a Query (Trasformazione di una richiesta utente in una query)

Il primo passo che un resolver compie è trasformare la richiesta del client, dichiarata in un formato adatto al sistema operativo locale, in una specifica di ricerca per RR a un nome specifico che corrisponde a un QTYPE e QCLASS specifici.

Linee guida per la specifica delle query

Preferenza per tipo e classe singoli: Ove possibile, QTYPE e QCLASS dovrebbero (SHOULD) corrispondere a un tipo singolo e una classe singola, perché ciò rende l'uso dei dati memorizzati nella cache molto più semplice.

Motivo: La presenza di dati di un tipo in una cache non conferma l'esistenza o la non esistenza di dati di altri tipi. Pertanto, l'unico modo per essere sicuri è consultare una fonte autoritativa.

Limitazione QCLASS=*: Se QCLASS=* è utilizzato, allora le risposte autoritarie non saranno disponibili.

Informazioni sullo stato della richiesta

Poiché un resolver deve essere in grado di multiplexare più richieste se deve svolgere la sua funzione in modo efficiente, ogni richiesta in sospeso è solitamente rappresentata in un blocco di informazioni di stato.

Questo blocco di stato conterrà tipicamente:

1. Timestamp

Scopo: Indicare il momento in cui la richiesta è iniziata.

Utilizzo:

  • Il timestamp viene utilizzato per decidere se gli RR nel database possono essere utilizzati o sono obsoleti
  • Questo timestamp utilizza il formato di tempo assoluto precedentemente discusso per l'archiviazione RR in zone e cache

Interpretazione del TTL:

  • Quando il TTL di un RR indica un tempo relativo, l'RR deve essere tempestivo, poiché fa parte di una zona
  • Quando l'RR ha un tempo assoluto, fa parte di una cache, e il TTL dell'RR viene confrontato con il timestamp per l'inizio della richiesta

Vantaggio dei timestamp: L'uso del timestamp è superiore all'uso di un tempo corrente, poiché permette agli RR con TTL di zero di essere inseriti nella cache nel modo usuale, ma ancora utilizzati dalla richiesta corrente, anche dopo intervalli di molti secondi a causa del carico del sistema, timeout di ritrasmissione delle query, ecc.

2. Parametri di limitazione del lavoro (Work Limitation Parameters)

Scopo: Una sorta di parametri per limitare la quantità di lavoro che verrà eseguita per questa richiesta.

Razionale: La quantità di lavoro che un resolver eseguirà in risposta a una richiesta del client deve essere limitata per proteggersi da:

  • Errori nel database, come riferimenti CNAME circolari
  • Problemi operativi, come il partizionamento della rete che impedisce al resolver di accedere ai name server di cui ha bisogno

Implementazione:

  • Mentre i limiti locali sul numero di volte che un resolver ritrasmette una particolare query a un particolare indirizzo di name server sono essenziali
  • Il resolver dovrebbe (SHOULD) avere un contatore globale per richiesta per limitare il lavoro su una singola richiesta
  • Il contatore dovrebbe (SHOULD) essere impostato su un valore iniziale e decrementato ogni volta che il resolver esegue un'azione (timeout di ritrasmissione, ritrasmissione, ecc.)
  • Se il contatore passa a zero, la richiesta viene terminata con un errore temporaneo

Richieste parallele: Si noti che se la struttura del resolver permette a una richiesta di avviarne altre in parallelo, come quando la necessità di accedere a un name server per una richiesta causa una risoluzione parallela per gli indirizzi del name server, la richiesta generata dovrebbe (SHOULD) essere avviata con un contatore inferiore. Questo impedisce che i riferimenti circolari nel database scatenino una reazione a catena di attività del resolver.

3. Struttura dati SLIST

La struttura dati SLIST discussa in RFC-1034.

Scopo: Questa struttura tiene traccia dello stato di una richiesta se deve attendere risposte da name server esterni.


7.2. Sending the Queries (Invio delle query)

Come descritto in RFC-1034, il compito di base del resolver è formulare una query che risponderà alla richiesta del client e indirizzare quella query ai name server che possono fornire le informazioni.

Sfide nella formulazione delle query

Il resolver di solito avrà solo suggerimenti molto forti su quali server interrogare, sotto forma di RR NS, e potrebbe dover:

  • Rivedere la query, in risposta ai CNAME
  • Rivedere l'insieme dei name server che il resolver sta interrogando, in risposta alle risposte di delega che puntano il resolver verso name server più vicini alle informazioni desiderate

Oltre alle informazioni richieste dal client, il resolver potrebbe dover chiamare i propri servizi per determinare l'indirizzo dei name server che desidera contattare.

Modello del resolver

Il modello utilizzato in questo memo assume che:

  • Il resolver stia multiplexando l'attenzione tra più richieste, alcune dal client e alcune generate internamente
  • Ogni richiesta sia rappresentata da alcune informazioni di stato
  • Il comportamento desiderato è che il resolver trasmetta query ai name server in un modo che:
    • Massimizzi la probabilità che la richiesta venga risposta
    • Minimizzi il tempo impiegato dalla richiesta
    • Eviti trasmissioni eccessive

Algoritmo chiave

L'algoritmo chiave utilizza le informazioni di stato della richiesta per:

  • Selezionare il prossimo indirizzo di name server da interrogare
  • Calcolare un timeout che causerà la prossima azione nel caso non arrivi una risposta

La prossima azione sarà solitamente una trasmissione a qualche altro server, ma potrebbe essere un errore temporaneo al client.

Inizializzazione SLIST

Punto di partenza: Il resolver inizia sempre con un elenco di nomi di server da interrogare (SLIST).

Contenuto iniziale:

  • Questo elenco sarà tutti gli RR NS che corrispondono alla zona antenata più vicina che il resolver conosce
  • Per evitare problemi di avvio, il resolver dovrebbe (SHOULD) avere un insieme di server predefiniti che interrogherà se non ha RR NS correnti appropriati

Aggiunta di indirizzi: Il resolver aggiunge quindi a SLIST tutti gli indirizzi noti per i name server, e può avviare richieste parallele per acquisire gli indirizzi dei server quando il resolver ha il nome, ma non gli indirizzi, per i name server.

Informazioni storiche

Per completare l'inizializzazione di SLIST, il resolver allega tutte le informazioni storiche che ha a ogni indirizzo in SLIST.

Dati storici tipici:

  • Una sorta di medie ponderate per il tempo di risposta dell'indirizzo
  • La media al piatto dell'indirizzo (cioè, quanto spesso l'indirizzo ha risposto alla richiesta)

Note importanti:

  • Queste informazioni dovrebbero (SHOULD) essere mantenute su base per indirizzo, piuttosto che su base per name server, perché il tempo di risposta e la media al piatto di un particolare server possono variare considerevolmente da indirizzo a indirizzo
  • Queste informazioni sono in realtà specifiche per una coppia indirizzo resolver / indirizzo server, quindi un resolver con più indirizzi potrebbe voler mantenere storie separate per ciascuno dei suoi indirizzi
  • Per gli indirizzi che non hanno tale storia: un tempo di andata e ritorno previsto di 5-10 secondi dovrebbe (SHOULD) essere il caso peggiore, con stime inferiori per la stessa rete locale, ecc.

Gestione della delega: Si noti che ogni volta che viene seguita una delega, l'algoritmo del resolver reinizializza SLIST.

Selezione del server e timeout

Classificazione: Le informazioni stabiliscono una classificazione parziale degli indirizzi di name server disponibili.

Strategia di selezione: Ogni volta che viene scelto un indirizzo, lo stato dovrebbe (SHOULD) essere modificato per impedire la sua selezione di nuovo fino a quando non sono stati provati tutti gli altri indirizzi.

Calcolo del timeout: Il timeout per ogni trasmissione dovrebbe (SHOULD) essere 50-100% maggiore del valore medio previsto per consentire la varianza nella risposta.

Casi speciali

Problema di bootstrap:

  • Il resolver può incontrare una situazione in cui nessun indirizzo è disponibile per nessuno dei name server nominati in SLIST, e dove i server nell'elenco sono precisamente quelli che sarebbero normalmente utilizzati per cercare i propri indirizzi
  • Questa situazione si verifica tipicamente quando gli RR di indirizzo glue hanno un TTL più piccolo degli RR NS che segnano la delega, o quando il resolver memorizza nella cache il risultato di una ricerca NS
  • Il resolver dovrebbe (SHOULD) rilevare questa condizione e riavviare la ricerca alla prossima zona antenata, o alternativamente alla radice

Errori del server:

  • Se un resolver ottiene un errore del server o un'altra risposta bizzarra da un name server, dovrebbe (SHOULD) rimuoverlo da SLIST
  • Il resolver potrebbe voler programmare una trasmissione immediata al prossimo indirizzo di server candidato

7.3. Processing Responses (Elaborazione delle risposte)

Il primo passo nell'elaborazione dei datagrammi di risposta in arrivo è analizzare la risposta.

Procedura di analisi della risposta

Questa procedura dovrebbe (SHOULD) includere:

1. Controllo dell'intestazione:

  • Controllare l'intestazione per ragionevolezza
  • Scartare i datagrammi che sono query quando sono attese risposte

2. Analisi delle sezioni:

  • Analizzare le sezioni del messaggio
  • Assicurarsi che tutti gli RR siano formattati correttamente

3. Controllo del TTL (Opzionale):

  • Come passo opzionale, controllare i TTL dei dati in arrivo cercando RR con TTL eccessivamente lunghi
  • Se un RR ha un TTL eccessivamente lungo, diciamo maggiore di 1 settimana:
    • Scartare l'intera risposta
    • Oppure limitare tutti i TTL nella risposta a 1 settimana

Corrispondenza della risposta

Il passo successivo è abbinare la risposta a una richiesta di resolver corrente.

Strategia consigliata:

  • Eseguire una corrispondenza preliminare utilizzando il campo ID nell'intestazione del dominio
  • Quindi verificare che la sezione domanda corrisponda alle informazioni attualmente desiderate

Requisito di implementazione: Questo richiede che l'algoritmo di trasmissione dedichi diversi bit del campo ID del dominio a un identificatore di richiesta di qualche tipo.

Considerazioni speciali

Variazione dell'indirizzo sorgente:

  • Alcuni name server inviano le loro risposte da indirizzi diversi da quello utilizzato per ricevere la query
  • Cioè, un resolver non può (CANNOT) fare affidamento sul fatto che una risposta provenga dallo stesso indirizzo a cui ha inviato la query corrispondente
  • Questo bug del name server si incontra tipicamente nei sistemi UNIX

Gestione della ritrasmissione:

  • Se il resolver ritrasmette una particolare richiesta a un name server, dovrebbe (SHOULD) essere in grado di utilizzare una risposta da una qualsiasi delle trasmissioni
  • Tuttavia, se sta utilizzando la risposta per campionare il tempo di andata e ritorno per accedere al name server:
    • Deve essere in grado di determinare quale trasmissione corrisponde alla risposta (e mantenere i tempi di trasmissione per ogni messaggio in uscita)
    • Oppure calcolare solo i tempi di andata e ritorno basati sulle trasmissioni iniziali

Dati di zona mancanti:

  • Un name server occasionalmente non avrà una copia corrente di una zona che dovrebbe avere secondo alcuni RR NS
  • Il resolver dovrebbe (SHOULD) semplicemente rimuovere il name server dalla SLIST corrente e continuare

7.4. Using the Cache (Utilizzo della cache)

In generale, ci aspettiamo che un resolver memorizzi nella cache tutti i dati che riceve nelle risposte poiché potrebbero essere utili per rispondere a future richieste dei client.

Tuttavia, ci sono diversi tipi di dati che non dovrebbero (SHOULD NOT) essere memorizzati nella cache:

Dati che non dovrebbero essere memorizzati nella cache

1. Insiemi incompleti:

  • Quando sono disponibili più RR dello stesso tipo per un particolare nome proprietario, il resolver dovrebbe (SHOULD) memorizzarli tutti nella cache o nessuno di essi
  • Quando una risposta è troncata e un resolver non sa se ha un insieme completo, non dovrebbe (SHOULD NOT) memorizzare nella cache un insieme possibilmente parziale di RR

2. Dati non autoritativi su autoritativi:

  • I dati memorizzati nella cache non dovrebbero mai (MUST NOT) essere utilizzati in preferenza ai dati autoritativi
  • Se la memorizzazione nella cache causerebbe questo, i dati non dovrebbero (SHOULD NOT) essere memorizzati nella cache

3. Risultati di query inverse:

  • I risultati di una query inversa non dovrebbero (SHOULD NOT) essere memorizzati nella cache

4. Risultati di query wildcard:

  • I risultati delle query standard dove il QNAME contiene etichette * se i dati potrebbero essere utilizzati per costruire wildcard
  • Motivo: La cache non contiene necessariamente RR esistenti o informazioni sui confini delle zone che sono necessarie per limitare l'applicazione degli RR wildcard

5. Dati di affidabilità dubbia:

  • Dati RR nelle risposte di affidabilità dubbia
  • Quando un resolver riceve risposte non richieste o dati RR diversi da quelli richiesti, dovrebbe (SHOULD) scartarli senza memorizzarli nella cache
  • Implicazione di base: Tutti i controlli di sanità su un pacchetto dovrebbero (SHOULD) essere eseguiti prima che qualcuno di essi venga memorizzato nella cache

Strategia di aggiornamento della cache

Quando un resolver ha un insieme di RR per qualche nome in una risposta e desidera memorizzare gli RR nella cache:

  • Dovrebbe (SHOULD) controllare la sua cache per RR già esistenti
  • A seconda delle circostanze, sono preferiti i dati nella risposta o nella cache
  • I due non dovrebbero mai essere combinati (MUST NOT)
  • Se i dati nella risposta provengono da dati autoritativi nella sezione risposta, sono sempre preferiti

Best Practices Summary (Riepilogo delle migliori pratiche)

Per un'implementazione efficiente del resolver

  1. Utilizzare query di tipo e classe singoli quando possibile per un migliore utilizzo della cache

  2. Mantenere lo stato per richiesta inclusi timestamp e contatori di lavoro

  3. Mantenere la cronologia per indirizzo per la selezione intelligente del server

  4. Implementare strategie di timeout appropriate (50-100% sopra il tempo previsto)

  5. Gestire i casi speciali come problemi di bootstrap e errori del server

  6. Analizzare attentamente le risposte con controlli di intestazione e validazione del formato

  7. Memorizzare nella cache selettivamente - non tutti i dati dovrebbero essere memorizzati nella cache

  8. Preferire i dati autoritativi ai dati memorizzati nella cache quando entrambi sono disponibili


Correlato: Vedere 6. Name Server Implementation (Implementazione del server dei nomi) per i dettagli lato server