Zum Hauptinhalt springen

16. Detailliertes Beispiel (Detailed Example)

Dieser Abschnitt enthält ein Beispiel für die Verwendung von TURN und zeigt detailliert den Inhalt der ausgetauschten Nachrichten. Das Beispiel verwendet das in der Übersicht (Abbildung 1) gezeigte Netzwerkdiagramm.

Für jede Nachricht werden die in der Nachricht enthaltenen Attribute und ihre Werte angezeigt. Aus Gründen der Übersichtlichkeit werden die Werte in einem menschenlesbaren Format anstelle der tatsächlichen Bytes angezeigt; beispielsweise zeigt "XOR-RELAYED-ADDRESS=192.0.2.15:9000" an, dass ein XOR-RELAYED-ADDRESS-Attribut mit einer Adresse von 192.0.2.15 und einem Port von 9000 vorhanden ist, wobei Adresse und Port angezeigt werden, bevor die XOR-Operation angewendet wurde. Bei Attributen mit zeichenkettenartigen Werten (z. B. SOFTWARE="Example client, version 1.03" und NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm") wird der Attributwert aus Gründen der Lesbarkeit in Anführungszeichen angezeigt, aber diese Anführungszeichen erscheinen nicht im tatsächlichen Wert.

 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=... | | |

Der Client wählt zunächst eine Host-Transportadresse aus, die für die TURN-Sitzung verwendet werden soll. In diesem Beispiel hat der Client 10.1.1.2:49721 ausgewählt, wie in Abbildung 1 gezeigt. Der Client sendet dann eine Allocate-Anfrage an den Server unter der Server-Transportadresse. Der Client hat für diese Transaktion zufällig eine 96-Bit-Transaktions-ID 0xA56250D3F17ABE679422DE85 ausgewählt, die im Transaktions-ID-Feld im festen Header kodiert ist. Der Client schließt ein SOFTWARE-Attribut ein, das Informationen über die Client-Software bereitstellt, hier ist der Wert "Example client, version 1.03", was anzeigt, dass es sich um Version 1.03 von etwas handelt, das Example-Client genannt wird. Der Client schließt ein LIFETIME-Attribut ein, weil er möchte, dass die Allocation eine längere Lebensdauer als die standardmäßigen 10 Minuten hat; der Wert dieses Attributs beträgt 3600 Sekunden, was 1 Stunde entspricht. Der Client muss immer ein REQUESTED-TRANSPORT-Attribut in eine Allocate-Anfrage einschließen; der einzige von dieser Spezifikation erlaubte Wert ist 17, was UDP-Transport zwischen Server und Peers anzeigt. Der Client schließt auch ein DONT-FRAGMENT-Attribut ein, weil er das DONT-FRAGMENT-Attribut später in Send-Indikationen verwenden möchte; dieses Attribut besteht nur aus dem Attribut-Header, es gibt keinen Wertteil. Schließlich nehmen wir an, dass der Client kürzlich nicht mit dem Server interagiert hat, und daher kein USERNAME-, REALM-, NONCE- oder MESSAGE-INTEGRITY-Attribut einschließt. Beachten Sie, dass die Reihenfolge der Attribute in der Nachricht beliebig ist (außer bei den MESSAGE-INTEGRITY- und FINGERPRINT-Attributen), und der Client hätte eine andere Reihenfolge verwenden können.

Der Server erfordert, dass alle Anfragen authentifiziert werden. Wenn der Server also die ursprüngliche Allocate-Anfrage empfängt, lehnt er die Anfrage ab, weil sie keine Authentifizierungsattribute enthält. Gemäß den Verfahren des STUN [RFC5389] Langzeit-Anmeldeinformationsmechanismus schließt der Server ein ERROR-CODE-Attribut mit einem Wert von 401 (Unauthorized, Nicht autorisiert), ein REALM-Attribut ein, das den vom Server verwendeten Authentifizierungsbereich angibt (hier die Domain des Servers "example.com"), und einen Nonce-Wert im NONCE-Attribut. Der Server schließt auch ein SOFTWARE-Attribut ein, das Informationen über die Server-Software bereitstellt.

Nach Erhalt des 401-Fehlers versucht der Client die Allocate-Anfrage erneut, diesmal einschließlich der Authentifizierungsattribute. Der Client hat eine neue Transaktions-ID ausgewählt und füllt die neue Allocate-Anfrage mit denselben Attributen wie zuvor. Der Client schließt ein USERNAME-Attribut ein; er verwendet den vom Server erhaltenen Realm-Wert, um zu bestimmen, welchen Wert er verwenden soll, hier ist der Client so konfiguriert, dass er den Benutzernamen "George" für den Realm "example.com" verwendet. Der Client schließt ein REALM-Attribut und ein NONCE-Attribut ein, die aus der 401-Fehlerantwort kopiert wurden. Schließlich schließt der Client ein MESSAGE-INTEGRITY-Attribut als letztes Attribut in der Nachricht ein; der Wert dieses Attributs ist ein HMAC-SHA1-Hash über den Inhalt der Nachricht (oben nur als "..." angezeigt); diese HMAC-SHA1-Berechnung schließt einen Passwortwert ein. Somit kann ein Angreifer den Nachrichtenintegritätswert nicht berechnen, ohne das geheime Passwort zu kennen.

Nach Erhalt der authentifizierten Allocate-Anfrage prüft der Server, dass alles korrekt ist, und erstellt dann eine Allocation. Der Server antwortet mit einer Allocate-Erfolgsantwort. Der Server schließt ein LIFETIME-Attribut ein, das die Lebensdauer der Allocation angibt; hier hat der Server die vom Client angeforderte 1-Stunden-Lebensdauer auf nur 20 Minuten reduziert, weil dieser spezielle Server keine Lebensdauern über 20 Minuten zulässt. Der Server schließt ein XOR-RELAYED-ADDRESS-Attribut ein, dessen Wert die weitergeleitete Transportadresse der Allocation ist. Der Server schließt ein XOR-MAPPED-ADDRESS-Attribut ein, dessen Wert die Server-Reflexive-Adresse des Clients ist; dieser Wert wird sonst nirgendwo in TURN verwendet, wird aber aus Gründen der Bequemlichkeit für den Client zurückgegeben. Der Server schließt ein MESSAGE-INTEGRITY-Attribut ein, um die Antwort zu authentifizieren und ihre Integrität zu gewährleisten. Beachten Sie, dass die Antwort keine USERNAME-, REALM- und NONCE-Attribute enthält. Der Server schließt auch ein SOFTWARE-Attribut ein.

 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=... | | |

Der Client erstellt nun eine Permission für Peer A in Vorbereitung auf das Senden einiger Anwendungsdaten. Dies geschieht über eine CreatePermission-Anfrage. Das XOR-PEER-ADDRESS-Attribut enthält die IP-Adresse, für die eine Permission eingerichtet wird (die IP-Adresse von Peer A). Beachten Sie, dass bei Verwendung in CreatePermission-Anfragen die Portnummer im Attribut ignoriert wird; hier wurde sie auf Null gesetzt. Beachten Sie auch, wie der Client die Server-Reflexive-IP-Adresse von Peer A anstelle seiner (privaten) Host-Adresse verwendet. Der Client verwendet die Benutzernamen-, Realm- und Nonce-Werte aus seiner letzten Anfrage auf der Allocation wieder. Obwohl dies erlaubt ist, hat sich der Client entschieden, das SOFTWARE-Attribut nicht in diese Anfrage einzuschließen.

Der Server empfängt die CreatePermission-Anfrage, erstellt die entsprechende Permission und antwortet mit einer CreatePermission-Erfolgsantwort. Wie der Client hat sich der Server entschieden, das SOFTWARE-Attribut nicht in seine Antwort einzuschließen. Beachten Sie erneut, wie die Erfolgsantwort ein MESSAGE-INTEGRITY-Attribut enthält (unter der Annahme, dass der Server den Langzeit-Anmeldeinformationsmechanismus verwendet), aber keine USERNAME-, REALM- und NONCE-Attribute.

 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=... | | |

Der Client sendet nun einige Anwendungsdaten an Peer A unter Verwendung einer Send-Indikation. Die Server-Reflexive-Transportadresse von Peer A wird im XOR-PEER-ADDRESS-Attribut angegeben, und die Anwendungsdaten werden im DATA-Attribut angegeben (oben nur als "..." angezeigt). Der Client führt eine Form der Pfad-MTU-Erkennung auf der Anwendungsschicht durch und gibt daher an (durch Einschluss des DONT-FRAGMENT-Attributs), dass der Server das DF-Bit in dem an den Peer zu sendenden UDP-Datagramm setzen soll. Es ist nicht möglich, Indikationen mit dem STUN-Langzeit-Anmeldeinformationsmechanismus zu authentifizieren, daher gibt es kein MESSAGE-INTEGRITY-Attribut in der Nachricht. Eine Anwendung, die sicherstellen möchte, dass ihre Daten nicht manipuliert oder gefälscht wurden, muss die Integrität ihrer Daten auf Anwendungsebene schützen.

Nach Erhalt der Send-Indikation extrahiert der Server die Anwendungsdaten und sendet sie in einem UDP-Datagramm an Peer A, wobei die weitergeleitete Transportadresse als Quelle des Datagramms verwendet wird und das DF-Bit wie angefordert gesetzt wird. Beachten Sie, dass der Server die Send-Indikation stillschweigend verworfen hätte, wenn der Client zuvor keine Permission für die Server-Reflexive-IP-Adresse von Peer A eingerichtet hätte.

Peer A antwortet dann mit seinem eigenen UDP-Datagramm, das Anwendungsdaten enthält. Das Datagramm wird an die weitergeleitete Transportadresse auf dem Server gesendet. Wenn dies eintrifft, erstellt der Server eine Data-Indikation, schließt die Quelle des UDP-Datagramms im XOR-PEER-ADDRESS-Attribut und die Daten des UDP-Datagramms im DATA-Attribut ein. Die resultierende Data-Indikation wird dann an den Client gesendet.

 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=... | | |

Der Client bindet nun einen Kanal an Peer B, wobei er eine nicht verwendete Kanalnummer (0x4000) im CHANNEL-NUMBER-Attribut und die Transportadresse von Peer B im XOR-PEER-ADDRESS-Attribut angibt. Wie zuvor verwendet der Client den Benutzernamen, Realm und Nonce aus seiner letzten Anfrage wieder.

Nach Erhalt der Anfrage bindet der Server die Kanalnummer an den Peer und installiert eine Permission für die IP-Adresse von Peer B, und antwortet dann mit einer ChannelBind-Erfolgsantwort.

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

Der Client sendet nun eine ChannelData-Nachricht an den Server mit Daten, die für Peer B bestimmt sind. Eine ChannelData-Nachricht ist keine STUN-Nachricht und hat daher keine Transaktions-ID; stattdessen hat sie nur drei Felder: die Kanalnummer, die Daten und die Datenlänge. Hier ist das Kanalnummernfeld 0x4000 (der Kanal, den der Client gerade an Peer B gebunden hat). Wenn der Server die ChannelData-Nachricht empfängt, prüft er, ob der Kanal derzeit gebunden ist (was er ist), und leitet dann die Daten in einem UDP-Datagramm an Peer B weiter, wobei die weitergeleitete Transportadresse als Quelltransportadresse und 192.0.2.210:49191 (der Wert des XOR-PEER-ADDRESS-Attributs in der ChannelBind-Anfrage) als Zieltransportadresse verwendet wird.

Später sendet Peer B ein UDP-Datagramm an die weitergeleitete Transportadresse. Dies veranlasst den Server, eine ChannelData-Nachricht an den Client zu senden, die die Daten aus dem UDP-Datagramm enthält. Der Server weiß, an welchen Client die ChannelData-Nachricht gesendet werden soll, aufgrund der weitergeleiteten Transportadresse, an die das UDP-Datagramm gesendet wurde, und weiß, Kanal 0x4000 zu verwenden, weil dies der an 192.0.2.210:49191 gebundene Kanal ist. Beachten Sie, dass der Server eine Data-Indikation verwendet hätte, wenn es keine an diese Adresse gebundene Kanalnummer gegeben hätte.

 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) | | |

Irgendwann vor Ablauf der 20-minütigen Lebensdauer erfrischt der Client die Allocation. Dies geschieht mit einer Refresh-Anfrage. Wie zuvor schließt der Client die neuesten Benutzernamen-, Realm- und Nonce-Werte in die Anfrage ein. Der Client schließt auch ein SOFTWARE-Attribut ein und folgt damit der Empfehlung, dieses Attribut immer in Allocate- und Refresh-Nachrichten einzuschließen. Wenn der Server die Refresh-Anfrage empfängt, bemerkt er, dass der Nonce veraltet ist, und antwortet daher mit einem 438 (Stale Nonce, Veralteter Nonce) Fehler, wobei er einen neuen Nonce-Wert bereitstellt. Der Client versucht die Anfrage dann erneut, diesmal mit dem neuen Nonce-Wert. Dieser zweite Versuch wird akzeptiert und der Server antwortet mit einer Erfolgsantwort. Beachten Sie, dass der Client kein LIFETIME-Attribut in die Anfrage eingeschlossen hat, daher hat der Server die Allocation für die Standard-Lebensdauer von 10 Minuten erfrischt (wie im LIFETIME-Attribut in der Erfolgsantwort angegeben).