6. Ciclo di vita della sessione DSO e timer
6.1. Avvio della sessione DSO
Una sessione DSO inizia come descritto nella Sezione 5.1.
Una volta creata una sessione DSO, il client o il server possono avviare tutte le operazioni DNS che desiderano utilizzando la sessione DSO.
Quando un iniziatore ha più messaggi da inviare, NON DOVREBBE attendere ogni risposta prima di inviare il messaggio successivo.
Un risponditore DEVE agire sui messaggi nell'ordine in cui vengono ricevuti e DOVREBBE restituire le risposte ai messaggi di richiesta non appena diventano disponibili. Un risponditore NON DOVREBBE ritardare l'invio delle risposte allo scopo di consegnare le risposte nello stesso ordine in cui sono state ricevute le richieste corrispondenti.
La Sezione 6.2.1.1 della specifica DNS-over-TCP [RFC7766] specifica questo in maggior dettaglio.
6.2. Timeout della sessione DSO
Due valori di timeout sono associati a una sessione DSO: il timeout di inattività e l'intervallo di keepalive. Entrambi i valori sono comunicati nello stesso TLV, il Keepalive TLV (Sezione 7.1).
Il primo valore di timeout, il timeout di inattività, è il tempo massimo per il quale un client può mantenere speculativamente aperta una sessione DSO inattiva nell'aspettativa che possa avere richieste future da inviare a quel server.
Il secondo valore di timeout, l'intervallo di keepalive, è l'intervallo massimo consentito tra i messaggi se il client desidera mantenere viva la sessione DSO.
I due valori di timeout sono indipendenti. Il timeout di inattività può essere più breve, uguale o più lungo dell'intervallo di keepalive, sebbene nella maggior parte dei casi ci si aspetti che il timeout di inattività sia più breve dell'intervallo di keepalive.
Un timeout di inattività più breve con un intervallo di keepalive più lungo segnala al client che non dovrebbe mantenere speculativamente aperta una sessione DSO inattiva per molto tempo senza motivo, ma quando ha un motivo attivo per mantenere aperta una sessione DSO, non ha bisogno di inviare un livello aggressivo di traffico di keepalive DSO per mantenere quella sessione. Un esempio di ciò sarebbe un client che si è iscritto alle notifiche Push DNS. In questo caso, il client non sta inviando alcun traffico al server, ma la sessione non è inattiva perché c'è una richiesta attiva al server per ricevere notifiche push.
Un timeout di inattività più lungo con un intervallo di keepalive più breve segnala al client che può mantenere speculativamente aperta una sessione DSO inattiva per molto tempo, ma per mantenere quella sessione DSO inattiva dovrebbe inviare molto traffico di keepalive DSO. Si prevede che questa configurazione sarà meno comune.
Nel caso usuale in cui il timeout di inattività è più breve dell'intervallo di keepalive, è solo quando un client ha un'operazione di lunga durata e a basso traffico che l'intervallo di keepalive entra in gioco per garantire che venga generata una quantità residua sufficiente di traffico per mantenere lo stato NAT e firewall e per assicurare al client e al server che hanno ancora connettività l'uno con l'altro.
Su una nuova sessione DSO, se non è avvenuto alcuno scambio esplicito di messaggi DSO Keepalive, il valore predefinito per entrambi i timeout è 15 secondi.
Per entrambi i timeout, valori di timeout più bassi comportano un traffico di rete più elevato e un carico CPU più elevato sul server.
6.3. Sessioni DSO inattive
Sia sui server che sui client, la generazione o la ricezione di qualsiasi messaggio DNS completo (inclusi richieste DNS, risposte, aggiornamenti, messaggi DSO, ecc.) reimposta entrambi i timer per quella sessione DSO, con l'unica eccezione che un messaggio DSO Keepalive reimposta solo il timer di keepalive, non il timer di timeout di inattività.
Inoltre, finché il client ha un'operazione in sospeso in corso, il timer di inattività rimane azzerato e non può verificarsi un timeout di inattività.
Per operazioni DNS di breve durata come query e aggiornamenti tradizionali, un'operazione è considerata "in corso" per il tempo tra la richiesta e la risposta, tipicamente un periodo di poche centinaia di millisecondi al massimo. Nel client, il timer di inattività viene azzerato alla trasmissione di una richiesta e rimane azzerato fino alla ricezione della risposta corrispondente. Nel server, il timer di inattività viene azzerato alla ricezione di una richiesta e rimane azzerato fino alla trasmissione della risposta corrispondente.
Per operazioni DNS con stato di lunga durata (come un abbonamento alle notifiche Push [Push] o un abbonamento all'interfaccia di Discovery Relay [Relay]), un'operazione è considerata "in corso" finché l'operazione è attiva, cioè finché non viene annullata. Ciò significa che una sessione DSO può esistere con operazioni attive, senza che alcun messaggio fluisca in nessuna delle due direzioni, per molto più tempo del timeout di inattività. Questo non è un errore. Questo è il motivo per cui ci sono due timer separati: il timeout di inattività e l'intervallo di keepalive. Solo perché una sessione DSO non ha traffico per un periodo di tempo prolungato, non rende automaticamente quella sessione DSO "inattiva", se ha un'operazione attiva che attende eventi.
6.4. Timeout di inattività
Lo scopo del timeout di inattività è che il server bilanci il compromesso tra i costi di configurazione di nuove sessioni DSO e i costi di mantenimento di sessioni DSO inattive. Un server con abbondante capacità di sessione DSO può offrire un timeout di inattività elevato per consentire ai client di mantenere aperta una sessione DSO speculativa per lungo tempo e risparmiare il costo di stabilire una nuova sessione DSO per le comunicazioni future con quel server. Un server con risorse di memoria scarse può offrire un timeout di inattività basso per indurre i client a chiudere prontamente le sessioni DSO ogni volta che non hanno operazioni in sospeso con quel server e quindi creare una nuova sessione DSO in seguito quando necessario.
6.4.1. Chiusura delle sessioni DSO inattive
Quando viene raggiunto il timeout di inattività di una connessione, il client DEVE iniziare a chiudere la connessione inattiva, ma un client non è tenuto a mantenere aperta una connessione inattiva fino al raggiungimento del timeout di inattività. Un client PUÒ chiudere una sessione DSO in qualsiasi momento, a discrezione del client. Se un client determina di non avere alcuna necessità attuale o ragionevolmente prevista per una sessione DSO attualmente inattiva, allora il client DOVREBBE chiudere gentilmente quella connessione.
Se, in qualsiasi momento durante la vita della sessione DSO, il valore di timeout di inattività (cioè 15 secondi per impostazione predefinita) trascorre senza che ci sia alcuna operazione attiva sulla sessione DSO, il client DEVE chiudere la connessione gentilmente.
Se, in qualsiasi momento durante la vita della sessione DSO, trascorre troppo tempo senza che ci sia alcuna operazione attiva sulla sessione DSO, allora il server DEVE considerare il client inadempiente e DEVE interrompere forzatamente la sessione DSO. Ciò che è considerato "troppo tempo" in questo contesto è cinque secondi o il doppio del valore corrente del timeout di inattività, a seconda di quale sia maggiore. Se il timeout di inattività ha il suo valore predefinito di 15 secondi, ciò significa che un client sarà considerato inadempiente e disconnesso se non ha chiuso la sua connessione dopo 30 secondi di inattività.
In questo contesto, un'operazione attiva su una sessione DSO include una query in attesa di una risposta, un aggiornamento in attesa di una risposta o un'operazione di lunga durata attiva, ma non uno scambio di messaggi DSO Keepalive stesso. Uno scambio di messaggi DSO Keepalive reimposta solo il timer dell'intervallo di keepalive, non il timer del timeout di inattività.
Se il client desidera mantenere aperta una sessione DSO inattiva per un periodo superiore alla durata predefinita, utilizza il messaggio DSO Keepalive per richiedere valori di timeout più lunghi come descritto nella Sezione 7.1.
6.4.2. Valori per il timeout di inattività
Per il valore del timeout di inattività, valori più bassi comportano smantellamenti e ristabilimenti della sessione DSO più frequenti. Valori più alti comportano un traffico inferiore e un carico CPU inferiore sul server, ma un onere di memoria maggiore per mantenere lo stato per le sessioni DSO inattive.
Un server può dettare qualsiasi valore scelga per il timeout di inattività (sia in una risposta a una richiesta avviata dal client che in un messaggio avviato dal server) inclusi valori inferiori a un secondo, o anche zero.
Un timeout di inattività pari a zero informa il client che non dovrebbe mantenere speculativamente connessioni inattive e, non appena il client ha completato l'operazione o le operazioni relative a questo server, il client dovrebbe iniziare immediatamente a chiudere questa sessione.
Un server interromperà forzatamente una sessione client inattiva dopo cinque secondi o il doppio del valore del timeout di inattività, a seconda di quale sia maggiore. Nel caso di un valore di timeout di inattività pari a zero, ciò significa che se un client non riesce a chiudere una sessione client inattiva, il server interromperà forzatamente la sessione inattiva dopo cinque secondi.
Un timeout di inattività di 0xFFFFFFFF rappresenta "infinito" e informa il client che può mantenere aperta una connessione inattiva per tutto il tempo che desidera. Si noti che dopo aver concesso un timeout di inattività illimitato in questo modo, in qualsiasi momento il server può rivedere tale timeout di inattività inviando un nuovo messaggio DSO Keepalive che detta nuovi valori di timeout di sessione al client.
Il più grande timeout di inattività finito supportato dall'attuale Keepalive TLV è 0xFFFFFFFE (2^32-2 millisecondi, circa 49,7 giorni).
6.5. Intervallo di Keepalive
Lo scopo dell'intervallo di keepalive è gestire la generazione di messaggi sufficienti per mantenere lo stato nei middlebox (come gateway NAT o firewall) e per consentire al client e al server di verificare periodicamente di avere ancora connettività l'uno con l'altro. Ciò consente loro di ripulire lo stato quando la connettività viene persa e di stabilire una nuova sessione se appropriato.
6.5.1. Scadenza dell'intervallo di Keepalive
Se, in qualsiasi momento durante la vita della sessione DSO, il valore dell'intervallo di keepalive (cioè 15 secondi per impostazione predefinita) trascorre senza che alcun messaggio DNS venga inviato o ricevuto su una sessione DSO, il client DEVE intraprendere azioni per mantenere viva la sessione DSO inviando un messaggio DSO Keepalive (Sezione 7.1). Uno scambio di messaggi DSO Keepalive reimposta solo il timer di keepalive, non il timer di inattività.
Se un client si disconnette dalla rete bruscamente, senza chiudere in modo pulito la sua sessione DSO, forse lasciando un'operazione di lunga durata non annullata, il server ne viene a conoscenza dopo non essere riuscito a ricevere il traffico di keepalive DSO richiesto da quel client. Se, in qualsiasi momento durante la vita della sessione DSO, trascorre il doppio del valore dell'intervallo di keepalive (cioè 30 secondi per impostazione predefinita) senza che alcun messaggio DNS venga inviato o ricevuto su una sessione DSO, il server DOVREBBE considerare il client inadempiente e DOVREBBE interrompere forzatamente la sessione DSO.
6.5.2. Valori per l'intervallo di Keepalive
Per il valore dell'intervallo di keepalive, valori più bassi comportano un volume maggiore di traffico di keepalive DSO. Valori più alti dell'intervallo di keepalive riducono il traffico e il carico della CPU, ma hanno un effetto minimo sull'onere di memoria presso il server perché i client mantengono aperta una sessione DSO per la stessa durata (determinata dal timeout di inattività) indipendentemente dal livello di traffico di keepalive DSO richiesto.
Potrebbe essere appropriato che client e server selezionino intervalli di keepalive diversi a seconda del tipo di rete su cui si trovano.
Un server DNS aziendale che sa di servire solo client sulla rete interna, senza gateway NAT o firewall intermedi, può imporre un intervallo di keepalive più lungo perché non è richiesto un traffico di keepalive DSO frequente.
Un server DNS pubblico che serve principalmente client consumatori residenziali, dove è probabile che ci sia un gateway NAT sul percorso, può imporre un intervallo di keepalive più breve per generare traffico di keepalive DSO più frequente.
Un client intelligente può essere adattivo al suo ambiente. Un client che utilizza un indirizzo IPv4 privato [RFC1918] per comunicare con un server DNS a un indirizzo esterno a quel blocco di indirizzi privati IPv4 può concludere che è probabile che ci sia un gateway NAT sul percorso e di conseguenza richiedere un intervallo di keepalive più breve.
Per impostazione predefinita, è RACCOMANDATO che i client richiedano e i server concedano un intervallo di keepalive di 60 minuti. Questo intervallo di keepalive fornisce un rilevamento ragionevolmente tempestivo se un client si disconnette bruscamente senza chiudere in modo pulito la sessione. Inoltre, è sufficiente per mantenere lo stato nei firewall e nei gateway NAT che seguono la migliore pratica corrente raccomandata dall'IETF secondo cui il "timeout di inattività della connessione stabilita" utilizzato dai middlebox deve essere di almeno 2 ore e 4 minuti [RFC5382] [RFC7857].
Si noti che più breve è il valore dell'intervallo di keepalive, maggiore è il carico su client e server. Inoltre, per un valore di keepalive più breve del tempo necessario al trasporto per ritrasmettere, la perdita di un singolo pacchetto causerebbe l'interruzione della connessione da parte di un server in modo eccessivamente zelante. Ad esempio, un valore di intervallo di keepalive (ipotetico e irrealistico) di 100 ms comporterebbe un flusso continuo di dieci messaggi al secondo o più (se consentito dall'attuale finestra di controllo della congestione) in entrambe le direzioni per mantenere viva la sessione DSO. E, in questo esempio estremo, una singola ritrasmissione su un percorso con, ad esempio, 100 ms RTT introdurrebbe una pausa momentanea nel flusso di messaggi abbastanza lunga da indurre il server a interrompere la connessione.
A causa di questa preoccupazione, il server NON DEVE inviare un messaggio DSO Keepalive (né una risposta DSO a una richiesta DSO avviata dal client né un messaggio DSO avviato dal server) con un valore di intervallo di keepalive inferiore a dieci secondi. Se un client riceve un messaggio DSO Keepalive che specifica un valore di intervallo di keepalive inferiore a dieci secondi, questo è un errore fatale e il client DEVE interrompere forzatamente la connessione immediatamente.
Un valore di intervallo di keepalive di 0xFFFFFFFF rappresenta "infinito" e informa il client che non dovrebbe generare alcun traffico di keepalive DSO. Si noti che dopo aver segnalato che il client non dovrebbe generare alcun traffico di keepalive DSO in questo modo, il server può in qualsiasi momento rivedere tale requisito di traffico di keepalive DSO inviando un nuovo messaggio DSO Keepalive che detta nuovi valori di timeout di sessione al client.
Il più grande intervallo di keepalive finito supportato dall'attuale Keepalive TLV è 0xFFFFFFFE (2^32-2 millisecondi, circa 49,7 giorni).
6.6. Terminazione della sessione DSO avviata dal server
Oltre ad annullare selettivamente le singole operazioni di lunga durata (Sezione 5.6), ci sono anche occasioni in cui un server potrebbe dover terminare una o più intere sessioni DSO. Un'intera sessione DSO potrebbe dover essere terminata se il client è difettoso in qualche modo o abbandona la rete senza chiudere la sua sessione DSO. Le sessioni DSO potrebbero anche dover essere terminate se il server diventa sovraccarico o viene riconfigurato e non ha la capacità di essere selettivo su quali operazioni devono essere annullate.
Questa sezione discute vari motivi per cui una sessione DSO può essere terminata e i meccanismi per farlo.
Nel normale funzionamento, la chiusura di una sessione DSO è responsabilità del client. Il client determina quando chiudere una sessione DSO in base a una valutazione sia delle proprie esigenze che del valore di timeout di inattività dettato dal server. Un server provoca la fine di una sessione DSO solo nelle circostanze eccezionali descritte di seguito. Alcune delle situazioni eccezionali in cui un server può terminare una sessione DSO includono:
-
Il software applicativo del server o il sistema operativo sottostante si sta spegnendo o riavviando.
-
Il software applicativo del server termina inaspettatamente (forse a causa di un bug che lo fa bloccare, causando l'invio di un TCP RST da parte del sistema operativo sottostante).
-
Il server sta subendo una procedura di riconfigurazione o manutenzione che, a causa del modo in cui è implementato il software del server, richiede la disconnessione dei client. Ad esempio, alcuni software sono implementati in modo tale da leggere un file di configurazione all'avvio e la modifica della configurazione del server comporta la modifica del file di configurazione e quindi l'uccisione e il riavvio del software del server, il che comporta generalmente una perdita di connessioni di rete.
-
Il client non riesce a soddisfare il suo obbligo di generare il traffico di keepalive DSO richiesto o di chiudere una sessione inattiva entro il tempo prescritto (cinque secondi o il doppio dell'intervallo di tempo dettato dal server, a seconda di quale sia maggiore, come descritto nella Sezione 6.2).
-
Il client invia una richiesta grossolanamente non valida o malformata che è indicativa di un'implementazione client gravemente difettosa.
-
Il server è oltre la capacità e deve scaricare un po' di carico.
6.6.1. Messaggio di ritardo di ritentativo avviato dal server
Nei casi descritti sopra in cui un server sceglie di terminare una sessione DSO, potrebbe farlo semplicemente interrompendo forzatamente la connessione. Tuttavia, se lo facesse, il probabile comportamento del client potrebbe essere semplicemente quello di trattare questo come un errore di rete e riconnettersi immediatamente, mettendo più onere sul server.
Pertanto, per evitare questa implosione di riconnessione, un server DOVREBBE invece scegliere di scaricare il carico del client inviando un messaggio di ritardo di ritentativo con un valore RCODE appropriato che informa il client del motivo per cui la sessione DSO deve essere terminata. Il formato del DSO Retry Delay TLV e le interpretazioni dei vari valori RCODE sono descritti nella Sezione 7.2. Dopo aver inviato un messaggio DSO Retry Delay, il server NON DEVE inviare ulteriori messaggi su quella sessione DSO.
Il server PUÒ randomizzare i ritardi di ritentativo in situazioni in cui molti ritardi di ritentativo vengono inviati in rapida successione in modo da evitare che tutti i client tentino di riconnettersi contemporaneamente. In generale, le implementazioni dovrebbero evitare di utilizzare il messaggio DSO Retry Delay in un modo che comporterebbe la riconnessione di molti client contemporaneamente se ogni client tentasse di riconnettersi all'ora esatta specificata.
Alla ricezione di un messaggio DSO Retry Delay dal server, il client DEVE prendere nota del ritardo di riconnessione per questo server e quindi chiudere immediatamente la connessione gentilmente.
Dopo aver inviato un messaggio DSO Retry Delay, il server DOVREBBE concedere al client cinque secondi per chiudere la connessione e, se il client non ha chiuso la connessione dopo cinque secondi, il server DOVREBBE interrompere forzatamente la connessione.
Un messaggio DSO Retry Delay NON DEVE essere avviato da un client. Se un server riceve un messaggio DSO Retry Delay, questo è un errore fatale e il server DEVE interrompere forzatamente la connessione immediatamente.
6.6.1.1. Operazioni in sospeso
All'istante in cui un server sceglie di avviare un messaggio DSO Retry Delay, potrebbero esserci richieste DNS già in volo dal client al server su questa sessione DSO, che arriveranno al server dopo che il suo messaggio DSO Retry Delay è stato inviato. Il server DEVE ignorare silenziosamente tali richieste in arrivo e NON DEVE generare alcun messaggio di risposta per esse. Quando il messaggio DSO Retry Delay dal server arriva al client, il client determinerà che tutte le richieste DNS inviate in precedenza su questa sessione DSO che non hanno ancora ricevuto una risposta non riceveranno certamente alcuna risposta.
Tali richieste dovrebbero essere considerate fallite e dovrebbero essere ritentate in un secondo momento, se appropriato.
Nel caso in cui alcune, ma non tutte, le operazioni esistenti su una sessione DSO siano diventate non valide (forse perché il server è stato riconfigurato e non è più autorevole per alcuni dei nomi), ma il server sta terminando tutte le sessioni DSO interessate in massa inviando loro tutte un messaggio DSO Retry Delay, il ritardo di riconnessione PUÒ essere zero, indicando che i client DOVREBBERO tentare immediatamente di ristabilire le operazioni.
È probabile che alcuni dei tentativi avranno successo e altri no, a seconda della natura della riconfigurazione.
Nel caso in cui un server stia terminando un gran numero di sessioni DSO contemporaneamente (ad esempio, se il sistema si sta riavviando) e il server non vuole essere inondato da un diluvio di ritentativi simultanei, DOVREBBE inviare valori di ritardo di riconnessione diversi a ciascun client. Queste regolazioni POSSONO essere selezionate in modo casuale, pseudocasuale o deterministico (ad esempio, incrementando il valore temporale di un decimo di secondo per ogni client successivo, producendo un tasso di riconnessione post-riavvio di dieci client al secondo).
6.6.2. Client che si comportano male
Un server può determinare che un client non sta seguendo correttamente il protocollo. Potrebbe non esserci modo per il server di recuperare la sessione DSO, nel qual caso il server termina forzatamente la connessione. Poiché il client non sa perché la connessione è caduta, potrebbe riconnettersi immediatamente. Se il server ha determinato che un client non sta seguendo correttamente il protocollo, PUÒ terminare la sessione DSO non appena viene stabilita, specificando un lungo ritardo di ritentativo per impedire al client di riconnettersi immediatamente.
6.6.3. Riconnessione del client
Dopo che una sessione DSO è terminata dal server (o inviando al client un messaggio DSO Retry Delay o interrompendo forzatamente la connessione di trasporto sottostante), il client DOVREBBE provare a riconnettersi a quell'istanza di servizio o a un'altra istanza di servizio idonea se ne è disponibile più di una. Se si riconnette alla stessa istanza di servizio, il client DEVE rispettare il ritardo indicato, se disponibile, prima di tentare di riconnettersi. I client NON DOVREBBERO tentare di randomizzare il ritardo; il server varierà casualmente ("jitter") i valori di ritardo di ritentativo che invia a ciascun client se questo comportamento è desiderato.
Se una particolare istanza di servizio sarà fuori servizio solo per un breve periodo di manutenzione, dovrebbe indicare un valore di ritardo di ritentativo leggermente più lungo della finestra di manutenzione prevista. Non dovrebbe impostare come predefinito un valore di ritardo molto grande, altrimenti i client potrebbero non tentare di riconnettersi prontamente dopo la ripresa del servizio.
Se un'istanza di servizio non vuole che un client si riconnetta mai (forse l'istanza di servizio viene dismessa), DOVREBBE impostare il ritardo di ritentativo al valore massimo 0xFFFFFFFF (2^32-1 millisecondi, circa 49,7 giorni). Non è possibile istruire un client a stare lontano per più di 49,7 giorni. Se, dopo 49,7 giorni, il DNS o altre informazioni di configurazione indicano ancora che questa è l'istanza di servizio valida per un particolare servizio, allora i client POSSONO tentare di riconnettersi. In realtà, se un client viene riavviato o perde altrimenti lo stato, potrebbe benissimo tentare di riconnettersi prima che trascorrano 49,7 giorni, fintanto che il DNS o altre informazioni di configurazione continuano a indicare che questa è l'istanza di servizio che il client dovrebbe utilizzare.
6.6.3.1. Riconnessione dopo un'interruzione forzata
Se una connessione è stata interrotta forzatamente dal client a causa di un comportamento non conforme da parte del server, il client DOVREBBE contrassegnare quell'istanza di servizio come non supportante DSO. Il client PUÒ riconnettersi ma non tentare di utilizzare DSO, oppure può connettersi a un'istanza di servizio diversa se applicabile.
6.6.3.2. Riconnessione dopo una caduta di connessione inspiegabile
È anche possibile che un server termini forzatamente la connessione; in questo caso, il client non sa se la terminazione è stata il risultato di un errore di protocollo o di un'interruzione di rete. Quando il client nota che la connessione è caduta, può tentare di riconnettersi immediatamente. Tuttavia, se la connessione cade di nuovo senza che il client sia in grado di fare con successo qualunque cosa stia cercando di fare, dovrebbe contrassegnare il server come non supportante DSO.
6.6.3.3. Sondaggio per il supporto DSO funzionante
Una volta che un server è stato contrassegnato dal client come non supportante DSO, il client NON DOVREBBE tentare operazioni DSO su quel server fino a quando non è trascorso un po' di tempo. Un minimo ragionevole sarebbe un'ora. Poiché le connessioni interrotte forzatamente sono il risultato di un guasto del software, non è probabile che il problema venga risolto nella prima ora dopo essere stato riscontrato per la prima volta. Tuttavia, limitando l'intervallo di ritentativo a un'ora, il client sarà in grado di notare quando il problema è stato risolto senza porre un onere eccessivo sul server.