Zum Hauptinhalt springen

18. Transport (Transport)

Die Transportschicht ist verantwortlich für die tatsächliche Übertragung von Anfragen und Antworten über Netzwerktransporte. Dies umfasst die Bestimmung der Verbindung, die im Falle verbindungsorientierter Transporte für eine Anfrage oder Antwort zu verwenden ist.

Die Transportschicht ist verantwortlich für die Verwaltung persistenter Verbindungen für Transportprotokolle wie TCP und SCTP oder TLS darüber, einschließlich solcher, die zur Transportschicht geöffnet wurden. Dies umfasst Verbindungen, die von den Client- oder Server-Transports geöffnet wurden, sodass Verbindungen zwischen Client- und Server-Transportfunktionen gemeinsam genutzt werden. Diese Verbindungen werden durch das Tupel indiziert, das sich aus der Adresse, dem Port und dem Transportprotokoll am entfernten Ende der Verbindung zusammensetzt. Wenn eine Verbindung von der Transportschicht geöffnet wird, wird dieser Index auf die Ziel-IP, den Port und den Transport gesetzt. Wenn die Verbindung von der Transportschicht akzeptiert wird, wird dieser Index auf die Quell-IP-Adresse, die Portnummer und den Transport gesetzt. Beachten Sie, dass, da der Quellport oft flüchtig (ephemeral) ist, aber nicht bekannt sein kann, ob er flüchtig oder über die Verfahren in [4] ausgewählt ist, von der Transportschicht akzeptierte Verbindungen häufig nicht wiederverwendet werden. Das Ergebnis ist, dass zwei Proxys in einer „Peering"-Beziehung, die einen verbindungsorientierten Transport verwenden, häufig zwei Verbindungen in Benutzung haben, eine für in jede Richtung initiierte Transaktionen.

Es wird EMPFOHLEN, Verbindungen für eine implementierungsdefinierte Dauer nach der letzten über diese Verbindung gesendeten oder empfangenen Nachricht offen zu halten. Diese Dauer SOLLTE mindestens der längsten Zeitspanne entsprechen, die das Element benötigen würde, um eine Transaktion von der Instanziierung in den beendeten Zustand zu überführen. Dies dient dazu, die Wahrscheinlichkeit zu erhöhen, dass Transaktionen über dieselbe Verbindung abgeschlossen werden, auf der sie initiiert wurden (z. B. Anfrage, Antwort und im Falle eines INVITE der ACK für nicht-2xx-Antworten). Dies bedeutet normalerweise mindestens 64*T1 (siehe Abschnitt 17.1.1.1 für eine Definition von T1). Es könnte jedoch in einem Element, dessen TU einen großen Wert für Timer C verwendet (Punkt 11 von Abschnitt 16.6), größer sein.

Alle SIP-Elemente MÜSSEN UDP und TCP implementieren. SIP-Elemente DÜRFEN andere Protokolle implementieren.

  Die Verpflichtung für TCP beim UA ist eine wesentliche Änderung gegenüber RFC 2543. Sie ergab sich aus der Notwendigkeit, größere Nachrichten zu verarbeiten, die TCP verwenden MÜSSEN, wie unten erörtert. Daher muss ein Element, selbst wenn es niemals große Nachrichten sendet, in der Lage sein, eine solche zu empfangen und zu verarbeiten.

18.1 Clients (Clients)​

18.1.1 Senden von Anfragen (Sending Requests)​

Die Client-Seite der Transportschicht ist verantwortlich für das Senden der Anfrage und den Empfang von Antworten. Der Nutzer der Transportschicht übergibt dem Client-Transport die Anfrage, eine IP-Adresse, einen Port, einen Transport und möglicherweise eine TTL für Multicast-Ziele.

Wenn eine Anfrage innerhalb von 200 Byte des Pfad-MTU liegt oder wenn sie größer als 1300 Byte ist und der Pfad-MTU unbekannt ist, MUSS die Anfrage unter Verwendung eines staukontrollierten Transportprotokolls gemäß RFC 2914 [43], wie TCP, gesendet werden. Wenn dies zu einer Änderung des Transportprotokolls gegenüber dem im obersten Via angegebenen führt, MUSS der Wert im obersten Via geändert werden. Dies verhindert die Fragmentierung von Nachrichten über UDP und bietet Staukontrolle für größere Nachrichten. Implementierungen MÜSSEN jedoch in der Lage sein, Nachrichten bis zur maximalen Datagramm-Paketgröße zu verarbeiten. Für UDP beträgt diese Größe 65.535 Byte einschließlich IP- und UDP-Headern.

  Der 200-Byte-„Puffer" zwischen Nachrichtengröße und MTU berücksichtigt die Tatsache, dass die Antwort in SIP größer als die Anfrage sein kann. Dies geschieht beispielsweise durch das Hinzufügen von Record-Route-Headerfeldwerten zu den Antworten auf INVITE. Mit dem zusätzlichen Puffer kann die Antwort etwa 170 Byte größer als die Anfrage sein und dennoch in IPv4 nicht fragmentiert werden (etwa 30 Byte werden von IP/UDP verbraucht, sofern kein IPSec verwendet wird). 1300 wird gewählt, wenn der Pfad-MTU nicht bekannt ist, basierend auf der Annahme eines Ethernet-MTU von 1500 Byte.

Wenn ein Element eine Anfrage über TCP aufgrund dieser Nachrichtengrößenbeschränkungen sendet und diese Anfrage ansonsten über UDP gesendet worden wäre, SOLLTE das Element die Anfrage erneut versuchen, falls der Verbindungsaufbau entweder ein ICMP „Protocol Not Supported" erzeugt oder zu einem TCP-Reset führt, und zwar unter Verwendung von UDP. Dies dient lediglich der Abwärtskompatibilität mit RFC-2543-konformen Implementierungen, die TCP nicht unterstützen. Es wird erwartet, dass dieses Verhalten in einer zukünftigen Überarbeitung dieser Spezifikation veraltet sein wird.

Ein Client, der eine Anfrage an eine Multicast-Adresse sendet, MUSS den Parameter „maddr" zu seinem Via-Headerfeldwert hinzufügen, der die Ziel-Multicast-Adresse enthält, und für IPv4 SOLLTE er den Parameter „ttl" mit einem Wert von 1 hinzufügen. Die Verwendung von IPv6-Multicast ist in dieser Spezifikation nicht definiert und wird Gegenstand zukünftiger Standardisierung sein, sobald Bedarf besteht.

Diese Regeln führen zu einer bewussten Einschränkung von Multicast in SIP. Ihre Hauptfunktion besteht darin, einen „single-hop-discovery-ähnlichen" Dienst bereitzustellen, der eine Anfrage an eine Gruppe homogener Server liefert, wobei nur die Antwort von einem beliebigen von ihnen verarbeitet werden muss. Diese Funktionalität ist für Registrierungen am nützlichsten. Tatsächlich wird die Client-Transaktion basierend auf den Transaktionsverarbeitungsregeln in Abschnitt 17.1.3 die erste Antwort akzeptieren und alle anderen als Retransmissionen betrachten, da sie alle dieselbe Via-Branch-Kennung enthalten.

Bevor eine Anfrage gesendet wird, MUSS der Client-Transport einen Wert des Feldes „sent-by" in das Via-Headerfeld einfügen. Dieses Feld enthält eine IP-Adresse oder einen Hostnamen und einen Port. Die Verwendung eines FQDN wird EMPFOHLEN. Dieses Feld wird unter bestimmten Bedingungen, die unten beschrieben werden, zum Senden von Antworten verwendet. Wenn der Port fehlt, hängt der Standardwert vom Transport ab. Er ist 5060 für UDP, TCP und SCTP sowie 5061 für TLS.

Für zuverlässige Transporte wird die Antwort normalerweise über die Verbindung gesendet, auf der die Anfrage empfangen wurde. Daher MUSS der Client-Transport darauf vorbereitet sein, die Antwort über dieselbe Verbindung zu empfangen, die zum Senden der Anfrage verwendet wurde. Unter Fehlerbedingungen kann der Server versuchen, eine neue Verbindung zu öffnen, um die Antwort zu senden. Um diesen Fall zu behandeln, MUSS die Transportschicht auch darauf vorbereitet sein, eine eingehende Verbindung auf der Quell-IP-Adresse, von der die Anfrage gesendet wurde, und der Portnummer im Feld „sent-by" zu empfangen. Sie MUSS ebenfalls darauf vorbereitet sein, eingehende Verbindungen auf jeder Adresse und jedem Port zu empfangen, die von einem Server auf der Grundlage der in Abschnitt 5 von [4] beschriebenen Verfahren ausgewählt würden.

Für unzuverlässige Unicast-Transporte MUSS der Client-Transport darauf vorbereitet sein, Antworten auf der Quell-IP-Adresse, von der die Anfrage gesendet wird (da Antworten an die Quelladresse zurückgesendet werden), und der Portnummer im Feld „sent-by" zu empfangen. Ferner MUSS der Client, wie bei zuverlässigen Transporten, in der Lage sein, Antworten auf jeder Adresse und jedem Port zu empfangen, die von einem Server auf der Grundlage der in Abschnitt 5 von [4] beschriebenen Verfahren ausgewählt würden.

Für Multicast MUSS der Client-Transport darauf vorbereitet sein, Antworten auf derselben Multicast-Gruppe und demselben Port zu empfangen, an die die Anfrage gesendet wird (das heißt, er muss Mitglied der Multicast-Gruppe sein, an die er die Anfrage gesendet hat).

Wenn eine Anfrage an eine IP-Adresse, einen Port und einen Transport bestimmt ist, für die eine bestehende Verbindung offen ist, wird EMPFOHLEN, diese Verbindung zum Senden der Anfrage zu verwenden, es DARF jedoch eine andere Verbindung geöffnet und verwendet werden.

Wenn eine Anfrage unter Verwendung von Multicast gesendet wird, wird sie an die Gruppenadresse, den Port und die TTL gesendet, die vom Transportnutzer bereitgestellt werden. Wenn eine Anfrage unter Verwendung unzuverlässiger Unicast-Transporte gesendet wird, wird sie an die IP-Adresse und den Port gesendet, die vom Transportnutzer bereitgestellt werden.

18.1.2 Empfang von Antworten (Receiving Responses)​

Wenn eine Antwort empfangen wird, untersucht der Client-Transport den Wert des obersten Via-Headerfelds. Wenn der Wert des Parameters „sent-by" in diesem Headerfeldwert nicht mit einem Wert übereinstimmt, den der Client-Transport so konfiguriert ist, dass er ihn in Anfragen einfügt, MUSS die Antwort stillschweigend verworfen werden.

Wenn Client-Transaktionen existieren, verwendet der Client-Transport die Abgleichsverfahren aus Abschnitt 17.1.3, um zu versuchen, die Antwort einer bestehenden Transaktion zuzuordnen. Bei Übereinstimmung MUSS die Antwort an diese Transaktion weitergegeben werden. Andernfalls MUSS die Antwort an den Kern (egal ob zustandsloser Proxy, zustandsbehafteter Proxy oder UA) zur weiteren Verarbeitung weitergegeben werden. Der Umgang mit diesen „verirrten" Antworten hängt vom Kern ab (ein Proxy wird sie weiterleiten, während ein UA sie verwirft, beispielsweise).

18.2 Server (Servers)​

18.2.1 Empfang von Anfragen (Receiving Requests)​

Ein Server SOLLTE darauf vorbereitet sein, Anfragen auf jeder Kombination aus IP-Adresse, Port und Transport zu empfangen, die das Ergebnis eines DNS-Lookups auf einem SIP- oder SIPS-URI [4] sein kann, der zum Zweck der Kommunikation mit diesem Server herausgegeben wird. In diesem Kontext bedeutet „herausgeben" das Platzieren eines URI in einem Contact-Headerfeld in einer REGISTER-Anfrage oder einer Redirect-Antwort oder in einem Record-Route-Headerfeld in einer Anfrage oder Antwort. Ein URI kann auch „herausgegeben" werden, indem er auf eine Webseite oder eine Visitenkarte gesetzt wird. Es wird ebenfalls EMPFOHLEN, dass ein Server auf den standardmäßigen SIP-Ports (5060 für TCP und UDP, 5061 für TLS über TCP) auf allen öffentlichen Schnittstellen auf Anfragen lauscht. Die typische Ausnahme wären private Netzwerke oder wenn mehrere Serverinstanzen auf demselben Host ausgeführt werden. Für jeden Port und jede Schnittstelle, auf denen ein Server für UDP lauscht, MUSS er auf diesem selben Port und dieser selben Schnittstelle für TCP lauschen. Dies liegt daran, dass eine Nachricht möglicherweise mit TCP statt UDP gesendet werden muss, wenn sie zu groß ist. Folglich gilt das Umgekehrte nicht. Ein Server muss nicht für UDP auf einer bestimmten Adresse und einem bestimmten Port lauschen, nur weil er auf derselben Adresse und demselben Port für TCP lauscht. Es kann selbstverständlich andere Gründe geben, warum ein Server für UDP auf einer bestimmten Adresse und einem bestimmten Port lauschen muss.

Wenn der Server-Transport eine Anfrage über einen beliebigen Transport empfängt, MUSS er den Wert des Parameters „sent-by" im obersten Via-Headerfeldwert prüfen. Wenn der Host-Teil des Parameters „sent-by" einen Domänennamen enthält oder wenn er eine IP-Adresse enthält, die sich von der Paketquelladresse unterscheidet, MUSS der Server einen Parameter „received" zu diesem Via-Headerfeldwert hinzufügen. Dieser Parameter MUSS die Quelladresse enthalten, von der das Paket empfangen wurde. Dies dient dazu, der Server-Transportschicht beim Senden der Antwort zu helfen, da sie an die Quell-IP-Adresse gesendet werden muss, von der die Anfrage kam.

Betrachten Sie eine Anfrage, die vom Server-Transport empfangen wurde und die teilweise wie folgt aussieht:

  INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP bobspc.biloxi.com:5060

Die Anfrage wird mit einer Quell-IP-Adresse von 192.0.2.4 empfangen. Bevor die Anfrage nach oben weitergegeben wird, fügt der Transport einen Parameter „received" hinzu, sodass die Anfrage teilweise wie folgt aussehen würde:

  INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP bobspc.biloxi.com:5060;received=192.0.2.4

Als Nächstes versucht der Server-Transport, die Anfrage einer Server-Transaktion zuzuordnen. Dies geschieht anhand der in Abschnitt 17.2.3 beschriebenen Abgleichsregeln. Wenn eine passende Server-Transaktion gefunden wird, wird die Anfrage zu deren Verarbeitung weitergegeben. Wenn keine Übereinstimmung gefunden wird, wird die Anfrage an den Kern weitergegeben, der entscheiden kann, eine neue Server-Transaktion für diese Anfrage zu konstruieren. Beachten Sie, dass, wenn ein UAS-Kern eine 2xx-Antwort auf einen INVITE sendet, die Server-Transaktion zerstört wird. Das bedeutet, dass bei Ankunft des ACK keine passende Server-Transaktion vorhanden sein wird und die Anfrage gemäß dieser Regel an den UAS-Kern weitergegeben wird, wo sie verarbeitet wird.

18.2.2 Senden von Antworten (Sending Responses)​

Der Server-Transport verwendet den Wert des obersten Via-Headerfelds, um zu bestimmen, wohin eine Antwort gesendet werden soll. Er MUSS dem folgenden Prozess folgen:

  o  Wenn das „sent-protocol" ein zuverlässiges Transportprotokoll wie TCP oder SCTP oder TLS darüber ist, MUSS die Antwort über die bestehende Verbindung zur Quelle der ursprünglichen Anfrage gesendet werden, die die Transaktion erstellt hat, sofern diese Verbindung noch offen ist. Dies erfordert, dass der Server-Transport eine Zuordnung zwischen Server-Transaktionen und Transportverbindungen aufrechterhält. Wenn diese Verbindung nicht mehr offen ist, SOLLTE der Server eine Verbindung zur IP-Adresse im Parameter „received", sofern vorhanden, unter Verwendung des Ports im Wert „sent-by" oder des Standardports für diesen Transport öffnen, falls kein Port angegeben ist. Wenn dieser Verbindungsversuch fehlschlägt, SOLLTE der Server die Verfahren in [4] für Server verwenden, um die IP-Adresse und den Port zum Öffnen der Verbindung und Senden der Antwort zu bestimmen.

  o  Andernfalls, wenn der Via-Headerfeldwert einen Parameter „maddr" enthält, MUSS die Antwort an die dort aufgeführte Adresse gesendet werden, unter Verwendung des im „sent-by" angegebenen Ports oder des Ports 5060, falls keiner vorhanden ist. Wenn die Adresse eine Multicast-Adresse ist, SOLLTE die Antwort mit dem im Parameter „ttl" angegebenen TTL gesendet werden oder mit einem TTL von 1, falls dieser Parameter nicht vorhanden ist.

  o  Andernfalls (für unzuverlässige Unicast-Transporte), wenn der oberste Via einen Parameter „received" hat, MUSS die Antwort an die Adresse im Parameter „received" gesendet werden, unter Verwendung des im Wert „sent-by" angegebenen Ports oder des Ports 5060, falls keiner explizit angegeben ist. Wenn dies fehlschlägt, z. B. eine ICMP-„port unreachable"-Antwort auslöst, SOLLTEN die Verfahren des Abschnitts 5 von [4] verwendet werden, um zu bestimmen, wohin die Antwort gesendet wird.

  o  Andernfalls, wenn sie nicht durch den Empfänger markiert ist, MUSS die Antwort an die durch den Wert „sent-by" angegebene Adresse gesendet werden, unter Verwendung der Verfahren in Abschnitt 5 von [4].

18.3 Rahmenbildung (Framing)​

Im Falle nachrichtenorientierter Transporte (wie UDP) wird, wenn die Nachricht ein Content-Length-Headerfeld hat, angenommen, dass der Nachrichtenrumpf diese Anzahl von Byte enthält. Wenn im Transportpaket über das Ende des Rumpfs hinaus zusätzliche Byte vorhanden sind, MÜSSEN diese verworfen werden. Wenn das Transportpaket vor dem Ende des Nachrichtenrumpfs endet, wird dies als Fehler betrachtet. Wenn die Nachricht eine Antwort ist, MUSS sie verworfen werden. Wenn die Nachricht eine Anfrage ist, SOLLTE das Element eine 400-Antwort (Bad Request) erzeugen. Wenn die Nachricht kein Content-Length-Headerfeld hat, wird angenommen, dass der Nachrichtenrumpf am Ende des Transportpakets endet.

Im Falle stromorientierter Transporte wie TCP gibt das Content-Length-Headerfeld die Größe des Rumpfs an. Das Content-Length-Headerfeld MUSS bei stromorientierten Transporten verwendet werden.

18.4 Fehlerbehandlung (Error Handling)​

Die Fehlerbehandlung ist unabhängig davon, ob die Nachricht eine Anfrage oder eine Antwort war.

Wenn der Transportnutzer das Senden einer Nachricht über einen unzuverlässigen Transport anfordert und das Ergebnis ein ICMP-Fehler ist, hängt das Verhalten vom Typ des ICMP-Fehlers ab. Host-, Network-, Port- oder Protocol-unreachable-Fehler oder Parameter-Problem-Fehler SOLLTEN die Transportschicht veranlassen, den Transportnutzer über einen Sende-Fehler zu informieren. Source-quench- und TTL-exceeded-ICMP-Fehler SOLLTEN ignoriert werden.

Wenn der Transportnutzer das Senden einer Anfrage über einen zuverlässigen Transport anfordert und das Ergebnis ein Verbindungsfehler ist, SOLLTE die Transportschicht den Transportnutzer über einen Sende-Fehler informieren.