Passa al contenuto principale

16. Esempio dettagliato (Detailed Example)

Questa sezione fornisce un esempio di utilizzo di TURN, mostrando in dettaglio il contenuto dei messaggi scambiati. L'esempio utilizza il diagramma di rete mostrato nella panoramica (Figura 1).

Per ogni messaggio, vengono mostrati gli attributi contenuti nel messaggio e i loro valori. Per comodità, i valori sono mostrati in un formato leggibile dall'uomo piuttosto che mostrare i byte effettivi; ad esempio, "XOR-RELAYED-ADDRESS=192.0.2.15:9000" indica che è presente un attributo XOR-RELAYED-ADDRESS con un indirizzo di 192.0.2.15 e una porta di 9000, dove l'indirizzo e la porta sono mostrati prima che sia stata applicata l'operazione XOR. Per gli attributi con valori di tipo stringa (ad esempio, SOFTWARE="Example client, version 1.03" e NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm"), il valore dell'attributo è mostrato tra virgolette per leggibilità, ma queste virgolette non appaiono nel valore effettivo.

 TURN                                 TURN           Peer          Peer
client server A B
| | | |
|--- Allocate request -------------->| | |
| Transaction-Id=0xA56250D3F17ABE679422DE85 | |
| SOFTWARE="Example client, version 1.03" | |
| LIFETIME=3600 (1 hour) | | |
| REQUESTED-TRANSPORT=17 (UDP) | | |
| DONT-FRAGMENT | | |
| | | |
|<-- Allocate error response --------| | |
| Transaction-Id=0xA56250D3F17ABE679422DE85 | |
| SOFTWARE="Example server, version 1.17" | |
| ERROR-CODE=401 (Unauthorized) | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| | | |
|--- Allocate request -------------->| | |
| Transaction-Id=0xC271E932AD7446A32C234492 | |
| SOFTWARE="Example client 1.03" | | |
| LIFETIME=3600 (1 hour) | | |
| REQUESTED-TRANSPORT=17 (UDP) | | |
| DONT-FRAGMENT | | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- Allocate success response ------| | |
| Transaction-Id=0xC271E932AD7446A32C234492 | |
| SOFTWARE="Example server, version 1.17" | |
| LIFETIME=1200 (20 minutes) | | |
| XOR-RELAYED-ADDRESS=192.0.2.15:50000 | |
| XOR-MAPPED-ADDRESS=192.0.2.1:7000 | |
| MESSAGE-INTEGRITY=... | | |

Il client seleziona innanzitutto un indirizzo di trasporto host da utilizzare per la sessione TURN. In questo esempio, il client ha selezionato 10.1.1.2:49721 come mostrato nella Figura 1. Il client invia quindi una richiesta Allocate al server all'indirizzo di trasporto del server. Il client ha selezionato casualmente un ID di transazione a 96 bit 0xA56250D3F17ABE679422DE85 per questa transazione, che è codificato nel campo ID di transazione nell'intestazione fissa. Il client include un attributo SOFTWARE che fornisce informazioni sul software del client, qui il valore è "Example client, version 1.03", indicando che si tratta della versione 1.03 di qualcosa chiamato client Example. Il client include un attributo LIFETIME perché desidera che l'allocazione abbia una durata più lunga del valore predefinito di 10 minuti; il valore di questo attributo è di 3600 secondi, corrispondenti a 1 ora. Il client deve sempre includere un attributo REQUESTED-TRANSPORT in una richiesta Allocate; l'unico valore consentito da questa specifica è 17, che indica il trasporto UDP tra server e peer. Il client include anche un attributo DONT-FRAGMENT perché desidera utilizzare l'attributo DONT-FRAGMENT nelle indicazioni Send in seguito; questo attributo consiste solo nell'intestazione dell'attributo, non c'è parte di valore. Infine, assumiamo che il client non abbia recentemente interagito con il server, e quindi non include alcun attributo USERNAME, REALM, NONCE o MESSAGE-INTEGRITY. Si noti che l'ordine degli attributi nel messaggio è arbitrario (eccetto per gli attributi MESSAGE-INTEGRITY e FINGERPRINT), e il client avrebbe potuto utilizzare un ordine diverso.

Il server richiede che tutte le richieste siano autenticate. Quindi, quando il server riceve la richiesta Allocate iniziale, rifiuta la richiesta perché non contiene gli attributi di autenticazione. Seguendo le procedure del meccanismo di credenziali a lungo termine STUN [RFC5389], il server include un attributo ERROR-CODE con un valore di 401 (Unauthorized, Non autorizzato), un attributo REALM che specifica il realm di autenticazione utilizzato dal server (qui, il dominio del server "example.com"), e un valore nonce nell'attributo NONCE. Il server include anche un attributo SOFTWARE, fornendo informazioni sul software del server.

Dopo aver ricevuto l'errore 401, il client riprova la richiesta Allocate, questa volta includendo gli attributi di autenticazione. Il client ha selezionato un nuovo ID di transazione e riempie la nuova richiesta Allocate con gli stessi attributi di prima. Il client include un attributo USERNAME; utilizza il valore realm ricevuto dal server per aiutarlo a determinare quale valore utilizzare, qui il client è configurato per utilizzare il nome utente "George" per il realm "example.com". Il client include un attributo REALM e un attributo NONCE, copiati dalla risposta di errore 401. Infine, il client include un attributo MESSAGE-INTEGRITY come ultimo attributo nel messaggio; il valore di questo attributo è un hash HMAC-SHA1 sul contenuto del messaggio (mostrato sopra come solo "..."); questo calcolo HMAC-SHA1 include un valore di password. Quindi, un attaccante non può calcolare il valore di integrità del messaggio senza conoscere la password segreta.

Dopo aver ricevuto la richiesta Allocate autenticata, il server verifica che tutto sia corretto, quindi crea un'allocazione. Il server risponde con una risposta di successo Allocate. Il server include un attributo LIFETIME che fornisce la durata dell'allocazione; qui, il server ha ridotto la durata di 1 ora richiesta dal client a soli 20 minuti, perché questo particolare server non consente durate superiori a 20 minuti. Il server include un attributo XOR-RELAYED-ADDRESS il cui valore è l'indirizzo di trasporto relayed dell'allocazione. Il server include un attributo XOR-MAPPED-ADDRESS il cui valore è l'indirizzo riflesso dal server del client; questo valore non viene utilizzato altrove in TURN, ma viene restituito per comodità del client. Il server include un attributo MESSAGE-INTEGRITY per autenticare la risposta e garantirne l'integrità. Si noti che la risposta non include attributi USERNAME, REALM e NONCE. Il server include anche un attributo SOFTWARE.

 TURN                                 TURN           Peer          Peer
client server A B
|--- CreatePermission request ------>| | |
| Transaction-Id=0xE5913A8F460956CA277D3319 | |
| XOR-PEER-ADDRESS=192.0.2.150:0 | | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- CreatePermission success resp.--| | |
| Transaction-Id=0xE5913A8F460956CA277D3319 | |
| MESSAGE-INTEGRITY=... | | |

Il client crea ora un permesso per il peer A in preparazione all'invio di alcuni dati dell'applicazione. Questo viene fatto tramite una richiesta CreatePermission. L'attributo XOR-PEER-ADDRESS contiene l'indirizzo IP per cui viene stabilito un permesso (l'indirizzo IP del peer A). Si noti che quando viene utilizzato nelle richieste CreatePermission, il numero di porta nell'attributo viene ignorato; qui, è stato impostato a zero. Si noti anche come il client utilizza l'indirizzo IP riflesso dal server del peer A piuttosto che il suo indirizzo host (privato). Il client riutilizza i valori di nome utente, realm e nonce dalla sua ultima richiesta sull'allocazione. Sebbene ciò sia consentito, il client ha scelto di non includere l'attributo SOFTWARE in questa richiesta.

Il server riceve la richiesta CreatePermission, crea il permesso corrispondente e risponde con una risposta di successo CreatePermission. Come il client, il server ha scelto di non includere l'attributo SOFTWARE nella sua risposta. Si noti ancora una volta come la risposta di successo contenga un attributo MESSAGE-INTEGRITY (supponendo che il server utilizzi il meccanismo di credenziali a lungo termine), ma nessun attributo USERNAME, REALM e NONCE.

 TURN                                 TURN           Peer          Peer
client server A B
|--- Send indication --------------->| | |
| Transaction-Id=0x1278E9ACA2711637EF7D3328 | |
| XOR-PEER-ADDRESS=192.0.2.150:32102 | |
| DONT-FRAGMENT | | |
| DATA=... | | |
| |-- UDP dgm ->| |
| | data=... | |
| | | |
| |<- UDP dgm --| |
| | data=... | |
|<-- Data indication ----------------| | |
| Transaction-Id=0x8231AE8F9242DA9FF287FEFF | |
| XOR-PEER-ADDRESS=192.0.2.150:32102 | |
| DATA=... | | |

Il client invia ora alcuni dati dell'applicazione al peer A utilizzando un'indicazione Send. L'indirizzo di trasporto riflesso dal server del peer A è specificato nell'attributo XOR-PEER-ADDRESS, e i dati dell'applicazione sono specificati nell'attributo DATA (mostrato sopra come solo "..."). Il client sta eseguendo una forma di scoperta MTU del percorso a livello di applicazione, e quindi specifica (includendo l'attributo DONT-FRAGMENT) che il server dovrebbe impostare il bit DF nel datagramma UDP da inviare al peer. Non è possibile autenticare le indicazioni utilizzando il meccanismo di credenziali a lungo termine STUN, quindi non c'è attributo MESSAGE-INTEGRITY nel messaggio. Un'applicazione che desidera assicurarsi che i suoi dati non siano stati manomessi o falsificati deve proteggere l'integrità dei suoi dati a livello di applicazione.

Dopo aver ricevuto l'indicazione Send, il server estrae i dati dell'applicazione e li invia in un datagramma UDP al peer A, utilizzando l'indirizzo di trasporto relayed come origine del datagramma, e con il bit DF impostato come richiesto. Si noti che se il client non avesse precedentemente stabilito un permesso per l'indirizzo IP riflesso dal server del peer A, il server avrebbe silenziosamente scartato l'indicazione Send.

Il peer A risponde quindi con il proprio datagramma UDP contenente dati dell'applicazione. Il datagramma viene inviato all'indirizzo di trasporto relayed sul server. Quando questo arriva, il server crea un'indicazione Data, include l'origine del datagramma UDP nell'attributo XOR-PEER-ADDRESS e i dati del datagramma UDP nell'attributo DATA. L'indicazione Data risultante viene quindi inviata al client.

 TURN                                 TURN           Peer          Peer
client server A B
|--- ChannelBind request ----------->| | |
| Transaction-Id=0x6490D3BC175AFF3D84513212 | |
| CHANNEL-NUMBER=0x4000 | | |
| XOR-PEER-ADDRESS=192.0.2.210:49191 | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- ChannelBind success response ---| | |
| Transaction-Id=0x6490D3BC175AFF3D84513212 | |
| MESSAGE-INTEGRITY=... | | |

Il client lega ora un canale al peer B, specificando un numero di canale inutilizzato (0x4000) nell'attributo CHANNEL-NUMBER e l'indirizzo di trasporto del peer B nell'attributo XOR-PEER-ADDRESS. Come prima, il client riutilizza il nome utente, il realm e il nonce dalla sua ultima richiesta.

Dopo aver ricevuto la richiesta, il server lega il numero di canale al peer e installa un permesso per l'indirizzo IP del peer B, quindi risponde con una risposta di successo ChannelBind.

 TURN                                 TURN           Peer          Peer
client server A B
|--- ChannelData ------------------->| | |
| Channel-number=0x4000 |--- UDP datagram --------->|
| Data=... | Data=... |
| | | |
| |<-- UDP datagram ----------|
| | Data=... | |
|<-- ChannelData --------------------| | |
| Channel-number=0x4000 | | |
| Data=... | | |

Il client invia ora un messaggio ChannelData al server con dati destinati al peer B. Un messaggio ChannelData non è un messaggio STUN e quindi non ha ID di transazione; invece, ha solo tre campi: il numero di canale, i dati e la lunghezza dei dati. Qui, il campo del numero di canale è 0x4000 (il canale che il client ha appena legato al peer B). Quando il server riceve il messaggio ChannelData, verifica che il canale sia attualmente legato (lo è), quindi inoltra i dati al peer B in un datagramma UDP, utilizzando l'indirizzo di trasporto relayed come indirizzo di trasporto di origine e 192.0.2.210:49191 (il valore dell'attributo XOR-PEER-ADDRESS nella richiesta ChannelBind) come indirizzo di trasporto di destinazione.

Successivamente, il peer B invia un datagramma UDP all'indirizzo di trasporto relayed. Questo fa sì che il server invii un messaggio ChannelData al client contenente i dati del datagramma UDP. Il server sa a quale client inviare il messaggio ChannelData a causa dell'indirizzo di trasporto relayed a cui è stato inviato il datagramma UDP, e sa di utilizzare il canale 0x4000 perché è il canale legato a 192.0.2.210:49191. Si noti che se non ci fosse stato alcun numero di canale legato a quell'indirizzo, il server avrebbe utilizzato un'indicazione Data.

 TURN                                 TURN           Peer          Peer
client server A B
|--- Refresh request --------------->| | |
| Transaction-Id=0x0864B3C27ADE9354B4312414 | |
| SOFTWARE="Example client 1.03" | | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- Refresh error response ---------| | |
| Transaction-Id=0x0864B3C27ADE9354B4312414 | |
| SOFTWARE="Example server, version 1.17" | |
| ERROR-CODE=438 (Stale Nonce) | | |
| REALM="example.com" | | |
| NONCE="npSw1Xw239bBwGYhjNWgz2yH47sxB2j" | |
| | | |
|--- Refresh request --------------->| | |
| Transaction-Id=0x427BD3E625A85FC731DC4191 | |
| SOFTWARE="Example client 1.03" | | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="npSw1Xw239bBwGYhjNWgz2yH47sxB2j" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- Refresh success response -------| | |
| Transaction-Id=0x427BD3E625A85FC731DC4191 | |
| SOFTWARE="Example server, version 1.17" | |
| LIFETIME=600 (10 minutes) | | |

In qualche momento prima della scadenza della durata di 20 minuti, il client aggiorna l'allocazione. Questo viene fatto utilizzando una richiesta Refresh. Come prima, il client include i valori più recenti di nome utente, realm e nonce nella richiesta. Il client include anche un attributo SOFTWARE, seguendo la raccomandazione di includere sempre questo attributo nei messaggi Allocate e Refresh. Quando il server riceve la richiesta Refresh, nota che il nonce è diventato obsoleto, quindi risponde con un errore 438 (Stale Nonce, Nonce obsoleto), fornendo un nuovo valore nonce. Il client riprova quindi la richiesta, questa volta con il nuovo valore nonce. Questo secondo tentativo viene accettato e il server risponde con una risposta di successo. Si noti che il client non ha incluso un attributo LIFETIME nella richiesta, quindi il server ha aggiornato l'allocazione per la durata predefinita di 10 minuti (come indicato nell'attributo LIFETIME nella risposta di successo).