11. Kanäle (Channels)
Kanäle (Channels) bieten dem Client und Server eine Möglichkeit, Anwendungsdaten mithilfe von ChannelData-Nachrichten zu senden, die weniger Overhead aufweisen als Send- und Data-Indikationen.
Die ChannelData-Nachricht (siehe Abschnitt 11.4) beginnt mit einem Zwei-Byte-Feld, das die Kanalnummer (Channel Number) trägt. Die Werte dieses Feldes werden wie folgt zugewiesen:
-
0x0000bis0x3FFF: Diese Werte können niemals für Kanalnummern verwendet werden. -
0x4000bis0x7FFF: Dies sind die zulässigen Kanalnummern (16.383 mögliche Werte). -
0x8000bis0xFFFF: Diese Werte sind für zukünftige Verwendung reserviert.
Aufgrund dieser Aufteilung können ChannelData-Nachrichten von STUN-formatierten Nachrichten (z. B. Allocate-Anfrage, Send-Indikation usw.) unterschieden werden, indem die ersten beiden Bits der Nachricht untersucht werden:
-
0b00: STUN-formatierte Nachricht (da die ersten beiden Bits einer STUN-formatierten Nachricht immer Null sind). -
0b01: ChannelData-Nachricht (da die Kanalnummer das erste Feld in einer ChannelData-Nachricht ist und Kanalnummern im Bereich 0x4000 - 0x7FFF liegen). -
0b10: Reserviert -
0b11: Reserviert
Die reservierten Werte können in Zukunft verwendet werden, um den Bereich der Kanalnummern zu erweitern. Daher DARF (MUST NOT) eine Implementierung nicht davon ausgehen, dass eine TURN-Nachricht immer mit einem 0-Bit beginnt.
Kanalbindungen (Channel Bindings) werden immer vom Client initiiert. Der Client kann einen Kanal während der Lebensdauer der Allokation jederzeit an einen Peer binden. Der Client kann einen Kanal vor dem Datenaustausch mit dem Peer an diesen binden, oder nach einiger Zeit des Datenaustauschs (unter Verwendung von Send- und Data-Indikationen), oder sich dafür entscheiden, niemals einen Kanal an ihn zu binden. Der Client kann auch Kanäle an einige Peers binden, während er keine Kanäle an andere Peers bindet.
Kanalbindungen sind allokationsspezifisch, daher hat eine in der Kanalbindung einer Allokation verwendete Kanalnummer oder Peer-Transportadresse keinen Einfluss auf ihre Verwendung in der Kanalbindung einer anderen Allokation. Wenn eine Allokation abläuft, laufen alle ihre Kanalbindungen mit ihr ab.
Eine Kanalbindung besteht aus:
-
Einer Kanalnummer.
-
Einer Transportadresse (des Peers).
-
Einem Ablaufzeitzähler.
Im Kontext einer Allokation wird eine Kanalbindung entweder durch die Kanalnummer oder durch die Transportadresse des Peers eindeutig identifiziert. Daher kann derselbe Kanal nicht an zwei verschiedene Transportadressen gebunden werden, noch kann dieselbe Transportadresse an zwei verschiedene Kanäle gebunden werden.
Kanalbindungen dauern 10 Minuten, sofern sie nicht aufgefrischt werden. Das Auffrischen der Bindung (durch den Server, der eine ChannelBind-Anfrage empfängt, die den Kanal erneut an denselben Peer bindet) setzt den Ablaufzeitzähler auf 10 Minuten zurück.
Wenn eine Kanalbindung abläuft, wird der Kanal ungebunden. Sobald er ungebunden ist, kann die Kanalnummer an eine andere Transportadresse gebunden werden, und die Transportadresse kann an eine andere Kanalnummer gebunden werden. Um Race-Conditions zu verhindern, MUSS (MUST) der Client 5 Minuten warten, nachdem eine Kanalbindung abgelaufen ist, bevor er versucht, die Kanalnummer an eine andere Transportadresse oder die Transportadresse an eine andere Kanalnummer zu binden.
Beim Binden eines Kanals an einen Peer SOLLTE (SHOULD) der Client darauf vorbereitet sein, ChannelData-Nachrichten auf dem Kanal vom Server zu empfangen, sobald er die ChannelBind-Anfrage gesendet hat. Über UDP KANN (MAY) der Client ChannelData-Nachrichten vom Server empfangen, bevor er die ChannelBind-Erfolgsantwort erhält.
In der anderen Richtung KANN (MAY) der Client wählen, ChannelData-Nachrichten zu senden, bevor er die ChannelBind-Erfolgsantwort erhält. Dies birgt jedoch das Risiko, dass die ChannelData-Nachrichten vom Server verworfen werden, wenn die ChannelBind-Anfrage aus irgendeinem Grund nicht erfolgreich ist (z. B. Paketverlust, wenn die Anfrage über UDP gesendet wird, oder der Server die Anfrage nicht erfüllen kann). Ein Client, der sicher sein möchte, sollte entweder die Daten in eine Warteschlange stellen oder Send-Indikationen verwenden, bis die Kanalbindung bestätigt ist.
11.1. Senden einer ChannelBind-Anfrage (Sending a ChannelBind Request)
Eine ChannelBind-Transaktion wird verwendet, um eine Kanalbindung zu erstellen oder aufzufrischen. Eine ChannelBind-Transaktion erstellt oder frischt auch die Berechtigung zum Peer auf (siehe Abschnitt 8).
Um die ChannelBind-Transaktion zu initiieren, erstellt der Client eine ChannelBind-Anfrage. Der zu bindende Kanal wird im Attribut CHANNEL-NUMBER angegeben, und die Transportadresse des Peers wird im Attribut XOR-PEER-ADDRESS angegeben. Abschnitt 11.2 beschreibt die Einschränkungen für diese Attribute.
Das erneute Binden eines Kanals an dieselbe Transportadresse, an die er bereits gebunden ist, bietet eine Möglichkeit, die Kanalbindung und die entsprechende Berechtigung aufzufrischen, ohne Daten an den Peer zu senden. Beachten Sie jedoch, dass Berechtigungen häufiger als Kanäle aufgefrischt werden müssen.
11.2. Empfangen einer ChannelBind-Anfrage (Receiving a ChannelBind Request)
Wenn der Server eine ChannelBind-Anfrage empfängt, verarbeitet er sie gemäß Abschnitt 4 plus den hier erwähnten spezifischen Regeln.
Der Server überprüft Folgendes:
-
Die Anfrage enthält sowohl ein CHANNEL-NUMBER- als auch ein XOR-PEER-ADDRESS-Attribut.
-
Die Kanalnummer liegt im Bereich 0x4000 bis 0x7FFE (einschließlich).
-
Die Kanalnummer ist derzeit nicht an eine andere Transportadresse gebunden (dieselbe Transportadresse ist in Ordnung).
-
Die Transportadresse ist derzeit nicht an eine andere Kanalnummer gebunden.
Wenn einer dieser Tests fehlschlägt, antwortet der Server mit einem 400 (Bad Request)-Fehler.
Der Server KANN (MAY) Einschränkungen für die im XOR-PEER-ADDRESS-Attribut zulässigen IP-Adressen- und Port-Werte auferlegen -- wenn ein Wert nicht zulässig ist, lehnt der Server die Anfrage mit einem 403 (Forbidden)-Fehler ab.
Wenn die Anfrage gültig ist, der Server jedoch aufgrund einer Kapazitätsbeschränkung oder ähnlichem die Anfrage nicht erfüllen kann, antwortet der Server mit einem 508 (Insufficient Capacity)-Fehler.
Andernfalls antwortet der Server mit einer ChannelBind-Erfolgsantwort. Es gibt keine erforderlichen Attribute in einer erfolgreichen ChannelBind-Antwort.
Wenn der Server die Anfrage erfüllen kann, erstellt oder frischt der Server die Kanalbindung unter Verwendung der Kanalnummer im CHANNEL-NUMBER-Attribut und der Transportadresse im XOR-PEER-ADDRESS-Attribut auf. Der Server installiert oder frischt auch die Berechtigung für die IP-Adresse im XOR-PEER-ADDRESS-Attribut auf, wie in Abschnitt 8 beschrieben.
HINWEIS: Der Server muss nichts Besonderes tun, um die Idempotenz von ChannelBind-Anfragen über UDP unter Verwendung des „zustandslosen Stack-Ansatzes" zu implementieren. Erneut übertragene ChannelBind-Anfragen werden einfach die Kanalbindung und die entsprechende Berechtigung auffrischen. Darüber hinaus muss der Client 5 Minuten warten, bevor er eine zuvor gebundene Kanalnummer oder Peer-Adresse an einen anderen Kanal bindet, wodurch die Möglichkeit ausgeschlossen wird, dass die Transaktion zunächst fehlschlägt, aber bei einer erneuten Übertragung erfolgreich ist.
11.3. Empfangen einer ChannelBind-Antwort (Receiving a ChannelBind Response)
Wenn der Client eine ChannelBind-Erfolgsantwort erhält, aktualisiert er seine Datenstrukturen, um zu verzeichnen, dass die Kanalbindung jetzt aktiv ist. Er aktualisiert auch seine Datenstrukturen, um zu verzeichnen, dass die entsprechende Berechtigung installiert oder aufgefrischt wurde.
Wenn der Client eine ChannelBind-Fehlerantwort erhält, die anzeigt, dass die Kanalinformationen zwischen Client und Server nicht synchron sind (z. B. eine unerwartete 400 „Bad Request"-Antwort), wird EMPFOHLEN (RECOMMENDED), dass der Client sofort die Allokation löscht und mit einer neuen Allokation von vorne beginnt.
11.4. Die ChannelData-Nachricht (The ChannelData Message)
Die ChannelData-Nachricht wird verwendet, um Anwendungsdaten zwischen dem Client und dem Server zu übertragen. Sie hat das folgende Format:
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 /
/ /
| |
| +-------------------------------+
| |
+-------------------------------+
Das Feld Channel Number gibt die Kanalnummer an, auf der die Daten übertragen werden, und damit die Adresse des Peers, der die Daten sendet oder empfangen soll.
Das Feld Length gibt die Länge in Bytes des Feldes Application Data an (d. h. es schließt nicht die Größe des ChannelData-Headers ein). Beachten Sie, dass 0 eine gültige Länge ist.
Das Feld Application Data trägt die Daten, die der Client versucht, an den Peer zu senden, oder die der Peer an den Client sendet.
11.5. Senden einer ChannelData-Nachricht (Sending a ChannelData Message)
Sobald ein Client einen Kanal an einen Peer gebunden hat, kann er, wenn er Daten an diesen Peer zu senden hat, entweder eine ChannelData-Nachricht oder eine Send-Indikation verwenden; das heißt, der Client ist nicht verpflichtet, den Kanal zu verwenden, wenn er existiert, und steht es frei, beim Senden von Daten an den Peer einen der beiden Nachrichtentypen zu verwenden. Der Server hingegen MUSS (MUST) die ChannelData-Nachricht verwenden, wenn ein Kanal an den Peer gebunden wurde.
Die Felder der ChannelData-Nachricht werden wie in Abschnitt 11.4 beschrieben ausgefüllt.
Über TCP und TLS-over-TCP MUSS (MUST) die ChannelData-Nachricht auf ein Vielfaches von vier Bytes aufgefüllt werden, um die Ausrichtung nachfolgender Nachrichten sicherzustellen. Die Auffüllung wird nicht im Längenfeld der ChannelData-Nachricht berücksichtigt, sodass die tatsächliche Größe einer ChannelData-Nachricht (einschließlich Auffüllung) (4 + Length) auf das nächste Vielfache von 4 aufgerundet ist. Über UDP ist die Auffüllung nicht erforderlich, KANN (MAY) jedoch enthalten sein.
Die ChannelData-Nachricht wird dann auf dem 5-Tupel gesendet, das der Allokation zugeordnet ist.
11.6. Empfangen einer ChannelData-Nachricht (Receiving a ChannelData Message)
Der Empfänger einer ChannelData-Nachricht verwendet die ersten beiden Bits, um sie von einer STUN-formatierten Nachricht zu unterscheiden, wie oben beschrieben. Wenn die Nachricht einen Wert im reservierten Bereich (0x8000 bis 0xFFFF) verwendet, wird die Nachricht stillschweigend verworfen.
Wenn die ChannelData-Nachricht in einem UDP-Datagramm empfangen wird und das UDP-Datagramm zu kurz ist, um die Länge der Daten zu enthalten, die die ChannelData-Nachricht zu tragen vorgibt (d. h. der Wert des UDP-Header-Längenfeldes ist kleiner als der ChannelData-Header-Längenfeldwert + 4 + 8), dann wird die Nachricht stillschweigend verworfen.
Wenn die ChannelData-Nachricht über TCP oder TLS-over-TCP empfangen wird, dann ist die tatsächliche Länge der ChannelData-Nachricht wie in Abschnitt 11.5 beschrieben.
Wenn die ChannelData-Nachricht auf einem Kanal empfangen wird, der an keinen Peer gebunden ist, wird die Nachricht stillschweigend verworfen.
Auf dem Client wird EMPFOHLEN (RECOMMENDED), dass der Client die ChannelData-Nachricht verwirft, wenn der Client glaubt, dass es keine aktive Berechtigung zum Peer gibt. Auf dem Server DARF (MUST NOT) der Empfang einer ChannelData-Nachricht weder die Kanalbindung noch die Berechtigung zum Peer auffrischen.
Auf dem Server leitet der Server, wenn keine Fehler erkannt werden, die Anwendungsdaten an den Peer weiter, indem er ein UDP-Datagramm wie folgt bildet:
-
Die Quelltransportadresse ist die weitergeleitete Transportadresse der Allokation, wobei die Allokation durch das 5-Tupel bestimmt wird, auf dem die ChannelData-Nachricht angekommen ist.
-
Die Zieltransportadresse ist die Transportadresse, an die der Kanal gebunden ist.
-
Die Daten nach dem UDP-Header sind der Inhalt des Datenfeldes der ChannelData-Nachricht.
Das resultierende UDP-Datagramm wird dann an den Peer gesendet. Beachten Sie, dass, wenn das Feld Length in der ChannelData-Nachricht 0 ist, keine Daten im UDP-Datagramm vorhanden sein werden, das UDP-Datagramm jedoch trotzdem gebildet und gesendet wird.
11.7. Weiterleiten von Daten vom Peer (Relaying Data from the Peer)
Wenn der Server ein UDP-Datagramm auf der weitergeleiteten Transportadresse empfängt, die einer Allokation zugeordnet ist, verarbeitet er es wie in Abschnitt 10.3 beschrieben. Wenn dieser Abschnitt angibt, dass eine ChannelData-Nachricht gesendet werden sollte (weil es einen Kanal gibt, der an den Peer gebunden ist, der das UDP-Datagramm gesendet hat), dann bildet und sendet der Server eine ChannelData-Nachricht, wie in Abschnitt 11.5 beschrieben.