Zum Hauptinhalt springen

4. Message Transmission (Nachrichtenübertragung)

CoAP-Nachrichten werden asynchron zwischen CoAP-Endpunkten ausgetauscht. Sie werden verwendet, um CoAP-Anfragen und -Antworten zu transportieren, deren Semantik in Abschnitt 5 definiert ist.

Da CoAP an unzuverlässige Transports wie UDP gebunden ist, können CoAP-Nachrichten in falscher Reihenfolge ankommen, dupliziert erscheinen oder ohne Benachrichtigung verloren gehen. Aus diesem Grund implementiert CoAP einen leichtgewichtigen Zuverlässigkeitsmechanismus, ohne zu versuchen, den vollständigen Funktionsumfang eines Transports wie TCP nachzubilden. Es verfügt über folgende Merkmale:

  • Einfache Stop-and-Wait-Neuübertragungszuverlässigkeit mit exponentiellem Back-off für bestätigbare Nachrichten (Confirmable messages).

  • Duplikaterkennung sowohl für bestätigbare als auch für nicht bestätigbare Nachrichten (Non-confirmable messages).

4.1. Messages and Endpoints (Nachrichten und Endpunkte)

Ein CoAP-Endpunkt ist die Quelle oder das Ziel einer CoAP-Nachricht. Die spezifische Definition eines Endpunkts hängt vom für CoAP verwendeten Transport ab. Für die in dieser Spezifikation definierten Transports wird der Endpunkt abhängig vom verwendeten Sicherheitsmodus identifiziert (siehe Abschnitt 9): Ohne Sicherheit wird der Endpunkt ausschließlich durch eine IP-Adresse und eine UDP-Portnummer identifiziert. Bei anderen Sicherheitsmodi wird der Endpunkt wie durch den Sicherheitsmodus definiert identifiziert.

Es gibt verschiedene Nachrichtentypen. Der Typ einer Nachricht wird durch das Type-Feld des CoAP-Headers angegeben.

Getrennt vom Nachrichtentyp kann eine Nachricht eine Anfrage, eine Antwort tragen oder leer (Empty) sein. Dies wird durch das Request/Response Code-Feld im CoAP-Header signalisiert und ist für das Request/Response-Modell relevant. Mögliche Werte für das Feld werden in den CoAP Code Registries (Abschnitt 12.1) verwaltet.

Eine leere Nachricht hat das Code-Feld auf 0.00 gesetzt. Das Token Length-Feld MUSS auf 0 gesetzt werden und Datenbytes DÜRFEN NICHT nach dem Message ID-Feld vorhanden sein. Wenn Bytes vorhanden sind, MÜSSEN sie als Nachrichtenformatfehler verarbeitet werden.

4.2. Messages Transmitted Reliably (Zuverlässig übertragene Nachrichten)

Die zuverlässige Übertragung einer Nachricht wird initiiert, indem die Nachricht im CoAP-Header als Confirmable markiert wird. Eine Confirmable-Nachricht trägt immer entweder eine Anfrage oder eine Antwort, es sei denn, sie wird nur verwendet, um eine Reset-Nachricht hervorzurufen, in diesem Fall ist sie leer. Ein Empfänger MUSS entweder (a) eine Confirmable-Nachricht mit einer Acknowledgement-Nachricht bestätigen oder (b) die Nachricht ablehnen, wenn dem Empfänger der Kontext fehlt, um die Nachricht ordnungsgemäß zu verarbeiten, einschließlich Situationen, in denen die Nachricht leer ist, einen Code mit einer reservierten Klasse (1, 6 oder 7) verwendet oder einen Nachrichtenformatfehler aufweist. Das Ablehnen einer Confirmable-Nachricht erfolgt durch Senden einer entsprechenden Reset-Nachricht und ansonsten durch Ignorieren. Die Acknowledgement-Nachricht MUSS die Message ID der Confirmable-Nachricht zurückgeben und MUSS eine Antwort tragen oder leer sein (siehe Abschnitte 5.2.1 und 5.2.2). Die Reset-Nachricht MUSS die Message ID der Confirmable-Nachricht zurückgeben und MUSS leer sein. Das Ablehnen einer Acknowledgement- oder Reset-Nachricht (einschließlich des Falls, in dem das Acknowledgement eine Anfrage oder einen Code mit einer reservierten Klasse trägt oder die Reset-Nachricht nicht leer ist) erfolgt durch stillschweigendes Ignorieren. Allgemeiner gesagt DÜRFEN Empfänger von Acknowledgement- und Reset-Nachrichten NICHT mit Acknowledgement- oder Reset-Nachrichten antworten.

Der Absender überträgt die Confirmable-Nachricht in exponentiell zunehmenden Intervallen erneut, bis er eine Bestätigung (oder Reset-Nachricht) erhält oder keine Versuche mehr hat.

Die Neuübertragung wird durch zwei Dinge gesteuert, die ein CoAP-Endpunkt für jede Confirmable-Nachricht, die es sendet, während es auf eine Bestätigung (oder Reset) wartet, verfolgen MUSS: ein Timeout und einen Neuübertragungszähler. Für eine neue Confirmable-Nachricht wird das anfängliche Timeout auf eine zufällige Dauer (oft keine ganzzahlige Anzahl von Sekunden) zwischen ACK_TIMEOUT und (ACK_TIMEOUT * ACK_RANDOM_FACTOR) gesetzt (siehe Abschnitt 4.8), und der Neuübertragungszähler wird auf 0 gesetzt. Wenn das Timeout ausgelöst wird und der Neuübertragungszähler kleiner als MAX_RETRANSMIT ist, wird die Nachricht erneut übertragen, der Neuübertragungszähler wird erhöht und das Timeout wird verdoppelt. Wenn der Neuübertragungszähler bei einem Timeout MAX_RETRANSMIT erreicht oder wenn der Endpunkt eine Reset-Nachricht erhält, wird der Versuch, die Nachricht zu übertragen, abgebrochen und der Anwendungsprozess über den Fehler informiert. Wenn andererseits der Endpunkt rechtzeitig eine Bestätigung erhält, gilt die Übertragung als erfolgreich.

Diese Spezifikation stellt keine strengen Anforderungen an die Genauigkeit der Uhren, die zur Implementierung des oben genannten binären exponentiellen Back-off-Algorithmus verwendet werden. Insbesondere kann ein Endpunkt aufgrund seines Schlafplans zu spät für eine bestimmte Neuübertragung sein und bei der nächsten aufholen. Der minimale Abstand vor einer weiteren Neuübertragung beträgt jedoch ACK_TIMEOUT, und die gesamte Sequenz von (Neu-)Übertragungen MUSS innerhalb der Hüllkurve von MAX_TRANSMIT_SPAN bleiben (siehe Abschnitt 4.8.2), auch wenn dies bedeutet, dass ein Absender möglicherweise eine Übertragungsmöglichkeit verpasst.

Ein CoAP-Endpunkt, das eine Confirmable-Nachricht gesendet hat, KANN beim Versuch, ein ACK zu erhalten, aufgeben, noch bevor der Zählerwert MAX_RETRANSMIT erreicht ist. Zum Beispiel hat die Anwendung die Anfrage abgebrochen, da sie keine Antwort mehr benötigt, oder es gibt einen anderen Hinweis darauf, dass die CON-Nachricht tatsächlich angekommen ist. Insbesondere kann eine CoAP-Anfragenachricht eine separate Antwort hervorgerufen haben, in diesem Fall ist es dem Anforderer klar, dass nur das ACK verloren ging und eine Neuübertragung der Anfrage keinen Zweck erfüllen würde. Ein Responder DARF sich jedoch NICHT seinerseits auf dieses schichtübergreifende Verhalten eines Anforderers verlassen, d.h., er MUSS den Status beibehalten, um das ACK für die Anfrage zu erstellen, falls erforderlich, auch wenn eine Confirmable-Antwort bereits vom Anforderer bestätigt wurde.

Ein weiterer Grund für das Aufgeben der Neuübertragung KANN der Empfang von ICMP-Fehlern sein. Wenn es gewünscht ist, ICMP-Fehler zu berücksichtigen, um potenzielle Spoofing-Angriffe zu mildern, SOLLTEN Implementierungen darauf achten, die Informationen über das ursprüngliche Datagramm in der ICMP-Nachricht zu überprüfen, einschließlich Portnummern und CoAP-Header-Informationen wie Nachrichtentyp und -code, Message ID und Token; wenn dies aufgrund von Einschränkungen der UDP-Service-API nicht möglich ist, SOLLTEN ICMP-Fehler ignoriert werden. Packet Too Big-Fehler [RFC4443] ("fragmentation needed and DF set" für IPv4 [RFC0792]) können nicht ordnungsgemäß auftreten und SOLLTEN ignoriert werden, wenn der Implementierungshinweis in Abschnitt 4.6 befolgt wird; andernfalls SOLLTEN sie in einen Pfad-MTU-Discovery-Algorithmus [RFC4821] einfließen. Source Quench- und Time Exceeded-ICMP-Nachrichten SOLLTEN ignoriert werden. Host-, Netzwerk-, Port- oder Protokoll-Unreachable-Fehler oder Parameter-Problem-Fehler KÖNNEN nach angemessener Überprüfung verwendet werden, um die Anwendung über einen Sendefehler zu informieren.

4.3. Messages Transmitted without Reliability (Ohne Zuverlässigkeit übertragene Nachrichten)

Einige Nachrichten erfordern keine Bestätigung. Dies gilt insbesondere für Nachrichten, die für Anwendungsanforderungen regelmäßig wiederholt werden, wie z.B. wiederholte Ablesungen von einem Sensor, bei denen ein eventueller Erfolg ausreicht.

Als leichtgewichtigere Alternative kann eine Nachricht weniger zuverlässig übertragen werden, indem die Nachricht als Non-confirmable markiert wird. Eine Non-confirmable-Nachricht trägt immer entweder eine Anfrage oder eine Antwort und DARF NICHT leer sein. Eine Non-confirmable-Nachricht DARF NICHT vom Empfänger bestätigt werden. Ein Empfänger MUSS die Nachricht ablehnen, wenn ihm der Kontext fehlt, um die Nachricht ordnungsgemäß zu verarbeiten, einschließlich des Falls, in dem die Nachricht leer ist, einen Code mit einer reservierten Klasse (1, 6 oder 7) verwendet oder einen Nachrichtenformatfehler aufweist. Das Ablehnen einer Non-confirmable-Nachricht KANN das Senden einer entsprechenden Reset-Nachricht beinhalten, und abgesehen von der Reset-Nachricht MUSS die abgelehnte Nachricht stillschweigend ignoriert werden.

Auf CoAP-Ebene gibt es keine Möglichkeit für den Absender zu erkennen, ob eine Non-confirmable-Nachricht empfangen wurde oder nicht. Ein Absender KANN wählen, mehrere Kopien einer Non-confirmable-Nachricht innerhalb von MAX_TRANSMIT_SPAN zu übertragen (begrenzt durch die Bestimmungen von Abschnitt 4.7, insbesondere durch PROBING_RATE, wenn keine Antwort empfangen wird), oder das Netzwerk kann die Nachricht während der Übertragung duplizieren. Um es dem Empfänger zu ermöglichen, nur einmal auf die Nachricht zu reagieren, geben Non-confirmable-Nachrichten ebenfalls eine Message ID an. (Diese Message ID wird aus demselben Zahlenraum wie die Message IDs für Confirmable-Nachrichten gezogen.)

Zusammenfassend für die Abschnitte 4.2 und 4.3 können die vier Nachrichtentypen wie in Tabelle 1 verwendet werden. "*" bedeutet, dass die Kombination nicht im normalen Betrieb verwendet wird, sondern nur um eine Reset-Nachricht hervorzurufen ("CoAP ping").

               +----------+-----+-----+-----+-----+
| | CON | NON | ACK | RST |
+----------+-----+-----+-----+-----+
| Request | X | X | - | - |
| Response | X | X | X | - |
| Empty | * | - | X | X |
+----------+-----+-----+-----+-----+

Tabelle 1: Verwendung der Nachrichtentypen

4.4. Message Correlation (Nachrichtenkorrelation)

Eine Acknowledgement- oder Reset-Nachricht wird mittels der Message ID zusammen mit zusätzlichen Adressinformationen des entsprechenden Endpunkts mit einer Confirmable- oder Non-confirmable-Nachricht korreliert. Die Message ID ist eine 16-Bit-Ganzzahl ohne Vorzeichen, die vom Absender einer Confirmable- oder Non-confirmable-Nachricht generiert und im CoAP-Header enthalten ist. Der Empfänger MUSS die Message ID in der Acknowledgement- oder Reset-Nachricht zurückgeben.

Dieselbe Message ID DARF NICHT innerhalb von EXCHANGE_LIFETIME (bei Kommunikation mit demselben Endpunkt) wiederverwendet werden (Abschnitt 4.8.2).

Implementierungshinweis: Es können mehrere Implementierungsstrategien zur Generierung von Message IDs verwendet werden. Im einfachsten Fall generiert ein CoAP-Endpunkt Message IDs, indem es eine einzige Message ID-Variable beibehält, die jedes Mal geändert wird, wenn eine neue Confirmable- oder Non-confirmable-Nachricht gesendet wird, unabhängig von der Zieladresse oder dem Port. Ein Endpunkt, der eine große Anzahl von Transaktionen verarbeiten muss, könnte mehrere Message ID-Variablen beibehalten, z.B. eine pro Präfix oder Zieladresse. (Beachten Sie, dass einige empfangende Endpunkte möglicherweise nicht zwischen an sie adressierten Unicast- und Multicast-Paketen unterscheiden können, daher müssen Endpunkte, die Message IDs generieren, sicherstellen, dass diese sich nicht überlappen.) Es wird dringend empfohlen, dass der Anfangswert der Variable (z.B. beim Start) randomisiert wird, um die Wahrscheinlichkeit erfolgreicher Off-Path-Angriffe auf das Protokoll zu verringern.

Damit eine Acknowledgement- oder Reset-Nachricht mit einer Confirmable- oder Non-confirmable-Nachricht übereinstimmt, MÜSSEN die Message ID und der Quellendpunkt der Acknowledgement- oder Reset-Nachricht mit der Message ID und dem Zielendpunkt der Confirmable- oder Non-confirmable-Nachricht übereinstimmen.

4.5. Message Deduplication (Nachrichtendeduplizierung)

Ein Empfänger kann innerhalb von EXCHANGE_LIFETIME (Abschnitt 4.8.2) mehrmals dieselbe Confirmable-Nachricht (wie durch Message ID und Quellendpunkt angezeigt) erhalten, beispielsweise wenn sein Acknowledgement verloren ging oder den ursprünglichen Absender nicht vor dem ersten Timeout erreichte. Der Empfänger SOLLTE jede duplizierte Kopie einer Confirmable-Nachricht mit derselben Acknowledgement- oder Reset-Nachricht bestätigen, SOLLTE jedoch jede Anfrage oder Antwort in der Nachricht nur einmal verarbeiten. Die Lockerung dieser Regel für den Fall, dass die in der Confirmable-Nachricht übertragene Anfrage idempotent ist (siehe Abschnitt 5.1) oder auf idempotente Weise verarbeitet werden kann, wird im nächsten Abschnitt diskutiert. Beispiele für gelockerte Nachrichtendeduplizierung:

  • Ein Server kann die Anforderung lockern, alle Neuübertragungen einer idempotenten Anfrage mit derselben Antwort zu beantworten (Abschnitt 4.2), damit er keinen Status für die Message ID aufrechterhalten muss. Beispielsweise möchte eine Implementierung möglicherweise doppelte Übertragungen einer GET-, PUT- oder DELETE-Anfrage als separate Anfragen behandeln, wenn die resultierende Arbeitsmenge billiger ist als der Aufwand, frühere Antworten zu verfolgen.

  • Ein eingeschränkter Server möchte möglicherweise sogar diese Anforderung für bestimmte nicht-idempotente Anfragen lockern, wenn die Anwendungssemantik diesen Kompromiss günstig macht. Wenn beispielsweise das Ergebnis einer POST-Anfrage nur die Erstellung eines kurzlebigen Status auf dem Server ist, kann es billiger sein, diesen Aufwand mehrmals für eine Anfrage zu verursachen, als zu verfolgen, ob eine frühere Übertragung derselben Anfrage bereits bearbeitet wurde.

Ein Empfänger kann innerhalb von NON_LIFETIME (Abschnitt 4.8.2) mehrmals dieselbe Non-confirmable-Nachricht (wie durch Message ID und Quellendpunkt angezeigt) erhalten. Als allgemeine Regel (die basierend auf der spezifischen Semantik einer Nachricht gelockert werden kann) SOLLTE der Empfänger jede duplizierte Non-confirmable-Nachricht stillschweigend ignorieren und SOLLTE jede Anfrage oder Antwort in der Nachricht nur einmal verarbeiten.

4.6. Message Size (Nachrichtengröße)

Obwohl es wünschenswert ist, dass die Nachrichten in ein einzelnes IP-Paket passen (IP-Fragmentierung vermeiden), ist dies eine Frage der Implementierungsqualität. Die CoAP-Spezifikation selbst bietet nur eine Obergrenze für die Nachrichtengröße. Nachrichten, die größer als ein IP-Paket sind, führen zu unerwünschter Paketfragmentierung. Eine CoAP-Nachricht sollte, entsprechend gekapselt, in ein einzelnes IP-Paket passen (d.h. IP-Fragmentierung vermeiden) und (durch Einpassen in eine UDP-Nutzlast) offensichtlich in ein einzelnes IP-Datagramm passen. Wenn die Pfad-MTU nicht bekannt ist, SOLLTE eine IP-MTU von 1280 Bytes angenommen werden; wenn über die Größe der Header nichts bekannt ist, sind gute Obergrenzen 1152 Bytes für die Nachrichtengröße und 1024 Bytes für die Nutzlastgröße.

Implementierungshinweis: Die Wahl der Nachrichtengrößenparameter von CoAP funktioniert gut mit IPv6 und mit den meisten heutigen IPv4-Pfaden. (Mit IPv4 ist es jedoch schwieriger, absolut sicherzustellen, dass keine IP-Fragmentierung stattfindet. Wenn es wesentlich ist, IPv4 in ungewöhnlichen Netzwerken zu unterstützen, möchten Implementierungen sich möglicherweise auf konservativere IPv4-Datagrammgrößen wie 576 Bytes beschränken; gemäß [RFC0791] beträgt das absolute Minimum für die IP-MTU in IPv4 nur 68 Bytes, was nur 40 Bytes abzüglich Sicherheitsoverhead für die UDP-Nutzlast übrig lassen würde. Implementierungen, die sich extrem auf diese Problemstellung konzentrieren, möchten möglicherweise auch das IPv4 DF-Bit setzen und eine Form der Pfad-MTU-Discovery [RFC4821] durchführen; dies ist jedoch in realistischen Anwendungsfällen von CoAP im Allgemeinen unnötig.) Wichtiger in vielen eingeschränkten Netzwerken ist die Fragmentierung auf der Adaptionsschicht (z.B. sind 6LoWPAN-L2-Pakete auf 127 Bytes einschließlich verschiedener Overheads beschränkt); dies kann Implementierungen dazu motivieren, bei ihren Paketgrößen sparsam zu sein und zum blockweisen Transfer [BLOCK] zu wechseln, wenn sie sich Nachrichtengrößen im dreistelligen Bereich nähern.

Die Nachrichtengröße ist auch für Implementierer auf eingeschränkten Knoten von erheblicher Bedeutung. Viele Implementierungen müssen einen Puffer für eingehende Nachrichten zuweisen. Wenn eine Implementierung zu eingeschränkt ist, um die Zuweisung der oben genannten Obergrenze zu ermöglichen, kann sie die folgende Implementierungsstrategie für Nachrichten anwenden, die keine DTLS-Sicherheit verwenden: Die Implementierung, die ein Datagramm in einen zu kleinen Puffer empfängt, ist normalerweise in der Lage zu bestimmen, ob das Ende des Datagramms verworfen wurde, und den Anfangsteil abzurufen. Somit passen zumindest der CoAP-Header und die Optionen (wenn nicht die gesamte Nutzlast) wahrscheinlich in den Puffer. Daher kann ein Server die Anfrage vollständig interpretieren und einen 4.13 (Request Entity Too Large; siehe Abschnitt 5.9.2.9) Antwortcode zurückgeben, wenn die Nutzlast abgeschnitten wurde. Ein Client, der eine idempotente Anfrage sendet und eine Antwort erhält, die größer ist als in seinen Puffer passt, kann die Anfrage mit einem geeigneten Wert für die Block-Option [BLOCK] wiederholen.

4.7. Congestion Control (Staukontrolle)

Die grundlegende Staukontrolle für CoAP wird durch den exponentiellen Back-off-Mechanismus in Abschnitt 4.2 bereitgestellt.

Um keine Stauung zu verursachen, MÜSSEN Clients (einschließlich Proxies) die Anzahl gleichzeitiger ausstehender Interaktionen, die sie zu einem bestimmten Server (einschließlich Proxies) aufrechterhalten, strikt auf NSTART begrenzen. Eine ausstehende Interaktion ist entweder ein CON (Nachrichtenschicht), für das noch kein ACK empfangen wurde und noch darauf gewartet wird, oder eine Anfrage (abgleichbar durch Message ID und Token), für die weder eine Antwort noch eine Acknowledgement-Nachricht empfangen wurde und noch darauf gewartet wird (beides kann gleichzeitig auftreten und zählt als eine ausstehende Interaktion). Der Standardwert für NSTART in dieser Spezifikation ist 1.

Weitere Staukontrolloptimierungen und -überlegungen werden in Zukunft erwartet, wie z.B. eine mögliche automatische Initialisierung der in Abschnitt 4.8 definierten CoAP-Übertragungsparameter, was dann auch Werte von NSTART größer als 1 ermöglichen könnte.

Nach EXCHANGE_LIFETIME hört ein Client auf, eine Antwort auf eine Confirmable-Anfrage zu erwarten, für die keine Acknowledgement-Nachricht empfangen wurde. Der spezifische Algorithmus, durch den ein Client aufhört, eine Antwort auf eine Anfrage zu "erwarten", die bestätigt wurde oder auf eine Non-confirmable-Anfrage, ist nicht definiert. Sofern nicht durch zusätzliche Staukontrolloptimierungen modifiziert, MUSS er so gewählt werden, dass ein Endpunkt beim Senden an einen anderen Endpunkt, der nicht antwortet, eine durchschnittliche Datenrate von PROBING_RATE nicht überschreitet.

Hinweis: CoAP legt die Verantwortung für die Staukontrolle hauptsächlich auf die Clients. Clients können jedoch fehlfunktionieren oder tatsächlich Angreifer sein, z.B. um Verstärkungsangriffe durchzuführen (Abschnitt 11.3). Um den Schaden (für das Netzwerk und seine eigenen Energieressourcen) zu begrenzen, SOLLTE ein Server eine gewisse Ratenbegrenzung für seine Antwortübertragung basierend auf vernünftigen Annahmen über Anwendungsanforderungen implementieren. Hierfür KANN ein Server separate Ratenbegrenzer für verschiedene Dienste und Ressourcen einsetzen.

4.8. Transmission Parameters (Übertragungsparameter)

Die Nachrichtenübertragung wird durch folgende Parameter gesteuert:

               +-------------------+---------------+
| name | default value |
+-------------------+---------------+
| ACK_TIMEOUT | 2 seconds |
| ACK_RANDOM_FACTOR | 1.5 |
| MAX_RETRANSMIT | 4 |
| NSTART | 1 |
| DEFAULT_LEISURE | 5 seconds |
| PROBING_RATE | 1 byte/second |
+-------------------+---------------+

Tabelle 2: CoAP-Protokollparameter

4.8.1. Changing the Parameters (Änderung der Parameter)

Die Werte für ACK_TIMEOUT, ACK_RANDOM_FACTOR, MAX_RETRANSMIT, NSTART, DEFAULT_LEISURE (Abschnitt 8.2) und PROBING_RATE können auf Werte konfiguriert werden, die spezifisch für die Anwendungsumgebung sind (einschließlich dynamisch angepasster Werte); die Konfigurationsmethode liegt jedoch außerhalb des Geltungsbereichs dieses Dokuments. Es wird EMPFOHLEN, dass eine Anwendungsumgebung konsistente Werte für diese Parameter verwendet; die spezifischen Auswirkungen des Betriebs mit inkompatiblen Werten in einer Anwendungsumgebung liegen außerhalb des Geltungsbereichs dieser Spezifikation.

Die Übertragungsparameter wurden gewählt, um ein sicheres Verhalten für die Verwendung im Internet zu erreichen. Wenn die Konfiguration andere Werte verwenden möchte, ist die Konfiguration dafür verantwortlich sicherzustellen, dass diese Staukontrolleigenschaften nicht verletzt werden. Insbesondere würde eine Verringerung von ACK_TIMEOUT unter 1 Sekunde gegen die Richtlinien von [RFC5405] verstoßen. ([RTO-CONSIDER] liefert zusätzlichen Hintergrund.) CoAP wurde entwickelt, um Implementierungen zu ermöglichen, die keine Messungen der Rundlaufzeit (RTT) aufrechterhalten. Wenn jedoch der Wunsch besteht, ACK_TIMEOUT erheblich zu verringern oder NSTART zu erhöhen, kann dies nur sicher durchgeführt werden, wenn solche Messungen aufrechterhalten werden. Eine Konfiguration DARF ACK_TIMEOUT NICHT verringern oder NSTART NICHT ohne Verwendung von Mechanismen erhöhen, die die Sicherheit der Staukontrolle gewährleisten, die entweder in der Konfiguration oder in einem zukünftigen Standarddokument definiert werden können.

ACK_RANDOM_FACTOR DARF NICHT unter 1.0 verringert werden, und er SOLLTE einen Wert haben, der ausreichend unterschiedlich von 1.0 ist, um einen gewissen Schutz vor Synchronisationseffekten zu bieten.

MAX_RETRANSMIT kann frei angepasst werden, aber niedrigere Werte verringern die Wahrscheinlichkeit, dass eine Confirmable-Nachricht tatsächlich empfangen wird, während größere Werte als hier angegeben weitere Anpassungen der Zeitwerte erfordern (siehe Abschnitt 4.8.2).

Wenn die Wahl der Übertragungsparameter zu einer Erhöhung der abgeleiteten Zeitwerte führt (siehe Abschnitt 4.8.2), MUSS der Konfigurationsmechanismus sicherstellen, dass die angepassten Werte auch für alle Endpunkte verfügbar sind, die unter Verwendung dieser angepassten Werte kommunizieren sollen.

4.8.2. Time Values Derived from Transmission Parameters (Von Übertragungsparametern abgeleitete Zeitwerte)

Die Kombination von ACK_TIMEOUT, ACK_RANDOM_FACTOR und MAX_RETRANSMIT beeinflusst das Timing der Neuübertragungen, was wiederum beeinflusst, wie lange bestimmte Informationselemente von einer Implementierung aufbewahrt werden müssen. Um eindeutig auf diese abgeleiteten Zeitwerte verweisen zu können, geben wir ihnen wie folgt Namen:

MAX_TRANSMIT_SPAN: Maximale Zeit von der ersten Übertragung einer Confirmable-Nachricht bis zu ihrer letzten Neuübertragung. Für die Standard-Übertragungsparameter beträgt der Wert (2+4+8+16)*1.5 = 45 Sekunden, oder allgemeiner:

ACK_TIMEOUT * ((2 ** MAX_RETRANSMIT) - 1) * ACK_RANDOM_FACTOR

MAX_TRANSMIT_WAIT: Maximale Zeit von der ersten Übertragung einer Confirmable-Nachricht bis zu dem Zeitpunkt, an dem der Absender aufgibt, eine Bestätigung oder Reset zu erhalten. Für die Standard-Übertragungsparameter beträgt der Wert (2+4+8+16+32)*1.5 = 93 Sekunden, oder allgemeiner:

ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT + 1)) - 1) * ACK_RANDOM_FACTOR

Zusätzlich müssen einige Annahmen über die Eigenschaften des Netzwerks und der Knoten getroffen werden.

MAX_LATENCY: Maximale Zeit, die ein Datagramm voraussichtlich vom Beginn seiner Übertragung bis zum Abschluss seines Empfangs benötigt. Diese Konstante bezieht sich auf die MSL (Maximum Segment Lifetime) von [RFC0793], die "willkürlich als 2 Minuten definiert" ist (Glossar [RFC0793], Seite 81). Beachten Sie, dass dies nicht notwendigerweise kleiner als MAX_TRANSMIT_WAIT ist, da MAX_LATENCY nicht dazu gedacht ist, eine Situation zu beschreiben, in der das Protokoll gut funktioniert, sondern die Worst-Case-Situation, gegen die sich das Protokoll schützen muss. Wir definieren MAX_LATENCY ebenfalls willkürlich als 100 Sekunden. Abgesehen davon, dass es für die meisten Konfigurationen ziemlich realistisch ist und nahe an der historischen Wahl für TCP liegt, ermöglicht dieser Wert auch, dass Message ID-Lebensdauer-Timer in 8 Bits dargestellt werden können (wenn in Sekunden gemessen). In diesen Berechnungen wird nicht angenommen, dass die Übertragungsrichtung irrelevant ist (d.h., dass das Netzwerk symmetrisch ist); es wird einfach angenommen, dass derselbe Wert vernünftigerweise als Maximalwert für beide Richtungen verwendet werden kann. Wenn dies nicht der Fall ist, werden die folgenden Berechnungen nur geringfügig komplexer.

PROCESSING_DELAY: Die Zeit, die ein Knoten benötigt, um eine Confirmable-Nachricht in eine Bestätigung umzuwandeln. Wir nehmen an, dass der Knoten versucht, ein ACK zu senden, bevor der Absender ein Timeout hat, daher setzen wir es als konservative Annahme gleich ACK_TIMEOUT.

MAX_RTT: Maximale Rundlaufzeit, oder:

(2 * MAX_LATENCY) + PROCESSING_DELAY

Aus diesen Werten können wir die folgenden für den Protokollbetrieb relevanten Werte ableiten:

EXCHANGE_LIFETIME: Zeit vom Beginn des Sendens einer Confirmable-Nachricht bis zu dem Zeitpunkt, an dem eine Bestätigung nicht mehr erwartet wird, d.h. Nachrichtenschichtinformationen über den Nachrichtenaustausch können gelöscht werden. EXCHANGE_LIFETIME umfasst einen MAX_TRANSMIT_SPAN, eine MAX_LATENCY für die Vorwärtsrichtung, PROCESSING_DELAY und eine MAX_LATENCY für die Rückrichtung. Beachten Sie, dass, wenn die Konfiguration so gewählt wird, dass die letzte Wartezeit (die ACK_TIMEOUT * (2 ** MAX_RETRANSMIT) oder die Differenz zwischen MAX_TRANSMIT_SPAN und MAX_TRANSMIT_WAIT ist) kleiner als MAX_LATENCY ist, dann MAX_TRANSMIT_WAIT nicht berücksichtigt werden muss -- eine Wahl, die hier getroffen wurde, da MAX_LATENCY ein Worst-Case-Wert ist, der in realistischen unteren Schichten unwahrscheinlich ist. In diesem Fall vereinfacht sich EXCHANGE_LIFETIME zu:

MAX_TRANSMIT_SPAN + (2 * MAX_LATENCY) + PROCESSING_DELAY

oder 247 Sekunden mit den Standard-Übertragungsparametern.

NON_LIFETIME: Zeit vom Senden einer Non-confirmable-Nachricht bis zu dem Zeitpunkt, an dem ihre Message ID sicher wiederverwendet werden kann. Wenn die Mehrfachübertragung der NON-Nachricht nicht verwendet wird, beträgt ihr Wert MAX_LATENCY oder 100 Sekunden. Ein CoAP-Absender kann jedoch eine NON-Nachricht mehrmals senden, insbesondere für Multicast-Anwendungen. Implementierungen, die NON-Nachrichten während der Übertragung nicht verfolgen, möchten möglicherweise einen konservativeren Wert verwenden. Obwohl die Spezifikation keine spezifische Grenze hierfür definiert, erfolgt in den meisten Fällen die zuverlässige Erkennung von Duplikaten durch den Empfänger auf der Zeitskala von MAX_TRANSMIT_SPAN. Daher ist es für diesen Zweck sicherer zu verwenden:

MAX_TRANSMIT_SPAN + MAX_LATENCY

oder 145 Sekunden mit den Standard-Übertragungsparametern; eine Implementierung, die jedoch einen einzelnen Timeout-Wert verwenden möchte, um Message IDs für alle Nachrichtentypen ablaufen zu lassen, kann sicher den größeren Wert von EXCHANGE_LIFETIME verwenden.

Tabelle 3 listet die in diesem Unterabschnitt eingeführten abgeleiteten Parameter zusammen mit ihren Standardwerten auf.

               +-------------------+---------------+
| name | default value |
+-------------------+---------------+
| MAX_TRANSMIT_SPAN | 45 s |
| MAX_TRANSMIT_WAIT | 93 s |
| MAX_LATENCY | 100 s |
| PROCESSING_DELAY | 2 s |
| MAX_RTT | 202 s |
| EXCHANGE_LIFETIME | 247 s |
| NON_LIFETIME | 145 s |
+-------------------+---------------+

Tabelle 3: Abgeleitete Protokollparameter