6. Erstellen einer Allokation
Eine Allokation auf dem Server wird mit einer Allocate-Transaktion erstellt.
6.1. Senden einer Allocate-Anfrage
Der Client bildet eine Allocate-Anfrage wie folgt.
Der Client wählt zunächst eine Host-Transportadresse aus. Es wird empfohlen, dass der Client eine unbenutzte Transportadresse wählt, typischerweise indem er dem zugrunde liegenden Betriebssystem erlaubt, einen unbenutzten Port für einen neuen Socket auszuwählen.
Der Client wählt dann ein Transportprotokoll aus, das zwischen dem Client und dem Server verwendet werden soll. Das Transportprotokoll muss UDP, TCP oder TLS-over-TCP sein. Da diese Spezifikation nur UDP zwischen dem Server und den Peers erlaubt, wird empfohlen, dass der Client UDP wählt, es sei denn, er hat einen Grund, ein anderes Transport zu verwenden. Ein Grund, ein anderes Transport zu wählen, wäre, dass der Client glaubt (möglicherweise durch Konfiguration oder durch Experimente), dass er keinen TURN-Server mit UDP kontaktieren kann. Siehe Abschnitt 2.1 für weitere Diskussionen.
Der Client wählt auch eine Server-Transportadresse aus, was wie folgt erfolgen sollte. Der Client erhält (möglicherweise durch Konfiguration) einen Domänennamen für einen TURN-Server. Der Client verwendet dann die in [RFC5389] beschriebenen DNS-Verfahren, jedoch mit einem SRV-Dienstnamen von „turn" (oder „turns" für TURN über TLS) anstelle von „stun" (oder „stuns"). Um beispielsweise Server in der Domain example.com zu finden, führt der Client eine Suche nach '_turn._udp.example.com', '_turn._tcp.example.com' und '_turns._tcp.example.com' durch, wenn der Client mit dem Server über UDP, TCP bzw. TLS-over-TCP kommunizieren möchte.
Der Client muss ein REQUESTED-TRANSPORT-Attribut in die Anfrage einschließen. Dieses Attribut gibt das Transportprotokoll zwischen dem Server und den Peers an (beachten Sie, dass dies nicht das Transportprotokoll ist, das im 5-Tupel erscheint). In dieser Spezifikation ist der REQUESTED-TRANSPORT-Typ immer UDP. Dieses Attribut ist enthalten, um zukünftigen Erweiterungen zu ermöglichen, andere Protokolle anzugeben.
Wenn der Client möchte, dass der Server das Feld Zeit bis zum Ablauf der Allokation auf einen anderen Wert als die Standardlebensdauer initialisiert, kann er ein LIFETIME-Attribut einschließen, das seinen gewünschten Wert angibt. Dies ist nur eine Anfrage, und der Server kann wählen, einen anderen Wert zu verwenden. Beachten Sie, dass der Server Anfragen ignoriert, das Feld auf einen Wert kleiner als den Standardwert zu initialisieren.
Wenn der Client später das DONT-FRAGMENT-Attribut in einer oder mehreren Send-Indikationen auf dieser Allokation verwenden möchte, sollte der Client das DONT-FRAGMENT-Attribut in die Allocate-Anfrage einschließen. Dies ermöglicht es dem Client zu testen, ob der Server dieses Attribut unterstützt.
Wenn der Client verlangt, dass die Portnummer der weitergeleiteten Transportadresse gerade ist, schließt der Client das EVEN-PORT-Attribut ein. Wenn dieses Attribut nicht eingeschlossen ist, kann der Port gerade oder ungerade sein. Durch Setzen des R-Bits im EVEN-PORT-Attribut auf 1 kann der Client anfordern, dass der Server die nächsthöhere Portnummer (auf derselben IP-Adresse) für eine nachfolgende Allokation reserviert. Wenn das R-Bit 0 ist, wird keine solche Anfrage gestellt.
Der Client kann auch ein RESERVATION-TOKEN-Attribut in die Anfrage einschließen, um den Server zu bitten, einen zuvor reservierten Port für die Allokation zu verwenden. Wenn das RESERVATION-TOKEN-Attribut eingeschlossen ist, muss der Client das EVEN-PORT-Attribut weglassen.
Nach der Konstruktion sendet der Client die Allocate-Anfrage über das 5-Tupel.
6.2. Empfangen einer Allocate-Anfrage
Wenn der Server eine Allocate-Anfrage erhält, führt er die folgenden Prüfungen durch:
-
Der Server muss verlangen, dass die Anfrage authentifiziert wird. Diese Authentifizierung muss mit dem Langzeit-Credential-Mechanismus von [RFC5389] durchgeführt werden, es sei denn, der Client und der Server vereinbaren, einen anderen Mechanismus durch ein Verfahren außerhalb des Umfangs dieses Dokuments zu verwenden.
-
Der Server prüft, ob das 5-Tupel derzeit von einer vorhandenen Allokation verwendet wird. Wenn ja, lehnt der Server die Anfrage mit einem 437-Fehler (Allocation Mismatch) ab.
-
Der Server prüft, ob die Anfrage ein REQUESTED-TRANSPORT-Attribut enthält. Wenn das REQUESTED-TRANSPORT-Attribut nicht enthalten oder fehlerhaft ist, lehnt der Server die Anfrage mit einem 400-Fehler (Bad Request) ab. Andernfalls, wenn das Attribut enthalten ist, aber ein anderes Protokoll als UDP angibt, lehnt der Server die Anfrage mit einem 442-Fehler (Unsupported Transport Protocol) ab.
-
Die Anfrage kann ein DONT-FRAGMENT-Attribut enthalten. Wenn ja, aber der Server das Senden von UDP-Datagrammen mit auf 1 gesetztem DF-Bit nicht unterstützt (siehe Abschnitt 12), behandelt der Server das DONT-FRAGMENT-Attribut in der Allocate-Anfrage als unbekanntes verständniserforderliches Attribut.
-
Der Server prüft, ob die Anfrage ein RESERVATION-TOKEN-Attribut enthält. Wenn ja und die Anfrage auch ein EVEN-PORT-Attribut enthält, lehnt der Server die Anfrage mit einem 400-Fehler (Bad Request) ab. Andernfalls prüft er, ob das Token gültig ist (d. h., das Token liegt im Bereich und ist nicht abgelaufen und die entsprechende weitergeleitete Transportadresse ist noch verfügbar). Wenn das Token aus irgendeinem Grund ungültig ist, lehnt der Server die Anfrage mit einem 508-Fehler (Insufficient Capacity) ab.
-
Der Server prüft, ob die Anfrage ein EVEN-PORT-Attribut enthält. Wenn ja, prüft der Server, ob er die Anfrage erfüllen kann (d. h., eine weitergeleitete Transportadresse wie unten beschrieben zuweisen kann). Wenn der Server die Anfrage nicht erfüllen kann, lehnt der Server die Anfrage mit einem 508-Fehler (Insufficient Capacity) ab.
-
Zu jedem Zeitpunkt kann der Server wählen, die Anfrage mit einem 486-Fehler (Allocation Quota Reached) abzulehnen, wenn er das Gefühl hat, dass der Client versucht, eine lokal definierte Allokationsquote zu überschreiten. Der Server ist frei, diese Allokationsquote auf beliebige Weise zu definieren, sollte sie jedoch basierend auf dem zur Authentifizierung der Anfrage verwendeten Benutzernamen und nicht auf der Transportadresse des Clients definieren.
-
Ebenfalls zu jedem Zeitpunkt kann der Server wählen, die Anfrage mit einem 300-Fehler (Try Alternate) abzulehnen, wenn er den Client zu einem anderen Server umleiten möchte. Die Verwendung dieses Fehlercodes und Attributs folgt der Spezifikation in [RFC5389].
Wenn alle Prüfungen bestanden werden, erstellt der Server die Allokation. Das 5-Tupel wird auf das 5-Tupel aus der Allocate-Anfrage gesetzt, während die Liste der Berechtigungen und die Liste der Kanäle zunächst leer sind.
Der Server wählt eine weitergeleitete Transportadresse für die Allokation wie folgt:
-
Wenn die Anfrage ein RESERVATION-TOKEN enthält, verwendet der Server die zuvor reservierte Transportadresse, die dem enthaltenen Token entspricht (wenn sie noch verfügbar ist). Beachten Sie, dass die Reservierung eine serverweite Reservierung ist und nicht spezifisch für eine bestimmte Allokation, da die Allocate-Anfrage, die das RESERVATION-TOKEN enthält, ein anderes 5-Tupel verwendet als die Allocate-Anfrage, die die Reservierung vorgenommen hat. Das 5-Tupel für die Allocate-Anfrage, die das RESERVATION-TOKEN-Attribut enthält, kann jedes zulässige 5-Tupel sein; es kann eine andere Client-IP-Adresse und einen anderen Port, ein anderes Transportprotokoll und sogar eine andere Server-IP-Adresse und einen anderen Port verwenden (vorausgesetzt, dass die Server-IP-Adresse und der Port solche sind, auf denen der Server auf TURN-Anfragen hört).
-
Wenn die Anfrage ein EVEN-PORT-Attribut mit auf 0 gesetztem R-Bit enthält, weist der Server eine weitergeleitete Transportadresse mit einer geraden Portnummer zu.
-
Wenn die Anfrage ein EVEN-PORT-Attribut mit auf 1 gesetztem R-Bit enthält, sucht der Server nach einem Paar von Portnummern N und N+1 auf derselben IP-Adresse, wobei N gerade ist. Port N wird in der aktuellen Allokation verwendet, während die weitergeleitete Transportadresse mit Port N+1 ein Token zugewiesen bekommt und für eine zukünftige Allokation reserviert wird. Der Server muss diese Reservierung mindestens 30 Sekunden lang halten und kann wählen, sie länger zu halten (z. B. bis die Allokation mit Port N abläuft). Der Server schließt dann das Token in ein RESERVATION-TOKEN-Attribut in der Erfolgsantwort ein.
-
Andernfalls weist der Server eine beliebige verfügbare weitergeleitete Transportadresse zu.
In allen Fällen sollte der Server nur Ports aus dem Bereich 49152 - 65535 (der dynamische und/oder private Portbereich [Port-Numbers]) zuweisen, es sei denn, die TURN-Serveranwendung weiß durch ein hier nicht spezifiziertes Mittel, dass andere Anwendungen, die auf demselben Host wie die TURN-Serveranwendung laufen, nicht durch die Zuweisung von Ports außerhalb dieses Bereichs beeinträchtigt werden. Diese Bedingung kann oft erfüllt werden, indem die TURN-Serveranwendung auf einer dedizierten Maschine ausgeführt wird und/oder indem vereinbart wird, dass alle anderen Anwendungen auf der Maschine Ports zuweisen, bevor die TURN-Serveranwendung startet. In jedem Fall sollte der TURN-Server keine Ports aus dem Bereich 0 - 1023 (der bekannte Portbereich) zuweisen, um Clients davon abzuhalten, TURN zum Ausführen von Standarddiensten zu verwenden.
HINWEIS: Die IETF untersucht derzeit das Thema zufällige Portzuweisungen, um bestimmte Arten von Angriffen zu vermeiden (siehe [TSVWG-PORT]). Es wird dringend empfohlen, dass TURN-Implementierer dieses Thema im Auge behalten und gegebenenfalls einen randomisierten Portzuweisungsalgorithmus implementieren. Dies gilt insbesondere für Server, die eine Anzahl von Ports vom zugrunde liegenden Betriebssystem vorab zuweisen und sie dann später Allokationen zuweisen; beispielsweise kann ein Server diese Technik wählen, um das EVEN-PORT-Attribut zu implementieren.
Der Server bestimmt den Anfangswert des Felds Zeit bis zum Ablauf wie folgt. Wenn die Anfrage ein LIFETIME-Attribut enthält, berechnet der Server das Minimum der vom Client vorgeschlagenen Lebensdauer und der maximal zulässigen Lebensdauer des Servers. Wenn dieser berechnete Wert größer als die Standardlebensdauer ist, verwendet der Server die berechnete Lebensdauer als Anfangswert des Felds Zeit bis zum Ablauf. Andernfalls verwendet der Server die Standardlebensdauer. Es wird empfohlen, dass der Server einen maximal zulässigen Lebensdauerwert von nicht mehr als 3600 Sekunden (1 Stunde) verwendet. Server, die Allokationsquoten implementieren oder Benutzer auf irgendeine Weise für Allokationen berechnen, möchten möglicherweise eine kleinere maximal zulässige Lebensdauer (möglicherweise so klein wie die Standardlebensdauer) verwenden, um verwaiste Allokationen (d. h. Allokationen, bei denen der entsprechende Client abgestürzt oder beendet wurde oder die Clientverbindung aus irgendeinem Grund verloren gegangen ist) schneller zu entfernen. Beachten Sie auch, dass die Zeit bis zum Ablauf bei jeder erfolgreichen Refresh-Anfrage neu berechnet wird, sodass der hier berechnete Wert nur bis zur ersten Aktualisierung gilt.
Nach der Erstellung der Allokation antwortet der Server mit einer Erfolgsantwort. Die Erfolgsantwort enthält:
-
Ein XOR-RELAYED-ADDRESS-Attribut, das die weitergeleitete Transportadresse enthält.
-
Ein LIFETIME-Attribut, das den aktuellen Wert des Timers Zeit bis zum Ablauf enthält.
-
Ein RESERVATION-TOKEN-Attribut (wenn eine zweite weitergeleitete Transportadresse reserviert wurde).
-
Ein XOR-MAPPED-ADDRESS-Attribut, das die IP-Adresse und den Port des Clients (aus dem 5-Tupel) enthält.
HINWEIS: Das XOR-MAPPED-ADDRESS-Attribut ist in der Antwort zur Bequemlichkeit des Clients enthalten. TURN selbst nutzt diesen Wert nicht, aber Clients, die ICE ausführen, benötigen diesen Wert normalerweise und können so vermeiden, eine zusätzliche Binding-Transaktion mit einem STUN-Server durchführen zu müssen, um ihn zu erhalten.
Die Antwort (Erfolg oder Fehler) wird über das 5-Tupel an den Client zurückgesendet.
HINWEIS: Wenn die Allocate-Anfrage über UDP gesendet wird, verlangt Abschnitt 7.3.1 von [RFC5389], dass der Server mögliche Neuübertragungen der Anfrage so behandelt, dass Neuübertragungen nicht zur Erstellung mehrerer Allokationen führen. Implementierungen können dies mit dem sogenannten „zustandslosen Stack-Ansatz" wie folgt erreichen. Um Neuübertragungen zu erkennen, wenn eine ursprüngliche Anfrage erfolgreich eine Allokation erstellt hat, kann der Server die Transaktions-ID, die in der Erstellungsanfrage verwendet wurde, mit den Allokationsdaten speichern und sie mit eingehenden Allocate-Anfragen auf demselben 5-Tupel vergleichen. Sobald eine solche Anfrage erkannt wird, kann der Server das Parsen der Anfrage stoppen und sofort eine Erfolgsantwort generieren. Beim Erstellen dieser Antwort kann der Wert des LIFETIME-Attributs aus dem Feld Zeit bis zum Ablauf in den Allokationszustandsdaten entnommen werden, auch wenn dieser Wert geringfügig vom ursprünglich zurückgegebenen LIFETIME-Wert abweichen kann. Darüber hinaus muss der Server möglicherweise eine Angabe jedes in der ursprünglichen Antwort zurückgegebenen Reservierungs-Tokens speichern, damit dieses in allen neu übertragenen Antworten zurückgegeben werden kann.
Für den Fall, dass die ursprüngliche Anfrage keine Allokation erstellen konnte, kann der Server wählen, nichts Besonderes zu tun. Beachten Sie jedoch, dass es einen seltenen Fall gibt, in dem der Server die ursprüngliche Anfrage ablehnt, aber die neu übertragene Anfrage akzeptiert (weil sich die Bedingungen in der kurzen Zwischenzeit geändert haben). Wenn der Client die erste (Ablehnungs-)Antwort erhält, ignoriert er die zweite (Erfolgs-)Antwort und glaubt, dass keine Allokation erstellt wurde. Eine auf diese Weise erstellte Allokation wird schließlich ablaufen, da der Client sie nicht aktualisiert. Wenn der Client später mit demselben 5-Tupel, aber einer anderen Transaktions-ID erneut versucht, erhält er einen 437-Fehler (Allocation Mismatch), der ihn dazu veranlasst, mit einem anderen 5-Tupel erneut zu versuchen. Der Server kann die Lebensdauer von auf diese Weise „verwaisten" Allokationen minimieren, indem er einen kleineren maximalen Lebensdauerwert verwendet.
6.3. Empfangen einer Allocate-Erfolgsantwort
Wenn der Client eine Allocate-Erfolgsantwort erhält, muss er prüfen, dass sowohl die gemappte Adresse als auch die weitergeleitete Transportadresse in der Adressfamilie liegen, die der Client versteht und zu handhaben bereit ist. Diese Spezifikation deckt nur den Fall ab, in dem beide Adressen IPv4-Adressen sind. Wenn eine der beiden Adressen nicht in einer Adressfamilie liegt, die der Client zu handhaben bereit ist, muss der Client die Allokation löschen (Abschnitt 7) und darf nicht versuchen, eine andere Allokation auf diesem Server zu erstellen, bis er glaubt, dass die Nichtübereinstimmung behoben wurde.
Die IETF erwägt derzeit Mechanismen für den Übergang zwischen IPv4 und IPv6, die dazu führen könnten, dass ein Client eine Allocate-Anfrage über IPv6 initiiert, die Anfrage aber über IPv4 beim Server ankommt, oder umgekehrt.
Andernfalls erstellt der Client seine eigene Kopie der Allokationsdatenstruktur, um zu verfolgen, was auf dem Server geschieht. Insbesondere muss sich der Client an die tatsächliche vom Server erhaltene Lebensdauer erinnern und nicht an den Wert, der in der Anfrage an den Server gesendet wurde. Der Client muss sich auch an das für die Anfrage verwendete 5-Tupel und an den Benutzernamen und das Passwort erinnern, die er zur Authentifizierung der Anfrage verwendet hat, um sicherzustellen, dass er sie für nachfolgende Nachrichten wiederverwendet. Der Client muss auch die Kanäle und Berechtigungen verfolgen, die er auf dem Server einrichtet.
Der Client möchte möglicherweise die weitergeleitete Transportadresse an Peers senden (mit einer hier nicht spezifizierten Methode), damit die Peers mit ihm kommunizieren können. Der Client möchte möglicherweise auch die serverreflexive Adresse verwenden, die er im XOR-MAPPED-ADDRESS-Attribut erhält, in seiner ICE-Verarbeitung.
6.4. Empfangen einer Allocate-Fehlerantwort
Wenn der Client eine Allocate-Fehlerantwort erhält, hängt die Verarbeitung vom tatsächlich zurückgegebenen Fehlercode ab:
-
(Anfrage abgelaufen, Request Timed Out): Es gibt entweder ein Problem mit dem Server oder ein Problem, den Server mit dem gewählten Transport zu erreichen. Der Client betrachtet die aktuelle Transaktion als fehlgeschlagen, kann aber wählen, die Allocate-Anfrage mit einem anderen Transport (z. B. TCP statt UDP) erneut zu versuchen.
-
300 (Try Alternate): Der Server möchte, dass der Client stattdessen den im ALTERNATE-SERVER-Attribut angegebenen Server verwendet. Der Client betrachtet die aktuelle Transaktion als fehlgeschlagen, sollte aber eine Allocate-Anfrage mit dem alternativen Server versuchen, bevor er andere Server (z. B. andere mit den SRV-Verfahren entdeckte Server) versucht. Wenn er die Allocate-Anfrage mit dem alternativen Server versucht, folgt der Client den in [RFC5389] angegebenen ALTERNATE-SERVER-Verfahren.
-
400 (Bad Request): Der Server glaubt, dass die Anfrage des Clients aus irgendeinem Grund fehlerhaft ist. Der Client betrachtet die aktuelle Transaktion als fehlgeschlagen. Der Client kann den Benutzer oder Operator benachrichtigen und sollte die Anfrage nicht mit diesem Server wiederholen, bis er glaubt, dass das Problem behoben wurde.
-
401 (Unauthorized): Wenn der Client die Verfahren des Langzeit-Credential-Mechanismus befolgt hat und trotzdem diesen Fehler erhält, akzeptiert der Server die Credentials des Clients nicht. In diesem Fall betrachtet der Client die aktuelle Transaktion als fehlgeschlagen und sollte den Benutzer oder Operator benachrichtigen. Der Client sollte keine weiteren Anfragen an diesen Server senden, bis er glaubt, dass das Problem behoben wurde.
-
403 (Forbidden): Die Anfrage ist gültig, aber der Server weigert sich, sie auszuführen, wahrscheinlich aufgrund administrativer Einschränkungen. Der Client betrachtet die aktuelle Transaktion als fehlgeschlagen. Der Client kann den Benutzer oder Operator benachrichtigen und sollte nicht dieselbe Anfrage mit diesem Server wiederholen, bis er glaubt, dass das Problem behoben wurde.
-
420 (Unknown Attribute): Wenn der Client ein DONT-FRAGMENT-Attribut in die Anfrage eingeschlossen hat und der Server die Anfrage mit einem 420-Fehlercode abgelehnt und das DONT-FRAGMENT-Attribut im UNKNOWN-ATTRIBUTES-Attribut der Fehlerantwort aufgelistet hat, weiß der Client jetzt, dass der Server das DONT-FRAGMENT-Attribut nicht unterstützt. Der Client betrachtet die aktuelle Transaktion als fehlgeschlagen, kann aber wählen, die Allocate-Anfrage ohne das DONT-FRAGMENT-Attribut erneut zu versuchen.
-
437 (Allocation Mismatch): Dies zeigt an, dass der Client ein 5-Tupel ausgewählt hat, das der Server als bereits verwendet ansieht. Eine Möglichkeit, wie dies geschehen kann, ist, wenn ein zwischengeschaltetes NAT eine gemappte Transportadresse zugewiesen hat, die von einem anderen Client verwendet wurde, der kürzlich abgestürzt ist. Der Client betrachtet die aktuelle Transaktion als fehlgeschlagen. Der Client sollte eine andere Client-Transportadresse wählen und die Allocate-Anfrage erneut versuchen (mit einer anderen Transaktions-ID). Der Client sollte drei verschiedene Client-Transportadressen versuchen, bevor er diesen Server aufgibt. Sobald der Client den Server aufgibt, sollte er 2 Minuten lang nicht versuchen, eine andere Allokation auf dem Server zu erstellen.
-
438 (Stale Nonce): Siehe die Verfahren für den Langzeit-Credential-Mechanismus [RFC5389].
-
441 (Wrong Credentials): Der Client sollte diesen Fehler nicht als Antwort auf eine Allocate-Anfrage erhalten. Der Client kann den Benutzer oder Operator benachrichtigen und sollte nicht dieselbe Anfrage mit diesem Server wiederholen, bis er glaubt, dass das Problem behoben wurde.
-
442 (Unsupported Transport Address): Der Client sollte diesen Fehler nicht als Antwort auf eine UDP-Allokationsanfrage erhalten. Der Client kann den Benutzer oder Operator benachrichtigen und sollte die Anfrage nicht mit diesem Server erneut versuchen, bis er glaubt, dass das Problem behoben wurde.
-
486 (Allocation Quota Reached): Der Server kann derzeit mit diesem Benutzernamen keine weiteren Allokationen erstellen. Der Client betrachtet die aktuelle Transaktion als fehlgeschlagen. Der Client sollte mindestens 1 Minute warten, bevor er versucht, weitere Allokationen auf dem Server zu erstellen.
-
508 (Insufficient Capacity): Der Server hat keine weiteren weitergeleiteten Transportadressen mehr verfügbar oder keine mit den angeforderten Eigenschaften, oder die dem angegebenen Reservierungs-Token entsprechende Adresse ist nicht verfügbar. Der Client betrachtet die aktuelle Operation als fehlgeschlagen. Wenn der Client das EVEN-PORT- oder RESERVATION-TOKEN-Attribut verwendet, kann der Client wählen, dieses Attribut zu entfernen oder zu ändern und sofort erneut zu versuchen. Andernfalls sollte der Client mindestens 1 Minute warten, bevor er versucht, weitere Allokationen auf diesem Server zu erstellen.
Eine unbekannte Fehlerantwort muss wie in [RFC5389] beschrieben behandelt werden.