Это реализация C ++ (11) безопасного протокола потока среды в реальном времени (RTMFP), как описано в RFC 7016.
Библиотека включает в себя образцы адаптеров платформы и другие утилиты, такие как простая петля на основе select() , но они не обязаны использовать. Реализация протокола предназначена для адаптации к любой среде программы хоста.
Библиотека предназначена для клиентов, серверов и приложений P2P. Он включает в себя необходимых помощников и крючков обратного вызова для поддержки введения P2P и балансировки нагрузки.
test каталог включает в себя модульные тесты и примеры. Следует отметить, что tcserver , простой медиа -сервер RTMFP и RTMP; tcrelay , RTMFP ↔︎ RTMP Relay/Proxy; и redirector , простой балансировщик нагрузки.
Наиболее полная документация API в настоящее время находится в файле заголовка rtmfp.hpp .
Приложение создаст экземпляр IPlatformAdapter и ICryptoAdapter , затем com::zenomt::rtmfp::RTMFP (который требует этих адаптеров). Как правило, адаптер платформы должен рассказывать о новом экземпляре RTMFP , чтобы он мог вызвать методы платформы экземпляра (например, howLongToSleep() и onReceivePacket() ).
Платформа добавит хотя бы один интерфейс , вызывая RTMFP::addInterface() .
Приложение может открыть отправку потоков в новые или текущие конечные точки с помощью RTMFP::openFlow() и Flow::openFlow и может открыть связанные обратные потоки с помощью RecvFlow::openReturnFlow() .
Приложение может принять новые потоки, установив обратные вызовы onRecvFlow на RTMFP (для входящих потоков) или на SendFlow S (для связанных обратных потоков).
Приложение может отправлять сообщения для отдаленных коллег с помощью SendFlow::write() и получать сообщения от далеких коллег, установив обратный вызов onMessage на RecvFlow s. Сообщения могут истекать и быть отброшенными, если не запускаются или не доставляются сроком по срокам, или произвольной логикой приложений с использованием WriteReceipt s, возвращаемого SendFlow::write() . Приложение может быть уведомлена обратным вызовом, когда сообщение будет доставлено или заброшено.
SendFlow S, установленная на приоритет/приоритет PRI_PRIORITY , PRI_IMMEDIATE , PRI_FLASH или PRI_FLASHOVERRIDE считается критическим. Отправка критически важных сообщений влияет на контроль заторов.
Когда это будет сделано, приложение может отключить RTMFP упорядоченным образом или внезапно.
Реализация протокола является однопоточной и не имеет замков/мутекс. Все вызовы к его API должны быть синхронизированы извне, например, в том же положении или конструкции, похожей на пробег. Это было сделано для улучшения переносимости и производительности, поскольку блокировка может быть очень дорогой для современных процессоров. Синхронизация абстрагирует метод perform адаптера платформы, позволяющий разгрузить некоторые дорогие или трудоемкие операции на другие ядра/потоки, при желании.
Реализация протокола напрямую не взаимодействует с розетками UDP операционной системы, часами, запусками петлей, блокировками или потоками. Эти взаимодействия абстрагируются с адаптером платформы, предоставленным программой хоста.
Адаптер платформы будет конкретной реализацией com::zenomt::rtmfp::IPlatformAdapter , которая называет методы публичного экземпляра RTMFP в разделе «Используется адаптером платформы». Адаптер обеспечивает текущее время, чтение и письмо для розетков, времени и синхронизации.
В библиотеке представлены два примера адаптеры платформы, которые работают в RunLoop S: PosixPlatformAdapter для чистых однопоточных приложений, и PerformerPosixPlatformAdapter , позволяющий разгрузить криптографию с интенсивным процессором в рабочую ветку. Эти адаптеры платформы должны быть подходящими для многих приложений в UNIX-подобных операционных системах и должны служить примерами того, как написать однопоточные и многопоточные адаптеры платформы для вашего хост-приложения.
Не требуется, чтобы интерфейсы адаптера платформы были гнездами UDP. Например, интерфейс может быть носков или симулятора повернуть, туннель или сетевой симулятор.
Для UNIX-подобных операционных систем эта библиотека предоставляет простой цикл Run select() подходящий для многих приложений на основе сокетов. Он также включает в себя простую петлю пробежки на основе epoll для Linux, которая масштабируется лучше, чем select() для обработки многих розеток. Используйте псевдоним PreferredRunLoop , чтобы автоматически выбрать лучший вариант, доступный в время компиляции для целевой ОС.
Performer может быть прикреплен к циклу пробега, чтобы включить задачу внутри/синхронизирован с циклом прогона из любого потока. Performer используются с помощью PerformerPosixPlatformAdapter .
Microsoft Windows не является официально поддерживаемой платформой. Тем не менее, основная библиотека (за исключением адаптеров платформы, запуск петлей и Performer ) должна создавать Windows, а обслуживание ядра для этой платформы будет предпринято как время и помощь сообщества. Пожалуйста, откройте проблему, если есть проблема с основной библиотекой в Windows.
Чтобы использовать эту библиотеку в Windows, вам нужно будет предоставить соответствующий адаптер платформы.
Пожалуйста, свяжитесь с сопровождающим или откройте проблему, чтобы запросить ссылку на ваш адаптер платформы Windows, который будет добавлен здесь, в этом документе.
RFC 7016 описывает обобщенную структуру для обеспечения связи RTMFP в соответствии с потребностями приложения и оставляет криптографическую специфику в профиль криптографии . Эта библиотека не блокирует свое приложение к какому -либо конкретному профилю криптографии и написана для поддержки многих потенциальных профилей. Профиль криптографии реализован конкретным ICryptoAdapter , предоставленным RTMFP при экземпляре.
Большинство приложений RTMFP будут использовать профиль криптографии для вспышки, описанную в RFC 7425. Это обеспечивается FlashCryptoAdapter . Обратите внимание, что этот адаптер является абстрактным и должен быть подкласлен, чтобы обеспечить конкретные реализации необходимых криптографических примитивов. Конкретная реализация с использованием OpenSSL предоставляется FlashCryptoAdapter_OpenSSL , которая также может служить примером для использования других криптографических библиотек. Если у вас нет OpenSSL или вы не хотите его использовать, вы можете подавить построение этого модуля, определив переменную make WITHOUT_OPENSSL . Если ваш OpenSSL установлен за пределами по умолчанию вашего компилятора и пути поиска линкера, вы можете определить make переменные, OPENSSL_INCLUDEDIR и OPENSSL_LIBDIR с соответствующими директивами (см. Makefile для примеров).
Реализация OpenSSL FlashCryptoAdapter реализует 4096-битную интернет-обмену (IKE) Группа 16, 2048-битная группа IKE 14 и 1024-битная группа IKE Group 2 для соглашения о ключах Diffie-Hellman. Все реализации профиля криптографии Flash Communice должны реализовать хотя бы группу 2; Некоторые также реализуют группу 14. Эта реализация предпочитает самую сильную общую группу.
Обратите внимание, что RTMFP не ограничивается коммуникацией флэш -платформы. Эта библиотека предоставляет PlainCryptoAdapter , подходящий для тестирования и оценки. Поскольку он не обеспечивает фактической криптографии (и его методы cryptoHash256() и pseudoRandomBytes() особенно слабы), он не подходит для производственного использования в открытом Интернете. Не.
Bufferbloat (чрезмерная буферизация и очередь в сети) может вызвать высокие задержки, приводящие к неприемлемым производительности для приложений в реальном времени. К сожалению, наилучшим решением этой проблемы (активное управление очередью с явным уведомлением о перегрузке) не является повсеместно развернутым в Интернете в настоящее время.
В дополнение к нормальным сигналам перегрузки (уведомление о потерь и явное уведомление о перегрузке), эта библиотека может при желании сделать вывод вероятный заторы на сеансе с увеличением времени в рамках пути (RTT). Чтобы включить эту возможность, используйте Flow::setSessionCongestionDelay() чтобы установить количество дополнительной задержки выше базового RTT, который будет интерпретироваться как показание заторов. Значение по умолчанию - INFINITY . Для этой функции предлагается значение 0.1 секунды дополнительной задержки.
Базовый RTT - это минимальный RTT, наблюдаемый не более последних трех минут. Базовое окно наблюдения RTT очищается и сбросится в следующих обстоятельствах:
Время от времени, если используется значительная часть окна перегрузки, окно заторов будет временно уменьшено, чтобы исследовать путь для нового базового RTT (в случае, если наша собственная отправка маскирует базовую линию). Обратите внимание, что это может вызвать джиттер.
Если наблюдается сглаженная RTT, превышает базовую линию плюс настроенный CongestionDelay (и также составляет не менее 30 мс), предполагается, что это является показателем заторов. Контроллер заторов реагирует на это, как будто это была потеря.
Эта схема обнаружения перегрузки, как и все, основанные на задержке, является несовершенной и подлежит ложным положительным сигналам, вызванным случаями, включая:
Таким образом, эта функция не может быть указана для всех вариантов использования. Следует проявлять осторожность, чтобы обеспечить эту функцию только тогда, когда сигналы ложных положительных заторов маловероятны, например, для существенно однонаправленной передачи средств массовой информации посредством выделенного узкого места. Ложные позитивы могут вызвать голодание передачи.
Эта функция вдохновлена низкой дополнительной задержкой фонового транспорта (LEDBAT), самостоятельной адаптацией скорости для мультимедиа (Scream) и алгоритмом управления перегрузками BBR Google.
Эта реализация RTMFP добавляет поддержку явного уведомления о перегрузке (ECN). Он добавляет новый экспериментальный кусок «отчет ECN» (тип 0xec ), чтобы приемник отправил количество полученных Codepoints обратно к отправителю ECN. RTMFP не должен отправлять отчет ECN своему одноранговому одному, если он не получил хотя бы одного действительного пакета в своем сеансе S_OPEN с тем узлом, который отмечен с помощью точки транспортного кода ECN ( ECT(0) , ECT(1) или ECN-CE ).
Приемник RTMFP, способный к ECN, отправляет отчеты ECN на свой экран ECN. Отчеты ECN должны быть собраны перед первым кусочком подтверждения в любом пакете, содержащем подтверждение (чтобы избежать усечения отчета). Чтобы отправитель ECN мог обнаружить, следует ли получить ближние и дальние интерфейсы, Path и Preciver Support ECN, приемник, способный к ECN , отправлять отчет ECN в любом пакете, который содержит подтверждение, если какой-либо пакет, отмеченный с помощью ECN, способной код транспорта, либо был получен либо с тех пор, как был отправлен отчет ECN, или если отчет еще не был отправлен.
Отправитель RTMFP должен прекратить маркировку пакетов с помощью ECN-точек транспортного кода, если он определяет, что приемник не способен ECN (например, если отправитель не получил хотя бы одного отчета ECN вместе с подтверждением для пользовательских данных, которые были отправлены в помеченном пакете во время открытого сеанса с PEER).
Приемник RTMFP с поддержкой ECN сохраняет как минимум количество полученных пакетов, отмеченных ECN-CE . Конечная точка посылает низкие 8 бит текущего счетчика своему сверстнику в кусках отчета ECN.
Эта реализация отправляет ECT(0) . Контроллер заторов реагирует на увеличение количества ECN-CE-count как будто это была потеря. ECT(0) отправляется только на пакеты, содержащие пользовательские данные.
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 : низкие 8 бит подсчета пакетов, полученных от сверстника, отмеченного ECN-CE (опыт перегрузки ECN).