11. Canali (Channels)
I canali (Channels) forniscono un modo per il client e il server di inviare dati dell'applicazione utilizzando messaggi ChannelData, che hanno un overhead inferiore rispetto alle indicazioni Send e Data.
Il messaggio ChannelData (vedere Sezione 11.4) inizia con un campo di due byte che porta il numero di canale (Channel Number). I valori di questo campo sono allocati come segue:
-
0x0000a0x3FFF: Questi valori non possono mai essere utilizzati per i numeri di canale. -
0x4000a0x7FFF: Questi sono i numeri di canale consentiti (16.383 valori possibili). -
0x8000a0xFFFF: Questi valori sono riservati per uso futuro.
A causa di questa divisione, i messaggi ChannelData possono essere distinti dai messaggi in formato STUN (ad esempio, richiesta Allocate, indicazione Send, ecc.) esaminando i primi due bit del messaggio:
-
0b00: Messaggio in formato STUN (poiché i primi due bit di un messaggio in formato STUN sono sempre zero). -
0b01: Messaggio ChannelData (poiché il numero di canale è il primo campo in un messaggio ChannelData e i numeri di canale sono nell'intervallo 0x4000 - 0x7FFF). -
0b10: Riservato -
0b11: Riservato
I valori riservati possono essere utilizzati in futuro per estendere l'intervallo dei numeri di canale. Pertanto, un'implementazione NON DEVE (MUST NOT) assumere che un messaggio TURN inizi sempre con un bit 0.
Le associazioni di canale (Channel Bindings) sono sempre avviate dal client. Il client può associare un canale a un peer in qualsiasi momento durante la vita dell'allocazione. Il client può associare un canale a un peer prima di scambiare dati con esso, o dopo aver scambiato dati (utilizzando indicazioni Send e Data) per un certo tempo, o può scegliere di non associare mai un canale ad esso. Il client può anche associare canali ad alcuni peer senza associare canali ad altri peer.
Le associazioni di canale sono specifiche per un'allocazione, quindi un numero di canale o un indirizzo di trasporto del peer utilizzato nell'associazione di canale di un'allocazione non ha impatto sul loro utilizzo nell'associazione di canale di un'allocazione diversa. Se un'allocazione scade, tutte le sue associazioni di canale scadono con essa.
Un'associazione di canale è composta da:
-
Un numero di canale.
-
Un indirizzo di trasporto (del peer).
-
Un timer di scadenza.
Nel contesto di un'allocazione, un'associazione di canale è identificata in modo univoco dal numero di canale o dall'indirizzo di trasporto del peer. Pertanto, lo stesso canale non può essere associato a due indirizzi di trasporto diversi, né lo stesso indirizzo di trasporto può essere associato a due canali diversi.
Le associazioni di canale durano 10 minuti a meno che non vengano rinnovate. Il rinnovo dell'associazione (tramite il server che riceve una richiesta ChannelBind che riassocia il canale allo stesso peer) ripristina il timer di scadenza a 10 minuti.
Quando un'associazione di canale scade, il canale diventa non associato. Una volta non associato, il numero di canale può essere associato a un indirizzo di trasporto diverso, e l'indirizzo di trasporto può essere associato a un numero di canale diverso. Per prevenire condizioni di gara, il client DEVE (MUST) attendere 5 minuti dopo la scadenza di un'associazione di canale prima di tentare di associare il numero di canale a un indirizzo di trasporto diverso o l'indirizzo di trasporto a un numero di canale diverso.
Quando si associa un canale a un peer, il client DOVREBBE (SHOULD) essere pronto a ricevere messaggi ChannelData sul canale dal server non appena ha inviato la richiesta ChannelBind. Su UDP, il client PUÒ (MAY) ricevere messaggi ChannelData dal server prima di ricevere la risposta di successo ChannelBind.
Nella direzione opposta, il client PUÒ (MAY) scegliere di inviare messaggi ChannelData prima di ricevere la risposta di successo ChannelBind. Tuttavia, ciò comporta il rischio che i messaggi ChannelData vengano scartati dal server se la richiesta ChannelBind non riesce per qualche motivo (ad esempio, perdita di pacchetto se la richiesta viene inviata su UDP, o il server non è in grado di soddisfare la richiesta). Un client che desidera essere sicuro dovrebbe mettere in coda i dati o utilizzare indicazioni Send fino a quando l'associazione di canale non è confermata.
11.1. Invio di una richiesta ChannelBind (Sending a ChannelBind Request)
Una transazione ChannelBind viene utilizzata per creare o rinnovare un'associazione di canale. Una transazione ChannelBind crea o rinnova anche il permesso verso il peer (vedere Sezione 8).
Per avviare la transazione ChannelBind, il client forma una richiesta ChannelBind. Il canale da associare è specificato nell'attributo CHANNEL-NUMBER, e l'indirizzo di trasporto del peer è specificato nell'attributo XOR-PEER-ADDRESS. La Sezione 11.2 descrive le restrizioni su questi attributi.
Riassociare un canale allo stesso indirizzo di trasporto a cui è già associato fornisce un modo per rinnovare l'associazione di canale e il permesso corrispondente senza inviare dati al peer. Si noti tuttavia che i permessi devono essere rinnovati più frequentemente dei canali.
11.2. Ricezione di una richiesta ChannelBind (Receiving a ChannelBind Request)
Quando il server riceve una richiesta ChannelBind, la elabora secondo la Sezione 4 più le regole specifiche menzionate qui.
Il server verifica quanto segue:
-
La richiesta contiene sia un attributo CHANNEL-NUMBER che un attributo XOR-PEER-ADDRESS.
-
Il numero di canale è nell'intervallo da 0x4000 a 0x7FFE (incluso).
-
Il numero di canale non è attualmente associato a un indirizzo di trasporto diverso (lo stesso indirizzo di trasporto è OK).
-
L'indirizzo di trasporto non è attualmente associato a un numero di canale diverso.
Se uno di questi test fallisce, il server risponde con un errore 400 (Bad Request).
Il server PUÒ (MAY) imporre restrizioni sui valori di indirizzo IP e porta consentiti nell'attributo XOR-PEER-ADDRESS -- se un valore non è consentito, il server rifiuta la richiesta con un errore 403 (Forbidden).
Se la richiesta è valida, ma il server non è in grado di soddisfare la richiesta a causa di qualche limite di capacità o simile, il server risponde con un errore 508 (Insufficient Capacity).
Altrimenti, il server risponde con una risposta di successo ChannelBind. Non ci sono attributi richiesti in una risposta di successo ChannelBind.
Se il server può soddisfare la richiesta, allora il server crea o rinnova l'associazione di canale utilizzando il numero di canale nell'attributo CHANNEL-NUMBER e l'indirizzo di trasporto nell'attributo XOR-PEER-ADDRESS. Il server installa o rinnova anche il permesso per l'indirizzo IP nell'attributo XOR-PEER-ADDRESS come descritto nella Sezione 8.
NOTA: Il server non ha bisogno di fare nulla di speciale per implementare l'idempotenza delle richieste ChannelBind su UDP utilizzando l'"approccio stack stateless". Le richieste ChannelBind ritrasmesse rinnoveranno semplicemente l'associazione di canale e il permesso corrispondente. Inoltre, il client deve attendere 5 minuti prima di associare un numero di canale o un indirizzo peer precedentemente associato a un canale diverso, eliminando la possibilità che la transazione fallisca inizialmente ma abbia successo su una ritrasmissione.
11.3. Ricezione di una risposta ChannelBind (Receiving a ChannelBind Response)
Quando il client riceve una risposta di successo ChannelBind, aggiorna le sue strutture dati per registrare che l'associazione di canale è ora attiva. Aggiorna anche le sue strutture dati per registrare che il permesso corrispondente è stato installato o rinnovato.
Se il client riceve una risposta di fallimento ChannelBind che indica che le informazioni sul canale sono fuori sincronizzazione tra il client e il server (ad esempio, una risposta 400 "Bad Request" inaspettata), allora è RACCOMANDATO (RECOMMENDED) che il client elimini immediatamente l'allocazione e ricominci con una nuova allocazione.
11.4. Il messaggio ChannelData (The ChannelData Message)
Il messaggio ChannelData viene utilizzato per trasportare dati dell'applicazione tra il client e il server. Ha il seguente formato:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Channel Number | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
/ Application Data /
/ /
| |
| +-------------------------------+
| |
+-------------------------------+
Il campo Channel Number specifica il numero di canale su cui i dati viaggiano, e quindi l'indirizzo del peer che sta inviando o deve ricevere i dati.
Il campo Length specifica la lunghezza in byte del campo Application Data (cioè, non include la dimensione dell'intestazione ChannelData). Si noti che 0 è una lunghezza valida.
Il campo Application Data trasporta i dati che il client sta cercando di inviare al peer, o che il peer sta inviando al client.
11.5. Invio di un messaggio ChannelData (Sending a ChannelData Message)
Una volta che un client ha associato un canale a un peer, quando il client ha dati da inviare a quel peer, può utilizzare un messaggio ChannelData o un'indicazione Send; cioè, il client non è obbligato a utilizzare il canale quando esiste ed è libero di utilizzare uno dei due tipi di messaggio quando invia dati al peer. Il server, d'altra parte, DEVE (MUST) utilizzare il messaggio ChannelData se un canale è stato associato al peer.
I campi del messaggio ChannelData sono compilati come descritto nella Sezione 11.4.
Su TCP e TLS-over-TCP, il messaggio ChannelData DEVE (MUST) essere riempito a un multiplo di quattro byte per garantire l'allineamento dei messaggi successivi. Il riempimento non è riflesso nel campo di lunghezza del messaggio ChannelData, quindi la dimensione effettiva di un messaggio ChannelData (incluso il riempimento) è (4 + Length) arrotondato al multiplo di 4 più vicino. Su UDP, il riempimento non è richiesto ma PUÒ (MAY) essere incluso.
Il messaggio ChannelData viene quindi inviato sulla 5-tupla associata all'allocazione.
11.6. Ricezione di un messaggio ChannelData (Receiving a ChannelData Message)
Il ricevitore di un messaggio ChannelData utilizza i primi due bit per distinguerlo da un messaggio in formato STUN, come descritto sopra. Se il messaggio utilizza un valore nell'intervallo riservato (da 0x8000 a 0xFFFF), allora il messaggio viene scartato silenziosamente.
Se il messaggio ChannelData viene ricevuto in un datagramma UDP, e se il datagramma UDP è troppo corto per contenere la lunghezza dei dati che il messaggio ChannelData dichiara di trasportare (cioè, il valore del campo di lunghezza dell'intestazione UDP è inferiore al valore del campo di lunghezza dell'intestazione ChannelData + 4 + 8), allora il messaggio viene scartato silenziosamente.
Se il messaggio ChannelData viene ricevuto su TCP o TLS-over-TCP, allora la lunghezza effettiva del messaggio ChannelData è come descritto nella Sezione 11.5.
Se il messaggio ChannelData viene ricevuto su un canale che non è associato ad alcun peer, allora il messaggio viene scartato silenziosamente.
Sul client, è RACCOMANDATO (RECOMMENDED) che il client scarti il messaggio ChannelData se il client ritiene che non ci sia un permesso attivo verso il peer. Sul server, la ricezione di un messaggio ChannelData NON DEVE (MUST NOT) rinnovare né l'associazione di canale né il permesso verso il peer.
Sul server, se non vengono rilevati errori, il server inoltra i dati dell'applicazione al peer formando un datagramma UDP come segue:
-
L'indirizzo di trasporto di origine è l'indirizzo di trasporto inoltrato dell'allocazione, dove l'allocazione è determinata dalla 5-tupla su cui è arrivato il messaggio ChannelData.
-
L'indirizzo di trasporto di destinazione è l'indirizzo di trasporto a cui il canale è associato.
-
I dati che seguono l'intestazione UDP sono il contenuto del campo dati del messaggio ChannelData.
Il datagramma UDP risultante viene quindi inviato al peer. Si noti che se il campo Length nel messaggio ChannelData è 0, allora non ci saranno dati nel datagramma UDP, ma il datagramma UDP viene comunque formato e inviato.
11.7. Inoltro di dati dal peer (Relaying Data from the Peer)
Quando il server riceve un datagramma UDP sull'indirizzo di trasporto inoltrato associato a un'allocazione, lo elabora come descritto nella Sezione 10.3. Se quella sezione indica che deve essere inviato un messaggio ChannelData (perché c'è un canale associato al peer che ha inviato il datagramma UDP), allora il server forma e invia un messaggio ChannelData come descritto nella Sezione 11.5.