Il s'agit d'une implémentation C ++ (11) du protocole de flux multimédia en temps réel sécurisé (RTMFP) comme décrit dans RFC 7016.
La bibliothèque comprend des échantillons d'adaptateurs de plate-forme et d'autres utilitaires, tels qu'une boucle d'exécution basée sur select() , mais celles-ci ne doivent pas être utilisées. La mise en œuvre du protocole est destinée à être adaptable à tout environnement de programme hôte.
La bibliothèque est destinée aux clients, aux serveurs et aux applications P2P. Il comprend les aides et les crochets de rappel nécessaires pour prendre en charge l'introduction P2P et l'équilibrage de charge.
Le répertoire test comprend des tests unitaires et des exemples. tcserver , un simple RTMFP et un serveur de médias en direct RTMP simple; tcrelay , un relais / proxy RTMFP ↔︎ RTMP; et redirector , un simple équilibreur de charge.
La documentation API la plus complète se trouve actuellement dans le fichier d'en-tête rtmfp.hpp .
Une application instanciera un IPlatformAdapter et un ICryptoAdapter , puis un com::zenomt::rtmfp::RTMFP (qui nécessite ces adaptateurs). En règle générale, l'adaptateur de plate-forme devra être informé de la nouvelle instance RTMFP afin qu'il puisse invoquer les méthodes de plate-forme de l'instance (telles que howLongToSleep() et onReceivePacket() ).
La plate-forme ajoutera au moins une interface en appelant RTMFP::addInterface() .
L'application peut ouvrir l'envoi de flux vers des points de terminaison nouveaux ou actuels avec RTMFP::openFlow() et Flow::openFlow , et peut ouvrir les flux de retour associés avec RecvFlow::openReturnFlow() .
L'application peut accepter de nouveaux flux en définissant les rappels onRecvFlow sur le RTMFP (pour les flux entrants nus) ou sur SendFlow S (pour les flux de retour associés).
L'application peut envoyer des messages à des pairs lointains avec SendFlow::write() et recevoir des messages de pairs lointains en définissant le rappel onMessage sur RecvFlow s. Les messages peuvent expirer et être abandonnés s'ils ne sont pas démarrés ou livrés par des délais par message, ou par une logique d'application arbitraire à l'aide de l' WriteReceipt renvoyé par SendFlow::write() . La demande peut être informée par rappel lorsqu'un message est livré ou abandonné.
SendFlow S Set to Priority / Pridiance PRI_PRIORITY , PRI_IMMEDIATE , PRI_FLASH ou PRI_FLASHOVERRIDE SONT MISE À L'EXPÉRIEMENT. L'envoi de messages critiques au temps affecte le contrôle de la congestion.
Lorsque cela est fait, l'application peut arrêter le RTMFP de manière ordonnée ou brusquement.
La mise en œuvre du protocole est unique et n'a pas de verrous / mutex. Tous les appels à ses API doivent être synchronisés en externe, par exemple en étant dans le même thread ou la même construction en boucle de run. Cela a été fait pour améliorer la portabilité et les performances, car le verrouillage peut être très cher sur les processeurs modernes. La synchronisation est abstraite par la méthode perform de l'adaptateur de plate-forme pour permettre de décharger certaines opérations coûteuses ou longues vers d'autres cœurs / threads, si vous le souhaitez.
L'implémentation du protocole n'interagit pas directement avec les prises UDP du système d'exploitation, l'horloge, les boucles d'exécution, les verrous ou les threads. Ces interactions sont résumées à un adaptateur de plate-forme fourni par le programme hôte.
L' adaptateur de plate-forme sera une implémentation concrète de com::zenomt::rtmfp::IPlatformAdapter , qui appelle les méthodes d'instance publique RTMFP dans sa section «utilisée par l'adaptateur de plate-forme». L'adaptateur fournit l'heure actuelle, la lecture et l'écriture sur les prises, le calendrier et la synchronisation.
La bibliothèque fournit deux exemples d'adaptateurs de plate-forme qui s'exécutent dans RunLoop S: PosixPlatformAdapter pour les applications purs à thread unique et PerformerPosixPlatformAdapter pour permettre à la cryptographie à clé publique à forte intensité de CPU à un fil de travail. Ces adaptateurs de plate-forme devraient convenir à de nombreuses applications sur les systèmes d'exploitation de type UNIX et devraient servir d'exemples de la façon d'écrire des adaptateurs de plate-forme unique et multithreads pour votre application hôte.
Il n'y a aucune exigence pour que les interfaces de l'adaptateur de plate-forme soient des prises UDP. Par exemple, une interface peut être une chaussette ou un transformateur de proxy, un tunnel ou un simulateur de réseau.
Pour les systèmes d'exploitation de type UNIX, cette bibliothèque fournit une boucle d'exécution simple select() adaptée à de nombreuses applications basées sur des socket. Il comprend également une boucle d'exécution basée sur epoll simple pour Linux qui évolue mieux que select() pour gérer de nombreuses prises. Utilisez les alias PreferredRunLoop pour choisir automatiquement la meilleure variante disponible au moment de la compilation pour le système d'exploitation cible.
Un Performer peut être attaché à une boucle d'exécution pour permettre à invoquer une tâche à l'intérieur / synchronisée avec la boucle d'exécution à partir de n'importe quel fil. Les Performer sont utilisés avec PerformerPosixPlatformAdapter .
Microsoft Windows n'est pas une plate-forme officiellement prise en charge. Cependant, la bibliothèque de base (à l'exclusion des adaptateurs de plate-forme, des boucles d'exécution et Performer ) devrait s'appuyer sur Windows, et la maintenance du noyau de cette plate-forme sera tentée comme le temps et l'aide de la communauté le permettent. Veuillez ouvrir un problème s'il y a un problème avec la bibliothèque de base sur Windows.
Pour utiliser cette bibliothèque sur Windows, vous devrez fournir un adaptateur de plate-forme approprié.
Veuillez contacter le mainteneur ou ouvrir un problème pour demander un lien vers votre adaptateur de plate-forme Windows à ajouter ici dans ce document.
RFC 7016 décrit un cadre généralisé pour sécuriser la communication RTMFP en fonction des besoins de l'application et laisse des détails cryptographiques à un profil de cryptographie . Cette bibliothèque ne verrouille pas son application sur un profil de cryptographie particulier et est écrite pour prendre en charge de nombreux profils potentiels. Le profil de cryptographie est implémenté par un ICryptoAdapter en béton fourni au RTMFP sur l'instanciation.
La plupart des applications de RTMFP utiliseront le profil de cryptographie pour la communication flash décrite dans RFC 7425. Ceci est fourni par le FlashCryptoAdapter . Notez que cet adaptateur est abstrait et doit être sous-classé pour fournir des implémentations concrètes des primitives cryptographiques requises. Une implémentation concrète utilisant OpenSSL est fournie par FlashCryptoAdapter_OpenSSL , qui peut également servir d'exemple sur la façon d'utiliser d'autres bibliothèques de cryptographie. Si vous n'avez pas OpenSSL ou si vous ne voulez pas l'utiliser, vous pouvez supprimer la construction de ce module en définissant make WITHOUT_OPENSSL . Si votre OpenSSL est installé en dehors des chemins de recherche par défaut de votre compilateur et de recherche de liens, vous pouvez définir make variables OPENSSL_INCLUDEDIR et OPENSSL_LIBDIR avec des directives appropriées (voir le Makefile pour des exemples).
La mise en œuvre OpenSSL de FlashCryptoAdapter implémente le groupe 16, 2096 bits de clé Internet Exchange (IKE), 2048 bits du groupe 14 et le groupe IKE 2 1024 bits pour l'accord de clé Diffie-Hellman. Toutes les implémentations du profil de cryptographie Flash Communication doivent implémenter au moins le groupe 2; Certains mettent également en œuvre le groupe 14. Cette implémentation préfère le groupe commun le plus fort.
Notez que RTMFP n'est pas limité à la communication de la plate-forme flash. Cette bibliothèque fournit une PlainCryptoAdapter adaptée aux tests et à l'évaluation. Comme il ne fournit pas de cryptographie réelle (et ses méthodes cryptoHash256() et pseudoRandomBytes() sont particulièrement faibles), il ne convient pas à une utilisation en production dans Internet ouvert. Ne le faites pas.
Bufferbloat (tampon excessif et mise en file d'attente dans le réseau) peut entraîner des retards de bout en bout, ce qui entraîne des performances inacceptables pour les applications en temps réel. Malheureusement, la meilleure solution à ce problème (gestion active des files d'attente avec notification de congestion explicite) n'est pas universellement déployée sur Internet pour le moment.
En plus des signaux de congestion normaux (perte et notification de congestion explicite), cette bibliothèque peut éventuellement déduire la congestion probable sur une session à partir d'augmentation du temps aller-retour (RTT). Pour permettre à cette capacité, utilisez Flow::setSessionCongestionDelay() pour définir une quantité de retard supplémentaire au-dessus du RTT de base à interpréter comme une indication de la congestion. La valeur par défaut est INFINITY . Une valeur de 0.1 seconde de retard supplémentaire est suggérée pour cette fonctionnalité.
Le RTT de base est le RTT minimum observé au plus au plus des trois dernières minutes. La fenêtre d'observation RTT de base est effacée et réinitialisée dans les circonstances suivantes:
De temps en temps, si une partie importante de la fenêtre de congestion est utilisée, la fenêtre de congestion sera temporairement réduite afin de sonder le chemin pour un nouveau RTT de base (au cas où notre propre envoi est le masque de la ligne de base). Notez que cela peut provoquer une gigue.
Si le RTT lissé est observé au-dessus de la ligne de base plus la CongestionDelay configurée (et est également d'au moins 30 ms), cela est supposé être une indication de la congestion. Le contrôleur de congestion répond à cela comme s'il s'agissait de perte.
Ce schéma de détection de congestion, comme tous les retards de bout en bout, est imparfait et est soumis à des signaux faux positifs causés par des cas, notamment:
En tant que telle, cette fonctionnalité peut ne pas être indiquée pour tous les cas d'utilisation. Il faut veiller à l'activation de cette fonctionnalité que lorsque les signaux de congestion des faux positifs sont peu probables, par exemple pour la transmission des médias sensiblement unidirectionnels via un goulot d'étranglement dédié. Les faux positifs peuvent provoquer une famine de transmission.
Cette fonctionnalité est inspirée par le transport de fond en retard supplémentaire (LEDBAT), l'adaptation des taux autoproclamés pour le multimédia (Scream) et l'algorithme de contrôle de la congestion BBR de Google.
Cette implémentation de RTMFP ajoute la prise en charge de la notification de congestion explicite (ECN). Il ajoute un nouveau morceau expérimental «Rapport ECN» (type 0xec ) pour que le récepteur renvoie les comptes de codepoints ECN reçus à l'expéditeur ECN. Un RTMFP ne doit pas envoyer de rapport ECN à son pair à moins qu'il n'ait reçu au moins un paquet valide dans sa session S_OPEN avec ce pair qui est marqué d'un point de code de transport capable ECN ( ECT(0) , ECT(1) ou ECN-CE ).
Un récepteur RTMFP qui est compatible ECN envoie des rapports ECN à son pair compatible ECN. Les rapports ECN doivent être assemblés avant le premier morceau de reconnaissance dans tout paquet contenant une reconnaissance (pour éviter la troncature du rapport). Afin que l'expéditeur ECN puisse détecter si les interfaces proches et lointaines, le chemin et le récepteur prennent en charge ECN, un récepteur compatible ECN devrait envoyer un rapport ECN dans n'importe quel paquet qui contient un accusé de réception, si un paquet marqué d'un point de code de transport ECN a été reçu non plus depuis la dernière fois qu'un rapport ECN a été envoyé ou si un rapport n'a pas encore été envoyé.
Un expéditeur RTMFP doit cesser de marquer des paquets avec les points de code de transport ECN capables s'il détermine que le récepteur n'est pas compatible ECN (par exemple, si l'expéditeur n'a pas reçu au moins un rapport ECN avec un accusé de réception pour les données utilisateur qui ont été envoyées dans un paquet marqué pendant la session ouverte avec le pair).
Un récepteur RTMFP compatible ECN conserve au moins un décompte du nombre de paquets reçus marqués d' ECN-CE . Le point de terminaison envoie les 8 bits bas du compteur actuel de son pair dans les morceaux de rapport ECN.
Cette implémentation envoie ECT(0) . Le contrôleur de congestion réagit à l'augmentation du ECN-CE-count comme s'il s'agissait de perte. ECT(0) n'est envoyé que sur des paquets contenant des données utilisateur.
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 : Les 8 bits bas du nombre de paquets reçus du pair marqué par ECN-CE (congestion ECN expérimentée).