Dies ist eine C ++ (11) Implementierung des sicheren Echtzeit-Medienflussprotokolls (RTMFP), wie in RFC 7016 beschrieben.
Die Bibliothek umfasst Beispielplattformadapter und andere Dienstprogramme, wie z. B. eine einfache select() basierende Laufschleife, diese müssen jedoch nicht verwendet werden. Die Protokollimplementierung soll an jede Hostprogrammumgebung anpassbar sein.
Die Bibliothek ist für Clients, Server und P2P -Anwendungen gedacht. Es enthält die notwendigen Helfer und Rückrufhaken zur Unterstützung der P2P -Einführung und des Lastausgleichs.
Das test enthält Unit -Tests und Beispiele. Besonders beachten Sie tcserver , ein einfacher RTMFP- und RTMP -Live -Media -Server. tcrelay , ein RTMFP ↔︎ RTMP -Relais/Proxy; und redirector , ein einfacher Lastausgleich.
Die vollständigste API -Dokumentation befindet sich derzeit in der Header -Datei rtmfp.hpp .
Eine Anwendung instanziiert einen IPlatformAdapter und einen ICryptoAdapter , dann ein com::zenomt::rtmfp::RTMFP (das diese Adapter erfordert). In der Regel muss der Plattformadapter der neuen RTMFP -Instanz mitgeteilt werden, damit die Plattformmethoden der Instanz (z. B. howLongToSleep() und onReceivePacket() ) aufrufen können.
Die Plattform fügt mindestens eine Schnittstelle hinzu, indem RTMFP::addInterface() aufgerufen wird.
Die Anwendung kann das Senden von Flows an neue oder aktuelle Endpunkte mit RTMFP::openFlow() und Flow::openFlow öffnen und die zugehörigen Rückflüsse mit RecvFlow::openReturnFlow() öffnen.
Die Anwendung kann neue Flows akzeptieren, indem die onRecvFlow -Rückrufe auf dem RTMFP (für bloße eingehende Ströme) oder auf SendFlow S (für zugehörige Rückflüsse) festgelegt werden.
Die Anwendung kann Nachrichten an weitaus Peers mit SendFlow::write() senden und Nachrichten von fernen Kollegen empfangen, indem der onMessage -Rückruf auf RecvFlow s eingestellt wird. Nachrichten können ablaufen und aufgegeben werden, wenn sie nicht durch Fristen pro Message oder durch willkürliche Anwendungslogik mit dem von SendFlow::write() zurückgegebenen WriteReceipt S oder einer beliebigen Anwendungslogik geliefert werden. Die Anwendung kann durch Rückruf benachrichtigt werden, wenn eine Nachricht übermittelt oder abgebrochen wird.
SendFlow s auf Priorität/Vorrang PRI_PRIORITY , PRI_IMMEDIATE , PRI_FLASH oder PRI_FLASHOVERRIDE gelten als zeitlich kritisch. Das Senden zeitkritischer Nachrichten wirkt sich auf die Überlastungskontrolle aus.
Wenn dies erledigt ist, kann die Anwendung das RTMFP ordentlich oder abrupt abschätzen.
Die Protokollimplementierung ist Single-Threaded und hat keine Schlösser/Mutexes. Alle Aufrufe seiner APIs müssen extern synchronisiert werden, beispielsweise alle im selben Thread- oder Run-Loop-ähnlichen Konstrukt. Dies wurde durchgeführt, um die Portabilität und Leistung zu verbessern, da das Sperren bei modernen CPUs sehr teuer sein kann. Die Synchronisation wird nach der perform des Plattformadapters abstrahiert, damit einige teure oder zeitaufwändige Vorgänge in andere Kerne/Threads abgestoßen werden.
Die Protokollimplementierung interagiert nicht direkt mit den UDP -Sockets, der Uhr, den Ausführen von Schleifen, Schlössern oder Fäden des Betriebssystems. Diese Interaktionen werden an einen vom Host -Programm bereitgestellten Plattformadapter abstrahiert.
Der Plattformadapter wird eine konkrete Implementierung von com::zenomt::rtmfp::IPlatformAdapter sein, das die RTMFP Public Instance -Methoden in seinem Abschnitt „Vom Plattformadapter verwendet“ aufruft. Der Adapter bietet die aktuelle Zeit, das Lesen und Schreiben von Sockets, Timing und Synchronisation.
Die Bibliothek bietet zwei Beispiel-Plattformadapter, die in RunLoop S ausgeführt werden: PosixPlatformAdapter für reine Single-Threaded-Anwendungen und PerformerPosixPlatformAdapter , damit die Cryptographie von CPU-intensiven öffentlichen Tasten in einen Arbeiter-Thread abgeladen werden kann. Diese Plattformadapter sollten für viele Anwendungen für UNIX-ähnliche Betriebssysteme geeignet sein und als Beispiele für das Schreiben von Einzel- und Multi-Thread-Plattformadaptern für Ihre Host-Anwendung dienen.
Es ist nicht erforderlich, dass die Schnittstellen von Plattformadapter UDP -Sockets sein. Beispielsweise kann eine Schnittstelle ein Socken oder einen Tunnel- oder Netzwerksimulator sein.
Für Unix-ähnliche Betriebssysteme bietet diese Bibliothek eine einfache select() -basierte Laufschleife, die für viele Socket-basierte Anwendungen geeignet ist. Es enthält auch eine einfache epoll Laufschleife für Linux, die besser als select() für die Behandlung vieler Steckdosen skaliert wird. Verwenden Sie den PreferredRunLoop -Alias, um automatisch die beste verfügbare Variante zum Kompilierzeit für das Zielbetrieb zu wählen.
Ein Performer kann an eine Run -Schleife angebracht werden, um eine Aufgabe innerhalb/synchronisiert mit der Laufschleife von jedem Thread zu ermöglichen. Performer werden mit dem PerformerPosixPlatformAdapter verwendet.
Microsoft Windows ist keine offiziell unterstützte Plattform. Die Kernbibliothek (mit Ausnahme der Plattformadapter, Ausführung von Schleifen und Performer ) sollte jedoch auf Windows aufbauen, und die Wartung des Kerns für diese Plattform wird als Zeit und Hilfe der Community versucht. Bitte öffnen Sie ein Problem, wenn die Kernbibliothek unter Windows ein Problem gibt.
Um diese Bibliothek unter Windows zu verwenden, müssen Sie einen geeigneten Plattformadapter angeben.
Bitte wenden Sie sich an den Betreuer oder öffnen Sie ein Problem, um einen Link zu Ihrem Windows -Plattformadapter in diesem Dokument hinzuzufügen.
RFC 7016 beschreibt einen verallgemeinerten Rahmen für die Sicherung der RTMFP -Kommunikation entsprechend den Anforderungen der Anwendung und überlässt kryptografische Einzelheiten für ein Kryptographieprofil . Diese Bibliothek sperrt ihre Anwendung nicht auf ein bestimmtes Kryptographieprofil und wird geschrieben, um viele potenzielle Profile zu unterstützen. Das Cryptography -Profil wird durch einen konkreten ICryptoAdapter implementiert, der dem RTMFP zur Instanziierung zur Verfügung gestellt wird.
Die meisten Anwendungen von RTMFP verwenden das in RFC 7425 beschriebene Cryptography -Profil für Flash -Kommunikation. Dies wird vom FlashCryptoAdapter bereitgestellt. Beachten Sie, dass dieser Adapter abstrakt ist und unterklassifiziert werden muss, um konkrete Implementierungen der erforderlichen kryptografischen Primitiven bereitzustellen. Eine konkrete Implementierung unter Verwendung von OpenSSL wird von FlashCryptoAdapter_OpenSSL bereitgestellt, das auch als Beispiel für die Verwendung anderer Kryptographie -Bibliotheken dienen kann. Wenn Sie OpenSSL nicht haben oder es nicht verwenden möchten, können Sie das Erstellen dieses Moduls unterdrücken, indem Sie definieren, dass er WITHOUT_OPENSSL Variable make . Wenn Ihr OpenSSL außerhalb der Standardeinstellung Ihres Compiler -Standards und der Linker -Suchpfade installiert ist, können Sie definieren, wie Variablen OPENSSL_INCLUDEDIR und OPENSSL_LIBDIR mit geeigneten Anweisungen (Beispiele siehe Makefile) und OpenSL_Libdir make können (Beispiele finden Sie unter dem Makefile ).
Die OpenSSL-Implementierung des FlashCryptoAdapter implementiert 4096-Bit Internet Key Exchange (IKE) Group 16, 2048-Bit IKE Group 14 und 1024-Bit Ike Group 2 für Diffie-Hellman-Schlüsselvereinbarung. Alle Implementierungen des Cryptography -Profils der Flash -Kommunikation müssen mindestens Gruppe 2 implementieren. Einige implementieren auch Gruppe 14. Diese Implementierung bevorzugt die stärkste gemeinsame Gruppe.
Beachten Sie, dass RTMFP nicht auf die Kommunikation mit Flash -Plattform beschränkt ist. Diese Bibliothek bietet einen PlainCryptoAdapter , der zum Testen und Bewertung geeignet ist. Da es keine tatsächliche Kryptographie bietet (und seine cryptoHash256() und pseudoRandomBytes() -Methoden sind besonders schwach), ist es nicht für die Produktion im offenen Internet geeignet. Nicht.
Bufferbloat (übermäßige Pufferung und Warteschlange im Netzwerk) kann zu Verzögerungen bei hoher End-to-End-Verspätungen führen, was zu einer inakzeptablen Leistung für Echtzeitanwendungen führt. Leider wird die beste Lösung für dieses Problem (aktives Warteschlangenmanagement mit explizitem Überlastungsbenachrichtigung) derzeit nicht allgemein im Internet eingesetzt.
Zusätzlich zu den normalen Überlastungssignalen (Verlust und explizite Überlastungsbenachrichtigung) kann diese Bibliothek optional durch eine Sitzung auf eine Sitzung aus einer Erhöhung der Hin- und Rückfahrt (RTT) eintreten. Um diese Fähigkeit zu ermöglichen, verwenden Sie Flow::setSessionCongestionDelay() um eine Menge zusätzlicher Verzögerung über die Basis -RTT zu setzen, die als Hinweis auf eine Überlastung interpretiert werden soll. Der Standardwert ist INFINITY . Für diese Funktion wird ein Wert von 0.1 Sekunden zusätzlicher Verzögerung vorgeschlagen.
Die Basis -RTT ist die minimale RTT, die in den letzten drei Minuten in den letzten drei Minuten beobachtet wird. Das Basis -RTT -Beobachtungsfenster wird unter folgenden Umständen gelöscht und zurückgesetzt:
Von Zeit zu Zeit, wenn ein erheblicher Teil des Überlastungsfensters verwendet wird, wird das Überlastungsfenster vorübergehend reduziert, um den Pfad für einen neuen Basislinien-RTT zu untersuchen (falls unser eigenes Senden die Basislinie maskiert). Beachten Sie, dass dies Jitter verursachen kann.
Wenn beobachtet wird, dass die geglättete RTT über der Basislinie plus der konfigurierten CongestionDelay (und ebenfalls mindestens 30 ms) liegt, wird angenommen, dass dies ein Hinweis auf Staus ist. Der Constion -Controller reagiert darauf, als wäre es Verlust.
Dieses Stauungserkennungsschema ist wie alle End-to-End-Verzögerungsbasis unvollkommen und unterliegt falsch positive Signale, die durch Fälle verursacht werden, darunter:
Aus diesem Grund ist diese Funktion für alle Anwendungsfälle möglicherweise nicht angezeigt. Es sollte darauf geachtet werden, dass diese Funktion nur dann, wenn falsch positive Überlastungssignale unwahrscheinlich sind, beispielsweise für eine wesentlich unidirektionale Medienübertragung durch einen speziellen Engpass. Fehlalarme können zu einem Übertragungshunger führen.
Diese Funktion ist von LEDBAT (Niedrig-Verzögerungs-Hintergrundtransport), der selbstklockten Ratenanpassung für Multimedia (Scream) und des BBR-Überlastungskontrollalgorithmus von Google inspiriert.
Diese Implementierung von RTMFP erhöht Unterstützung für die explizite Überlastungsbenachrichtigung (ECN). Es fügt einen neuen experimentellen Chunk „ECN -Bericht“ (Typ 0xec ) hinzu, damit der Empfänger die Anzahl der empfangenen ECN -Codepoints an den ECN -Absender zurücksendet. Ein RTMFP darf keinen ECN-Bericht an seinen Peer senden, es sei denn, er hat in seiner S_OPEN Sitzung mindestens ein gültiges Paket mit dem Peer erhalten, der mit einem ECN-fähigen Transportcodepunkt ( ECT(0) , ECT(1) oder ECN-CE markiert ist.
Ein RTMFP-Empfänger, der ECN-fähig ist, sendet ECN-Berichte an seinen ECN-fähigen Peer. ECN -Berichte sollten vor dem ersten Bestätigungsanteil in jedem Paket zusammengestellt werden, das eine Bestätigung enthält (um die Kürzung des Berichts zu vermeiden). Damit der ECN-Absender erkennen kann, ob die Nah- und Ferne Schnittstellen, Pfad und Empfängerunterstützung ECN, sollte ein ECN-fähiger Empfänger einen ECN-Bericht in einem Paket senden, das eine Bestätigung enthält. Wenn ein mit einem ECN-fähiger Transportcodepunkt gekennzeichneter Paket entweder vorgenommen wurde, seit ein ECN-Bericht noch nicht gesendet wurde oder wenn ein Bericht gesendet wurde.
Ein RTMFP-Absender muss die Markierung von Paketen mit eCN-fähigen Transportcodepunkten einstellen, wenn er feststellt, dass der Empfänger nicht mit ECN-fähig ist (z. B. wenn der Absender nicht mindestens einen ECN-Bericht zusammen mit einer Bestätigung für Benutzerdaten erhalten hat, die während der offenen Sitzung mit dem Peer in einem markierten Paket gesendet wurde).
Ein ECN-fähiger RTMFP-Empfänger hält mindestens eine Anzahl der mit ECN-CE markierten Pakete. Der Endpunkt sendet die niedrigen 8 Bit des aktuellen Zählers an seinen Peer in ECN -Berichtsbrocken.
Diese Implementierung sendet ECT(0) . Der Constion-Controller reagiert auf Erhöhungen des ECN-CE-count , als wäre es Verlust. ECT(0) wird nur auf Paketen gesendet, die Benutzerdaten enthalten.
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0xec | 1 | ECN-CE-count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
struct ecnReportChunkPayload_t
{
uint8_t congestionExperiencedCountMod256; // ECN-CE-count
} :8;
congestionExperiencedCountMod256 : Die niedrigen 8 Bit der Anzahl der Pakete, die vom Peer mit ECN-CE gekennzeichnet sind (ECN-Überlastung erlebt).