6. Creazione di un'allocazione
Un'allocazione sul server viene creata utilizzando una transazione Allocate.
6.1. Invio di una richiesta Allocate
Il client forma una richiesta Allocate come segue.
Il client sceglie innanzitutto un indirizzo di trasporto host. Si raccomanda che il client scelga un indirizzo di trasporto non utilizzato, tipicamente consentendo al sistema operativo sottostante di scegliere una porta non utilizzata per un nuovo socket.
Il client sceglie quindi un protocollo di trasporto da utilizzare tra il client e il server. Il protocollo di trasporto deve essere uno tra UDP, TCP o TLS-over-TCP. Poiché questa specifica consente solo UDP tra il server e i peer, si raccomanda che il client scelga UDP a meno che non abbia un motivo per utilizzare un trasporto diverso. Un motivo per scegliere un trasporto diverso sarebbe che il client ritiene (forse attraverso la configurazione o attraverso esperimenti) di non essere in grado di contattare alcun server TURN utilizzando UDP. Vedere la sezione 2.1 per ulteriori discussioni.
Il client sceglie anche un indirizzo di trasporto del server, il che dovrebbe essere fatto come segue. Il client riceve (forse attraverso la configurazione) un nome di dominio per un server TURN. Il client utilizza quindi le procedure DNS descritte in [RFC5389], ma utilizzando un nome di servizio SRV di "turn" (o "turns" per TURN su TLS) invece di "stun" (o "stuns"). Ad esempio, per trovare server nel dominio example.com, il client esegue una ricerca per '_turn._udp.example.com', '_turn._tcp.example.com' e '_turns._tcp.example.com' se il client desidera comunicare con il server utilizzando rispettivamente UDP, TCP o TLS-over-TCP.
Il client deve includere un attributo REQUESTED-TRANSPORT nella richiesta. Questo attributo specifica il protocollo di trasporto tra il server e i peer (si noti che questo non è il protocollo di trasporto che appare nella 5-tupla). In questa specifica, il tipo REQUESTED-TRANSPORT è sempre UDP. Questo attributo è incluso per consentire alle estensioni future di specificare altri protocolli.
Se il client desidera che il server inizializzi il campo tempo alla scadenza dell'allocazione a un valore diverso dalla durata predefinita, può includere un attributo LIFETIME che specifica il suo valore desiderato. Questa è solo una richiesta e il server può scegliere di utilizzare un valore diverso. Si noti che il server ignorerà le richieste di inizializzare il campo a un valore inferiore al valore predefinito.
Se il client desidera utilizzare successivamente l'attributo DONT-FRAGMENT in una o più indicazioni Send su questa allocazione, allora il client dovrebbe includere l'attributo DONT-FRAGMENT nella richiesta Allocate. Questo consente al client di testare se il server supporta questo attributo.
Se il client richiede che il numero di porta dell'indirizzo di trasporto inoltrato sia pari, il client include l'attributo EVEN-PORT. Se questo attributo non è incluso, allora la porta può essere pari o dispari. Impostando il bit R nell'attribut EVEN-PORT a 1, il client può richiedere che il server riservi il numero di porta successivo più alto (sullo stesso indirizzo IP) per un'allocazione successiva. Se il bit R è 0, non viene fatta tale richiesta.
Il client può anche includere un attributo RESERVATION-TOKEN nella richiesta per chiedere al server di utilizzare una porta precedentemente riservata per l'allocazione. Se l'attributo RESERVATION-TOKEN è incluso, allora il client deve omettere l'attributo EVEN-PORT.
Una volta costruita, il client invia la richiesta Allocate sulla 5-tupla.
6.2. Ricezione di una richiesta Allocate
Quando il server riceve una richiesta Allocate, esegue i seguenti controlli:
-
Il server deve richiedere che la richiesta sia autenticata. Questa autenticazione deve essere eseguita utilizzando il meccanismo di credenziali a lungo termine di [RFC5389] a meno che il client e il server non concordino di utilizzare un altro meccanismo attraverso una procedura al di fuori dell'ambito di questo documento.
-
Il server verifica se la 5-tupla è attualmente in uso da un'allocazione esistente. Se sì, il server rifiuta la richiesta con un errore 437 (Allocation Mismatch).
-
Il server verifica se la richiesta contiene un attributo REQUESTED-TRANSPORT. Se l'attributo REQUESTED-TRANSPORT non è incluso o è malformato, il server rifiuta la richiesta con un errore 400 (Bad Request). Altrimenti, se l'attributo è incluso ma specifica un protocollo diverso da UDP, il server rifiuta la richiesta con un errore 442 (Unsupported Transport Protocol).
-
La richiesta può contenere un attributo DONT-FRAGMENT. Se è così, ma il server non supporta l'invio di datagrammi UDP con il bit DF impostato a 1 (vedere sezione 12), allora il server tratta l'attributo DONT-FRAGMENT nella richiesta Allocate come un attributo di comprensione richiesta sconosciuto.
-
Il server verifica se la richiesta contiene un attributo RESERVATION-TOKEN. Se sì, e la richiesta contiene anche un attributo EVEN-PORT, allora il server rifiuta la richiesta con un errore 400 (Bad Request). Altrimenti, verifica se il token è valido (cioè, il token è nell'intervallo e non è scaduto e l'indirizzo di trasporto inoltrato corrispondente è ancora disponibile). Se il token non è valido per qualche motivo, il server rifiuta la richiesta con un errore 508 (Insufficient Capacity).
-
Il server verifica se la richiesta contiene un attributo EVEN-PORT. Se sì, allora il server verifica di poter soddisfare la richiesta (cioè, può allocare un indirizzo di trasporto inoltrato come descritto di seguito). Se il server non può soddisfare la richiesta, allora il server rifiuta la richiesta con un errore 508 (Insufficient Capacity).
-
In qualsiasi momento, il server può scegliere di rifiutare la richiesta con un errore 486 (Allocation Quota Reached) se ritiene che il client stia cercando di superare una quota di allocazione definita localmente. Il server è libero di definire questa quota di allocazione in qualsiasi modo desideri, ma dovrebbe definirla in base al nome utente utilizzato per autenticare la richiesta, e non sull'indirizzo di trasporto del client.
-
Anche in qualsiasi momento, il server può scegliere di rifiutare la richiesta con un errore 300 (Try Alternate) se desidera reindirizzare il client a un server diverso. L'uso di questo codice di errore e attributo segue la specifica in [RFC5389].
Se tutti i controlli vengono superati, il server crea l'allocazione. La 5-tupla è impostata sulla 5-tupla della richiesta Allocate, mentre l'elenco dei permessi e l'elenco dei canali sono inizialmente vuoti.
Il server sceglie un indirizzo di trasporto inoltrato per l'allocazione come segue:
-
Se la richiesta contiene un RESERVATION-TOKEN, il server utilizza l'indirizzo di trasporto precedentemente riservato corrispondente al token incluso (se è ancora disponibile). Si noti che la prenotazione è una prenotazione a livello di server e non è specifica di una particolare allocazione, poiché la richiesta Allocate contenente il RESERVATION-TOKEN utilizza una 5-tupla diversa dalla richiesta Allocate che ha effettuato la prenotazione. La 5-tupla per la richiesta Allocate contenente l'attributo RESERVATION-TOKEN può essere qualsiasi 5-tupla consentita; può utilizzare un indirizzo IP e una porta client diversi, un protocollo di trasporto diverso e persino un indirizzo IP e una porta server diversi (a condizione che l'indirizzo IP e la porta del server siano quelli su cui il server sta ascoltando le richieste TURN).
-
Se la richiesta contiene un attributo EVEN-PORT con il bit R impostato a 0, allora il server alloca un indirizzo di trasporto inoltrato con un numero di porta pari.
-
Se la richiesta contiene un attributo EVEN-PORT con il bit R impostato a 1, allora il server cerca una coppia di numeri di porta N e N+1 sullo stesso indirizzo IP, dove N è pari. La porta N viene utilizzata nell'allocazione corrente, mentre l'indirizzo di trasporto inoltrato con porta N+1 viene assegnato un token e riservato per un'allocazione futura. Il server deve mantenere questa prenotazione per almeno 30 secondi, e può scegliere di mantenerla più a lungo (ad esempio, fino a quando l'allocazione con porta N scade). Il server include quindi il token in un attributo RESERVATION-TOKEN nella risposta di successo.
-
Altrimenti, il server alloca qualsiasi indirizzo di trasporto inoltrato disponibile.
In tutti i casi, il server dovrebbe allocare solo porte dall'intervallo 49152 - 65535 (l'intervallo di porte dinamiche e/o private [Port-Numbers]), a meno che l'applicazione server TURN non sappia, attraverso mezzi non specificati qui, che altre applicazioni in esecuzione sullo stesso host dell'applicazione server TURN non saranno influenzate dall'allocazione di porte al di fuori di questo intervallo. Questa condizione può spesso essere soddisfatta eseguendo l'applicazione server TURN su una macchina dedicata e/o organizzando che qualsiasi altra applicazione sulla macchina allochi le porte prima dell'avvio dell'applicazione server TURN. In ogni caso, il server TURN non dovrebbe allocare porte nell'intervallo 0 - 1023 (l'intervallo di porte ben note) per scoraggiare i client dall'utilizzare TURN per eseguire servizi standard.
NOTA: L'IETF sta attualmente indagando sull'argomento delle assegnazioni di porte casuali per evitare certi tipi di attacchi (vedere [TSVWG-PORT]). Si raccomanda vivamente agli implementatori TURN di rimanere aggiornati su questo argomento e, se appropriato, di implementare un algoritmo di assegnazione delle porte casuali. Questo è particolarmente applicabile ai server che scelgono di pre-allocare un numero di porte dal sistema operativo sottostante e poi successivamente assegnarle alle allocazioni; ad esempio, un server può scegliere questa tecnica per implementare l'attributo EVEN-PORT.
Il server determina il valore iniziale del campo tempo alla scadenza come segue. Se la richiesta contiene un attributo LIFETIME, allora il server calcola il minimo tra la durata proposta dal client e la durata massima consentita del server. Se questo valore calcolato è maggiore della durata predefinita, allora il server utilizza la durata calcolata come valore iniziale del campo tempo alla scadenza. Altrimenti, il server utilizza la durata predefinita. Si raccomanda che il server utilizzi un valore di durata massima consentita non superiore a 3600 secondi (1 ora). I server che implementano quote di allocazione o addebitano agli utenti le allocazioni in qualche modo potrebbero voler utilizzare una durata massima consentita più piccola (forse piccola quanto la durata predefinita) per rimuovere più rapidamente le allocazioni orfane (cioè, allocazioni in cui il client corrispondente è crashato o terminato o la connessione client è stata persa per qualche motivo). Si noti inoltre che il tempo alla scadenza viene ricalcolato con ogni richiesta Refresh riuscita, e quindi il valore calcolato qui si applica solo fino al primo refresh.
Una volta creata l'allocazione, il server risponde con una risposta di successo. La risposta di successo contiene:
-
Un attributo XOR-RELAYED-ADDRESS contenente l'indirizzo di trasporto inoltrato.
-
Un attributo LIFETIME contenente il valore corrente del timer tempo alla scadenza.
-
Un attributo RESERVATION-TOKEN (se un secondo indirizzo di trasporto inoltrato è stato riservato).
-
Un attributo XOR-MAPPED-ADDRESS contenente l'indirizzo IP e la porta del client (dalla 5-tupla).
NOTA: L'attributo XOR-MAPPED-ADDRESS è incluso nella risposta per comodità del client. TURN stesso non fa uso di questo valore, ma i client che eseguono ICE tipicamente necessitano di questo valore e possono quindi evitare di dover effettuare una transazione Binding aggiuntiva con un server STUN per ottenerlo.
La risposta (successo o errore) viene inviata al client sulla 5-tupla.
NOTA: Quando la richiesta Allocate viene inviata tramite UDP, la sezione 7.3.1 di [RFC5389] richiede che il server gestisca possibili ritrasmissioni della richiesta in modo che le ritrasmissioni non causino la creazione di allocazioni multiple. Le implementazioni possono ottenere ciò utilizzando il cosiddetto "approccio stack senza stato" come segue. Per rilevare le ritrasmissioni quando una richiesta originale ha avuto successo nella creazione di un'allocazione, il server può memorizzare l'ID di transazione utilizzato nella richiesta di creazione con i dati dell'allocazione e confrontarlo con le richieste Allocate in arrivo sulla stessa 5-tupla. Una volta rilevata tale richiesta, il server può interrompere l'analisi della richiesta e generare immediatamente una risposta di successo. Quando costruisce questa risposta, il valore dell'attributo LIFETIME può essere preso dal campo tempo alla scadenza nei dati di stato dell'allocazione, anche se questo valore può differire leggermente dal valore LIFETIME originariamente restituito. Inoltre, il server potrebbe aver bisogno di memorizzare un'indicazione di qualsiasi token di prenotazione restituito nella risposta originale in modo che possa essere restituito in qualsiasi risposta ritrasmessa.
Per il caso in cui la richiesta originale non sia riuscita a creare un'allocazione, il server può scegliere di non fare nulla di speciale. Si noti tuttavia che esiste un caso raro in cui il server rifiuta la richiesta originale ma accetta la richiesta ritrasmessa (perché le condizioni sono cambiate nel breve periodo intermedio). Se il client riceve la prima risposta (rifiuto), ignorerà la seconda risposta (successo) e crederà che un'allocazione non sia stata creata. Un'allocazione creata in questo modo alla fine scadrà, poiché il client non la aggiornerà. Inoltre, se il client riprova successivamente con la stessa 5-tupla ma un ID di transazione diverso, riceverà un errore 437 (Allocation Mismatch), il che lo porterà a riprovare con una 5-tupla diversa. Il server può minimizzare la durata delle allocazioni "orfane" in questo modo utilizzando un valore di durata massima più piccolo.
6.3. Ricezione di una risposta di successo Allocate
Se il client riceve una risposta di successo Allocate, allora deve verificare che sia l'indirizzo mappato che l'indirizzo di trasporto inoltrato siano nella famiglia di indirizzi che il client comprende ed è pronto a gestire. Questa specifica copre solo il caso in cui entrambi gli indirizzi sono indirizzi IPv4. Se uno dei due indirizzi non è in una famiglia di indirizzi che il client è pronto a gestire, allora il client deve eliminare l'allocazione (sezione 7), e non deve tentare di creare un'altra allocazione su quel server fino a quando non ritiene che la mancata corrispondenza sia stata corretta.
L'IETF sta attualmente considerando meccanismi per la transizione tra IPv4 e IPv6 che potrebbero portare un client a originare una richiesta Allocate su IPv6, ma la richiesta arriverebbe al server su IPv4, o viceversa.
Altrimenti, il client crea la propria copia della struttura dati dell'allocazione per tenere traccia di cosa sta succedendo sul server. In particolare, il client deve ricordare la durata effettiva ricevuta dal server, piuttosto che il valore inviato al server nella richiesta. Il client deve anche ricordare la 5-tupla utilizzata per la richiesta e il nome utente e la password utilizzati per autenticare la richiesta per garantire che li riutilizzi per i messaggi successivi. Il client deve anche tenere traccia dei canali e dei permessi che stabilisce sul server.
Il client probabilmente vorrà inviare l'indirizzo di trasporto inoltrato ai peer (utilizzando un metodo non specificato qui) in modo che i peer possano comunicare con esso. Il client potrebbe anche voler utilizzare l'indirizzo riflesso dal server che riceve nell'attributo XOR-MAPPED-ADDRESS nella sua elaborazione ICE.
6.4. Ricezione di una risposta di errore Allocate
Se il client riceve una risposta di errore Allocate, allora l'elaborazione dipende dal codice di errore effettivo restituito:
-
(Richiesta scaduta, Request Timed Out): C'è un problema con il server o un problema nel raggiungere il server con il trasporto scelto. Il client considera la transazione corrente come fallita ma può scegliere di ritentare la richiesta Allocate utilizzando un trasporto diverso (ad esempio, TCP invece di UDP).
-
300 (Try Alternate): Il server vorrebbe che il client utilizzasse invece il server specificato nell'attributo ALTERNATE-SERVER. Il client considera la transazione corrente come fallita, ma dovrebbe provare una richiesta Allocate con il server alternativo prima di provare altri server (ad esempio, altri server scoperti utilizzando le procedure SRV). Quando prova la richiesta Allocate con il server alternativo, il client segue le procedure ALTERNATE-SERVER specificate in [RFC5389].
-
400 (Bad Request): Il server ritiene che la richiesta del client sia malformata per qualche motivo. Il client considera la transazione corrente come fallita. Il client può notificare l'utente o l'operatore e non dovrebbe ritentare la richiesta con questo server fino a quando non ritiene che il problema sia stato risolto.
-
401 (Unauthorized): Se il client ha seguito le procedure del meccanismo di credenziali a lungo termine e riceve ancora questo errore, allora il server non sta accettando le credenziali del client. In questo caso, il client considera la transazione corrente come fallita e dovrebbe notificare l'utente o l'operatore. Il client non dovrebbe inviare ulteriori richieste a questo server fino a quando non ritiene che il problema sia stato risolto.
-
403 (Forbidden): La richiesta è valida, ma il server si rifiuta di eseguirla, probabilmente a causa di restrizioni amministrative. Il client considera la transazione corrente come fallita. Il client può notificare l'utente o l'operatore e non dovrebbe ritentare la stessa richiesta con questo server fino a quando non ritiene che il problema sia stato risolto.
-
420 (Unknown Attribute): Se il client ha incluso un attributo DONT-FRAGMENT nella richiesta e il server ha rifiutato la richiesta con un codice di errore 420 e ha elencato l'attributo DONT-FRAGMENT nell'attributo UNKNOWN-ATTRIBUTES della risposta di errore, allora il client ora sa che il server non supporta l'attributo DONT-FRAGMENT. Il client considera la transazione corrente come fallita ma può scegliere di ritentare la richiesta Allocate senza l'attributo DONT-FRAGMENT.
-
437 (Allocation Mismatch): Questo indica che il client ha scelto una 5-tupla che il server vede come già in uso. Un modo in cui questo può accadere è se un NAT intermedio ha assegnato un indirizzo di trasporto mappato che è stato utilizzato da un altro client recentemente crashato. Il client considera la transazione corrente come fallita. Il client dovrebbe scegliere un altro indirizzo di trasporto client e ritentare la richiesta Allocate (con un ID di transazione diverso). Il client dovrebbe provare tre diversi indirizzi di trasporto client prima di rinunciare a questo server. Una volta che il client rinuncia al server, non dovrebbe tentare di creare un'altra allocazione sul server per 2 minuti.
-
438 (Stale Nonce): Vedere le procedure per il meccanismo di credenziali a lungo termine [RFC5389].
-
441 (Wrong Credentials): Il client non dovrebbe ricevere questo errore in risposta a una richiesta Allocate. Il client può notificare l'utente o l'operatore e non dovrebbe ritentare la stessa richiesta con questo server fino a quando non ritiene che il problema sia stato risolto.
-
442 (Unsupported Transport Address): Il client non dovrebbe ricevere questo errore in risposta a una richiesta di allocazione UDP. Il client può notificare l'utente o l'operatore e non dovrebbe ritentare la richiesta con questo server fino a quando non ritiene che il problema sia stato risolto.
-
486 (Allocation Quota Reached): Il server è attualmente impossibilitato a creare altre allocazioni con questo nome utente. Il client considera la transazione corrente come fallita. Il client dovrebbe attendere almeno 1 minuto prima di tentare di creare altre allocazioni sul server.
-
508 (Insufficient Capacity): Il server non ha più indirizzi di trasporto inoltrati disponibili, o non ne ha nessuno con le proprietà richieste, o quello che corrisponde al token di prenotazione specificato non è disponibile. Il client considera l'operazione corrente come fallita. Se il client sta utilizzando l'attributo EVEN-PORT o RESERVATION-TOKEN, allora il client può scegliere di rimuovere o modificare questo attributo e riprovare immediatamente. Altrimenti, il client dovrebbe attendere almeno 1 minuto prima di tentare di creare altre allocazioni su questo server.
Una risposta di errore sconosciuta deve essere gestita come descritto in [RFC5389].