From 3d7fa88937a3382f06b624e796b5a6be5977e4a4 Mon Sep 17 00:00:00 2001 From: Eunhye Choi Date: Wed, 3 Aug 2022 14:57:35 +0900 Subject: [PATCH] srt 1.5.0 - srt v1.5.0 code upload Change-Id: I26f9c714d701d39b42ad403faca72aac3df5fe14 --- .clang-format | 90 + .gitignore | 45 + CMakeLists.txt | 1351 +++ CONTRIBUTING.md | 58 + LICENSE | 373 + README.md | 228 + cmake_object_lib_support.c | 9 + codecov.yml | 8 + configure | 268 + configure-data.tcl | 409 + docs/API/API-functions.md | 3362 ++++++ docs/API/API-socket-options.md | 1577 +++ docs/API/API.md | 711 ++ docs/API/configuration-guidelines.md | 109 + docs/API/statistics.md | 825 ++ docs/README.md | 75 + docs/apps/srt-file-transmit.md | 55 + docs/apps/srt-live-transmit.md | 478 + docs/apps/srt-test-multiplex.md | 99 + docs/apps/srt-test-relay.md | 34 + docs/apps/srt-tunnel.md | 37 + docs/build/build-android.md | 18 + docs/build/build-iOS.md | 44 + docs/build/build-linux.md | 44 + docs/build/build-macOS.md | 32 + docs/build/build-options.md | 656 ++ docs/build/build-win.md | 307 + docs/dev/developers-guide.md | 282 + docs/dev/low-level-info.md | 238 + docs/dev/making-srt-better.md | 137 + docs/features/access-control.md | 435 + docs/features/bonding-intro.md | 258 + docs/features/bonding-main-backup.md | 248 + docs/features/bonding-quick-start.md | 139 + docs/features/encryption.md | 157 + docs/features/handshake.md | 1564 +++ docs/features/images/block-aligned-5rx10c.png | Bin 0 -> 69799 bytes docs/features/images/block-aligned.png | Bin 0 -> 8232 bytes .../non-block-aligned-5rx10c-deleted-packets.png | Bin 0 -> 78010 bytes docs/features/images/non-block-aligned-5rx10c.png | Bin 0 -> 78751 bytes docs/features/images/non-block-aligned.png | Bin 0 -> 12029 bytes docs/features/images/packet-filter-mechanism.png | Bin 0 -> 25406 bytes docs/features/images/rebuild-missing-sequence.png | Bin 0 -> 25998 bytes docs/features/images/srt-encryption-1.png | Bin 0 -> 87854 bytes docs/features/images/srt-encryption-2.png | Bin 0 -> 19324 bytes docs/features/images/staircase-pattern-5rx10c.png | Bin 0 -> 78885 bytes docs/features/live-streaming.md | 141 + docs/features/packet-filtering-and-fec.md | 934 ++ docs/features/socket-groups.md | 714 ++ docs/misc/images/srt-history-good-signal.png | Bin 0 -> 155143 bytes docs/misc/images/srt-transmission-bad-signal.png | Bin 0 -> 116613 bytes docs/misc/why-srt-was-created.md | 31 + haicrypt/cryspr-config.h | 26 + haicrypt/cryspr-gnutls.c | 178 + haicrypt/cryspr-gnutls.h | 61 + haicrypt/cryspr-mbedtls.c | 235 + haicrypt/cryspr-mbedtls.h | 63 + haicrypt/cryspr-openssl.c | 218 + haicrypt/cryspr-openssl.h | 65 + haicrypt/cryspr.c | 707 ++ haicrypt/cryspr.h | 203 + haicrypt/filelist-gnutls.maf | 26 + haicrypt/filelist-mbedtls.maf | 24 + haicrypt/filelist-openssl.maf | 24 + haicrypt/haicrypt.h | 122 + haicrypt/haicrypt_log.cpp | 117 + haicrypt/haicrypt_log.h | 34 + haicrypt/hcrypt.c | 338 + haicrypt/hcrypt.h | 169 + haicrypt/hcrypt_ctx.h | 97 + haicrypt/hcrypt_ctx_rx.c | 199 + haicrypt/hcrypt_ctx_tx.c | 422 + haicrypt/hcrypt_msg.h | 155 + haicrypt/hcrypt_rx.c | 146 + haicrypt/hcrypt_sa.c | 96 + haicrypt/hcrypt_tx.c | 176 + haicrypt/hcrypt_ut.c | 224 + haicrypt/hcrypt_xpt_srt.c | 171 + packaging/baselibs.conf | 5 + packaging/srt.manifest | 5 + packaging/srt.spec | 68 + scripts/CheckCXXAtomic.cmake | 62 + scripts/CheckGCCAtomicIntrinsics.cmake | 113 + scripts/FindMbedTLS.cmake | 115 + scripts/FindPThreadGetSetName.cmake | 73 + scripts/ShowProjectConfig.cmake | 191 + scripts/changelog/README.md | 18 + scripts/changelog/changelog.py | 100 + scripts/changelog/requirements.txt | 3 + scripts/check-deps | 56 + scripts/collect-gcov.sh | 7 + scripts/gather-package.bat | 37 + scripts/generate-configure-options.tcl | 115 + scripts/generate-error-types.tcl | 251 + scripts/generate-logging-defs.tcl | 454 + scripts/haiUtil.cmake | 290 + scripts/maf.vim | 38 + scripts/mafread.tcl | 58 + scripts/set-version-metadata.ps1 | 56 + scripts/srt-dev.lua | 938 ++ scripts/srt.pc.in | 12 + srtcore/README.md | 75 + srtcore/access_control.h | 79 + srtcore/api.cpp | 4527 +++++++ srtcore/api.h | 486 + srtcore/atomic.h | 311 + srtcore/atomic_clock.h | 91 + srtcore/atomic_msvc.h | 245 + srtcore/buffer.cpp | 2298 ++++ srtcore/buffer.h | 607 + srtcore/buffer_rcv.cpp | 1071 ++ srtcore/buffer_rcv.h | 367 + srtcore/cache.cpp | 118 + srtcore/cache.h | 273 + srtcore/channel.cpp | 912 ++ srtcore/channel.h | 167 + srtcore/common.cpp | 667 ++ srtcore/common.h | 1421 +++ srtcore/congctl.cpp | 660 ++ srtcore/congctl.h | 226 + srtcore/core.cpp | 11751 +++++++++++++++++++ srtcore/core.h | 1163 ++ srtcore/crypto.cpp | 858 ++ srtcore/crypto.h | 274 + srtcore/epoll.cpp | 1012 ++ srtcore/epoll.h | 506 + srtcore/fec.cpp | 2562 ++++ srtcore/fec.h | 277 + srtcore/filelist.maf | 84 + srtcore/group.cpp | 4741 ++++++++ srtcore/group.h | 822 ++ srtcore/group_backup.cpp | 159 + srtcore/group_backup.h | 128 + srtcore/group_common.cpp | 63 + srtcore/group_common.h | 62 + srtcore/handshake.cpp | 325 + srtcore/handshake.h | 366 + srtcore/list.cpp | 870 ++ srtcore/list.h | 271 + srtcore/logger_default.cpp | 53 + srtcore/logger_defs.cpp | 55 + srtcore/logger_defs.h | 61 + srtcore/logging.h | 488 + srtcore/logging_api.h | 107 + srtcore/md5.cpp | 389 + srtcore/md5.h | 90 + srtcore/netinet_any.h | 426 + srtcore/packet.cpp | 585 + srtcore/packet.h | 435 + srtcore/packetfilter.cpp | 354 + srtcore/packetfilter.h | 219 + srtcore/packetfilter_api.h | 158 + srtcore/packetfilter_builtin.h | 18 + srtcore/platform_sys.h | 123 + srtcore/queue.cpp | 1812 +++ srtcore/queue.h | 613 + srtcore/socketconfig.cpp | 1020 ++ srtcore/socketconfig.h | 377 + srtcore/srt.h | 1001 ++ srtcore/srt_attr_defs.h | 191 + srtcore/srt_c_api.cpp | 478 + srtcore/srt_compat.c | 142 + srtcore/srt_compat.h | 109 + srtcore/srt_shared.rc | 45 + srtcore/stats.h | 221 + srtcore/strerror_defs.cpp | 154 + srtcore/sync.cpp | 355 + srtcore/sync.h | 882 ++ srtcore/sync_cxx11.cpp | 108 + srtcore/sync_posix.cpp | 572 + srtcore/threadname.h | 224 + srtcore/tsbpd_time.cpp | 269 + srtcore/tsbpd_time.h | 162 + srtcore/udt.h | 274 + srtcore/utilities.h | 1098 ++ srtcore/version.h.in | 34 + srtcore/window.cpp | 256 + srtcore/window.h | 355 + 178 files changed, 79149 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 cmake_object_lib_support.c create mode 100644 codecov.yml create mode 100644 configure create mode 100644 configure-data.tcl create mode 100644 docs/API/API-functions.md create mode 100644 docs/API/API-socket-options.md create mode 100644 docs/API/API.md create mode 100644 docs/API/configuration-guidelines.md create mode 100644 docs/API/statistics.md create mode 100644 docs/README.md create mode 100644 docs/apps/srt-file-transmit.md create mode 100644 docs/apps/srt-live-transmit.md create mode 100644 docs/apps/srt-test-multiplex.md create mode 100644 docs/apps/srt-test-relay.md create mode 100644 docs/apps/srt-tunnel.md create mode 100644 docs/build/build-android.md create mode 100644 docs/build/build-iOS.md create mode 100644 docs/build/build-linux.md create mode 100644 docs/build/build-macOS.md create mode 100644 docs/build/build-options.md create mode 100644 docs/build/build-win.md create mode 100644 docs/dev/developers-guide.md create mode 100644 docs/dev/low-level-info.md create mode 100644 docs/dev/making-srt-better.md create mode 100644 docs/features/access-control.md create mode 100644 docs/features/bonding-intro.md create mode 100644 docs/features/bonding-main-backup.md create mode 100644 docs/features/bonding-quick-start.md create mode 100644 docs/features/encryption.md create mode 100644 docs/features/handshake.md create mode 100644 docs/features/images/block-aligned-5rx10c.png create mode 100644 docs/features/images/block-aligned.png create mode 100644 docs/features/images/non-block-aligned-5rx10c-deleted-packets.png create mode 100644 docs/features/images/non-block-aligned-5rx10c.png create mode 100644 docs/features/images/non-block-aligned.png create mode 100644 docs/features/images/packet-filter-mechanism.png create mode 100644 docs/features/images/rebuild-missing-sequence.png create mode 100644 docs/features/images/srt-encryption-1.png create mode 100644 docs/features/images/srt-encryption-2.png create mode 100644 docs/features/images/staircase-pattern-5rx10c.png create mode 100644 docs/features/live-streaming.md create mode 100644 docs/features/packet-filtering-and-fec.md create mode 100644 docs/features/socket-groups.md create mode 100644 docs/misc/images/srt-history-good-signal.png create mode 100644 docs/misc/images/srt-transmission-bad-signal.png create mode 100644 docs/misc/why-srt-was-created.md create mode 100644 haicrypt/cryspr-config.h create mode 100644 haicrypt/cryspr-gnutls.c create mode 100644 haicrypt/cryspr-gnutls.h create mode 100644 haicrypt/cryspr-mbedtls.c create mode 100644 haicrypt/cryspr-mbedtls.h create mode 100644 haicrypt/cryspr-openssl.c create mode 100644 haicrypt/cryspr-openssl.h create mode 100644 haicrypt/cryspr.c create mode 100644 haicrypt/cryspr.h create mode 100644 haicrypt/filelist-gnutls.maf create mode 100644 haicrypt/filelist-mbedtls.maf create mode 100644 haicrypt/filelist-openssl.maf create mode 100644 haicrypt/haicrypt.h create mode 100644 haicrypt/haicrypt_log.cpp create mode 100644 haicrypt/haicrypt_log.h create mode 100644 haicrypt/hcrypt.c create mode 100644 haicrypt/hcrypt.h create mode 100644 haicrypt/hcrypt_ctx.h create mode 100644 haicrypt/hcrypt_ctx_rx.c create mode 100644 haicrypt/hcrypt_ctx_tx.c create mode 100644 haicrypt/hcrypt_msg.h create mode 100644 haicrypt/hcrypt_rx.c create mode 100644 haicrypt/hcrypt_sa.c create mode 100644 haicrypt/hcrypt_tx.c create mode 100644 haicrypt/hcrypt_ut.c create mode 100644 haicrypt/hcrypt_xpt_srt.c create mode 100644 packaging/baselibs.conf create mode 100644 packaging/srt.manifest create mode 100644 packaging/srt.spec create mode 100644 scripts/CheckCXXAtomic.cmake create mode 100644 scripts/CheckGCCAtomicIntrinsics.cmake create mode 100644 scripts/FindMbedTLS.cmake create mode 100644 scripts/FindPThreadGetSetName.cmake create mode 100644 scripts/ShowProjectConfig.cmake create mode 100644 scripts/changelog/README.md create mode 100644 scripts/changelog/changelog.py create mode 100644 scripts/changelog/requirements.txt create mode 100644 scripts/check-deps create mode 100644 scripts/collect-gcov.sh create mode 100644 scripts/gather-package.bat create mode 100644 scripts/generate-configure-options.tcl create mode 100644 scripts/generate-error-types.tcl create mode 100644 scripts/generate-logging-defs.tcl create mode 100644 scripts/haiUtil.cmake create mode 100644 scripts/maf.vim create mode 100644 scripts/mafread.tcl create mode 100644 scripts/set-version-metadata.ps1 create mode 100644 scripts/srt-dev.lua create mode 100644 scripts/srt.pc.in create mode 100644 srtcore/README.md create mode 100644 srtcore/access_control.h create mode 100644 srtcore/api.cpp create mode 100644 srtcore/api.h create mode 100644 srtcore/atomic.h create mode 100644 srtcore/atomic_clock.h create mode 100644 srtcore/atomic_msvc.h create mode 100644 srtcore/buffer.cpp create mode 100644 srtcore/buffer.h create mode 100644 srtcore/buffer_rcv.cpp create mode 100644 srtcore/buffer_rcv.h create mode 100644 srtcore/cache.cpp create mode 100644 srtcore/cache.h create mode 100644 srtcore/channel.cpp create mode 100644 srtcore/channel.h create mode 100644 srtcore/common.cpp create mode 100644 srtcore/common.h create mode 100644 srtcore/congctl.cpp create mode 100644 srtcore/congctl.h create mode 100644 srtcore/core.cpp create mode 100644 srtcore/core.h create mode 100644 srtcore/crypto.cpp create mode 100644 srtcore/crypto.h create mode 100644 srtcore/epoll.cpp create mode 100644 srtcore/epoll.h create mode 100644 srtcore/fec.cpp create mode 100644 srtcore/fec.h create mode 100644 srtcore/filelist.maf create mode 100644 srtcore/group.cpp create mode 100644 srtcore/group.h create mode 100644 srtcore/group_backup.cpp create mode 100644 srtcore/group_backup.h create mode 100644 srtcore/group_common.cpp create mode 100644 srtcore/group_common.h create mode 100644 srtcore/handshake.cpp create mode 100644 srtcore/handshake.h create mode 100644 srtcore/list.cpp create mode 100644 srtcore/list.h create mode 100644 srtcore/logger_default.cpp create mode 100644 srtcore/logger_defs.cpp create mode 100644 srtcore/logger_defs.h create mode 100644 srtcore/logging.h create mode 100644 srtcore/logging_api.h create mode 100644 srtcore/md5.cpp create mode 100644 srtcore/md5.h create mode 100644 srtcore/netinet_any.h create mode 100644 srtcore/packet.cpp create mode 100644 srtcore/packet.h create mode 100644 srtcore/packetfilter.cpp create mode 100644 srtcore/packetfilter.h create mode 100644 srtcore/packetfilter_api.h create mode 100644 srtcore/packetfilter_builtin.h create mode 100644 srtcore/platform_sys.h create mode 100644 srtcore/queue.cpp create mode 100644 srtcore/queue.h create mode 100644 srtcore/socketconfig.cpp create mode 100644 srtcore/socketconfig.h create mode 100644 srtcore/srt.h create mode 100644 srtcore/srt_attr_defs.h create mode 100644 srtcore/srt_c_api.cpp create mode 100644 srtcore/srt_compat.c create mode 100644 srtcore/srt_compat.h create mode 100644 srtcore/srt_shared.rc create mode 100644 srtcore/stats.h create mode 100644 srtcore/strerror_defs.cpp create mode 100644 srtcore/sync.cpp create mode 100644 srtcore/sync.h create mode 100644 srtcore/sync_cxx11.cpp create mode 100644 srtcore/sync_posix.cpp create mode 100644 srtcore/threadname.h create mode 100644 srtcore/tsbpd_time.cpp create mode 100644 srtcore/tsbpd_time.h create mode 100644 srtcore/udt.h create mode 100644 srtcore/utilities.h create mode 100644 srtcore/version.h.in create mode 100644 srtcore/window.cpp create mode 100644 srtcore/window.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..387de5c --- /dev/null +++ b/.clang-format @@ -0,0 +1,90 @@ +Language: Cpp +BasedOnStyle: LLVM +AccessModifierOffset: -4 +# AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +# AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +# AllowAllArgumentsOnNextLine: true # Requires clang-format v9 and higher +# AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +# AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +# AllowShortIfStatementsOnASingleLine: false +# AllowShortLoopsOnASingleLine: false +# AlwaysBreakAfterDefinitionReturnType: None +# AlwaysBreakAfterReturnType: None +# AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: false +BinPackParameters: false +# BraceWrapping: +# AfterClass: false +# AfterControlStatement: false +# AfterEnum: false +# AfterFunction: false +# AfterNamespace: false +# AfterObjCDeclaration: false +# AfterStruct: false +# AfterUnion: false +# BeforeCatch: false +# BeforeElse: false +# IndentBraces: false +# BreakBeforeBinaryOperators: None +BreakBeforeBraces: Allman +# BreakInheritanceList: BeforeComma +# BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +# BreakAfterJavaFieldAnnotations: false +# BreakStringLiterals: true +ColumnLimit: 120 +# CommentPragmas: '^ IWYU pragma:' +# ConstructorInitializerAllOnOneLineOrOnePerLine: false +# ConstructorInitializerIndentWidth: 4 +# ContinuationIndentWidth: 4 +# Cpp11BracedListStyle: true +# DerivePointerAlignment: false +# DisableFormat: false +# ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +# ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +# IncludeIsMainRegex: '$' +# IndentCaseLabels: false +IndentWidth: 4 +# IndentWrappedFunctionNames: false +# JavaScriptQuotes: Leave +# JavaScriptWrapImports: true +# KeepEmptyLinesAtTheStartOfBlocks: true +# MacroBlockBegin: '' +# MacroBlockEnd: '' +# MaxEmptyLinesToKeep: 1 +# NamespaceIndentation: None +# ObjCBlockIndentWidth: 2 +# ObjCSpaceAfterProperty: false +# ObjCSpaceBeforeProtocolList: true +# PenaltyBreakBeforeFirstCallParameter: 19 +# PenaltyBreakComment: 300 +# PenaltyBreakFirstLessLess: 120 +# PenaltyBreakString: 1000 +# PenaltyExcessCharacter: 1000000 +# PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +# ReflowComments: true +SortIncludes: false +# SpaceAfterCStyleCast: false +# SpaceAfterTemplateKeyword: true +# SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +# SpaceInEmptyParentheses: false +# SpacesBeforeTrailingComments: 1 +# SpacesInAngles: false +# SpacesInContainerLiterals: true +# SpacesInCStyleCastParentheses: false +# SpacesInParentheses: false +# SpacesInSquareBrackets: false +Standard: Cpp03 +TabWidth: 4 +UseTab: Never diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..699d0e1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Ignore any folder starting from underscore +_*/ + +# Ignode Visual Studio Code temp folder +.vs/ +.vscode/ + +# Ignore vcpkg submodule +vcpkg/ + +# LSP +compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a4af656 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,1351 @@ +# +# SRT - Secure, Reliable, Transport +# Copyright (c) 2018 Haivision Systems Inc. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +cmake_minimum_required (VERSION 2.8.12 FATAL_ERROR) +set (SRT_VERSION 1.5.0) + +set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/scripts") +include(haiUtil) # needed for set_version_variables +# CMake version 3.0 introduced the VERSION option of the project() command +# to specify a project version as well as the name. +if(${CMAKE_VERSION} VERSION_LESS "3.0.0") + project(SRT C CXX) + # Sets SRT_VERSION_MAJOR, SRT_VERSION_MINOR, SRT_VERSION_PATCH + set_version_variables(SRT_VERSION ${SRT_VERSION}) +else() + cmake_policy(SET CMP0048 NEW) + # Also sets SRT_VERSION_MAJOR, SRT_VERSION_MINOR, SRT_VERSION_PATCH + project(SRT VERSION ${SRT_VERSION} LANGUAGES C CXX) +endif() + +include(FindPkgConfig) +# XXX See 'if (MINGW)' condition below, may need fixing. +include(FindThreads) +include(CheckFunctionExists) + +# Platform shortcuts +string(TOLOWER ${CMAKE_SYSTEM_NAME} SYSNAME_LC) +set_if(DARWIN (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + OR (${CMAKE_SYSTEM_NAME} MATCHES "iOS") + OR (${CMAKE_SYSTEM_NAME} MATCHES "tvOS") + OR (${CMAKE_SYSTEM_NAME} MATCHES "watchOS")) +set_if(LINUX ${CMAKE_SYSTEM_NAME} MATCHES "Linux") +set_if(BSD ${SYSNAME_LC} MATCHES "bsd$") +set_if(MICROSOFT WIN32 AND (NOT MINGW AND NOT CYGWIN)) +set_if(GNU ${CMAKE_SYSTEM_NAME} MATCHES "GNU") +set_if(ANDROID ${SYSNAME_LC} MATCHES "android") +set_if(SUNOS "${SYSNAME_LC}" MATCHES "sunos") +set_if(POSIX LINUX OR DARWIN OR BSD OR SUNOS OR ANDROID OR (CYGWIN AND CYGWIN_USE_POSIX)) +set_if(SYMLINKABLE LINUX OR DARWIN OR BSD OR SUNOS OR CYGWIN OR GNU) + +# Not sure what to do in case of compiling by MSVC. +# This will make installdir in C:\Program Files\SRT then +# inside "bin" and "lib64" directories. At least this maintains +# the current status. Shall this be not desired, override values +# of CMAKE_INSTALL_BINDIR, CMAKE_INSTALL_LIBDIR and CMAKE_INSTALL_INCLUDEDIR. +if (NOT DEFINED CMAKE_INSTALL_LIBDIR) + include(GNUInstallDirs) +endif() + +# The CMAKE_BUILD_TYPE seems not to be always set, weird. +if (NOT DEFINED ENABLE_DEBUG) + + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set (ENABLE_DEBUG ON) + else() + set (ENABLE_DEBUG OFF) + endif() +endif() + +# Set CMAKE_BUILD_TYPE properly, now that you know +# that ENABLE_DEBUG is set as it should. + +if (ENABLE_DEBUG EQUAL 2) + set (CMAKE_BUILD_TYPE "RelWithDebInfo") +elseif (ENABLE_DEBUG) # 1, ON, YES, TRUE, Y, or any other non-zero number + set (CMAKE_BUILD_TYPE "Debug") +else() + set (CMAKE_BUILD_TYPE "Release") +endif() + +message(STATUS "BUILD TYPE: ${CMAKE_BUILD_TYPE}") + +getVarsWith(ENFORCE_ enforcers) +foreach(ef ${enforcers}) + set (val ${${ef}}) + if (NOT val STREQUAL "") + set(val =${val}) + endif() + string(LENGTH ENFORCE_ pflen) + string(LENGTH ${ef} eflen) + math(EXPR alen ${eflen}-${pflen}) + string(SUBSTRING ${ef} ${pflen} ${alen} ef) + message(STATUS "FORCED PP VARIABLE: ${ef}${val}") + add_definitions(-D${ef}${val}) +endforeach() + +# NOTE: Known options you can change using ENFORCE_ variables: + +# SRT_ENABLE_ECN 1 /* Early Congestion Notification (for source bitrate control) */ +# SRT_DEBUG_TSBPD_OUTJITTER 1 /* Packet Delivery histogram */ +# SRT_DEBUG_TRACE_DRIFT 1 /* Create a trace log for Encoder-Decoder Clock Drift */ +# SRT_DEBUG_TSBPD_WRAP 1 /* Debug packet timestamp wraparound */ +# SRT_DEBUG_TLPKTDROP_DROPSEQ 1 +# SRT_DEBUG_SNDQ_HIGHRATE 1 +# SRT_DEBUG_BONDING_STATES 1 +# SRT_DEBUG_RTT 1 /* RTT trace */ +# SRT_MAVG_SAMPLING_RATE 40 /* Max sampling rate */ + +# option defaults +set(ENABLE_HEAVY_LOGGING_DEFAULT OFF) + +# Always turn logging on if the build type is debug +if (ENABLE_DEBUG) + set(ENABLE_HEAVY_LOGGING_DEFAULT ON) +endif() + + +set(ENABLE_STDCXX_SYNC_DEFAULT OFF) +set(ENABLE_MONOTONIC_CLOCK_DEFAULT OFF) +set(MONOTONIC_CLOCK_LINKLIB "") +if (MICROSOFT) + set(ENABLE_STDCXX_SYNC_DEFAULT ON) +elseif (POSIX) + test_requires_clock_gettime(ENABLE_MONOTONIC_CLOCK_DEFAULT MONOTONIC_CLOCK_LINKLIB) +endif() + + +# options +option(CYGWIN_USE_POSIX "Should the POSIX API be used for cygwin. Ignored if the system isn't cygwin." OFF) +if (CMAKE_CXX_COMPILER_ID MATCHES "^GNU$" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) + option(ENABLE_CXX11 "Should the c++11 parts (srt-live-transmit) be enabled" OFF) +else() + option(ENABLE_CXX11 "Should the c++11 parts (srt-live-transmit) be enabled" ON) +endif() +option(ENABLE_APPS "Should the Support Applications be Built?" OFF) +option(ENABLE_BONDING "Should the bonding functionality be enabled?" OFF) +option(ENABLE_TESTING "Should the Developer Test Applications be Built?" OFF) +option(ENABLE_PROFILE "Should instrument the code for profiling. Ignored for non-GNU compiler." $ENV{HAI_BUILD_PROFILE}) +option(ENABLE_LOGGING "Should logging be enabled" ON) +option(ENABLE_HEAVY_LOGGING "Should heavy debug logging be enabled" ${ENABLE_HEAVY_LOGGING_DEFAULT}) +option(ENABLE_HAICRYPT_LOGGING "Should logging in haicrypt be enabled" 0) +option(ENABLE_SHARED "Should libsrt be built as a shared library" ON) +option(ENABLE_STATIC "Should libsrt be built as a static library" ON) +option(ENABLE_RELATIVE_LIBPATH "Should application contain relative library paths, like ../lib" OFF) +option(ENABLE_GETNAMEINFO "In-logs sockaddr-to-string should do rev-dns" OFF) +option(ENABLE_UNITTESTS "Enable unit tests" OFF) +option(ENABLE_ENCRYPTION "Enable encryption in SRT" ON) +option(ENABLE_CXX_DEPS "Extra library dependencies in srt.pc for the CXX libraries useful with C language" ON) +option(USE_STATIC_LIBSTDCXX "Should use static rather than shared libstdc++" OFF) +option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON) +option(ENABLE_CODE_COVERAGE "Enable code coverage reporting" OFF) +option(ENABLE_MONOTONIC_CLOCK "Enforced clock_gettime with monotonic clock on GC CV" ${ENABLE_MONOTONIC_CLOCK_DEFAULT}) +option(ENABLE_STDCXX_SYNC "Use C++11 chrono and threads for timing instead of pthreads" ${ENABLE_STDCXX_SYNC_DEFAULT}) +option(USE_OPENSSL_PC "Use pkg-config to find OpenSSL libraries" ON) +option(OPENSSL_USE_STATIC_LIBS "Link OpenSSL libraries statically." OFF) +option(USE_BUSY_WAITING "Enable more accurate sending times at a cost of potentially higher CPU load" OFF) +option(USE_GNUSTL "Get c++ library/headers from the gnustl.pc" OFF) +option(ENABLE_SOCK_CLOEXEC "Enable setting SOCK_CLOEXEC on a socket" ON) +option(ENABLE_SHOW_PROJECT_CONFIG "Enable show Project Configuration" OFF) +option(ENABLE_NEW_RCVBUFFER "Enable new receiver buffer implementation" ON) + +option(ENABLE_CLANG_TSA "Enable Clang Thread Safety Analysis" OFF) + +# NOTE: Use ATOMIC_USE_SRT_SYNC_MUTEX and will override the auto-detection of the +# Atomic implemetation in srtcore/atomic.h. +option(ATOMIC_USE_SRT_SYNC_MUTEX "Use srt::sync::Mutex to Implement Atomics" OFF) +if (ATOMIC_USE_SRT_SYNC_MUTEX) + add_definitions(-DATOMIC_USE_SRT_SYNC_MUTEX=1) +endif() + +set(TARGET_srt "srt" CACHE STRING "The name for the SRT library") + +# Use application-defined group reader +# (currently the only one implemented) +add_definitions(-DSRT_ENABLE_APP_READER) + +# XXX This was added once as experimental, it is now in force for +# write-blocking-mode sockets. Still unclear if all issues around +# closing while data still not written are eliminated. +add_definitions(-DSRT_ENABLE_CLOSE_SYNCH) + +if (NOT ENABLE_LOGGING) + set (ENABLE_HEAVY_LOGGING OFF) + message(STATUS "LOGGING: DISABLED") +else() + if (ENABLE_HEAVY_LOGGING) + message(STATUS "LOGGING: HEAVY") + else() + message(STATUS "LOGGING: ENABLED") + endif() +endif() + +if (USE_BUSY_WAITING) + message(STATUS "USE_BUSY_WAITING: ON") + list(APPEND SRT_EXTRA_CFLAGS "-DUSE_BUSY_WAITING=1") +else() + message(STATUS "USE_BUSY_WAITING: OFF (default)") +endif() + +if ( CYGWIN AND NOT CYGWIN_USE_POSIX ) + set(WIN32 1) + set(CMAKE_LEGACY_CYGWIN_WIN32 1) + add_definitions(-DWIN32=1 -DCYGWIN=1) + message(STATUS "HAVE CYGWIN. Setting backward compat CMAKE_LEGACY_CYGWIN_WIN32 and -DWIN32") +endif() + +if (NOT USE_ENCLIB) + if (USE_GNUTLS) + message("NOTE: USE_GNUTLS is deprecated. Use -DUSE_ENCLIB=gnutls instead.") + set (USE_ENCLIB gnutls) + else() + set (USE_ENCLIB openssl) + endif() +endif() + +set(USE_ENCLIB "${USE_ENCLIB}" CACHE STRING "The crypto library that SRT uses") +set_property(CACHE USE_ENCLIB PROPERTY STRINGS "openssl" "gnutls" "mbedtls") + +# Make sure DLLs and executabes go to the same path regardles of subdirectory +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +if (NOT DEFINED WITH_COMPILER_TYPE) + + # This is for a case when you provided the prefix, but you didn't + # provide compiler type. This option is in this form predicted to work + # only on POSIX systems. Just typical compilers for Linux and Mac are + # included. + if (DARWIN) + set (WITH_COMPILER_TYPE clang) + elseif (POSIX) # Posix, but not DARWIN + set(WITH_COMPILER_TYPE gcc) + else() + get_filename_component(WITH_COMPILER_TYPE ${CMAKE_C_COMPILER} NAME) + endif() + set (USING_DEFAULT_COMPILER_PREFIX 1) +endif() + +if (NOT USING_DEFAULT_COMPILER_PREFIX OR DEFINED WITH_COMPILER_PREFIX) + message(STATUS "Handling compiler with PREFIX=${WITH_COMPILER_PREFIX} TYPE=${WITH_COMPILER_TYPE}") + + parse_compiler_type(${WITH_COMPILER_TYPE} COMPILER_TYPE COMPILER_SUFFIX) + + if (${COMPILER_TYPE} STREQUAL gcc) + set (CMAKE_C_COMPILER ${WITH_COMPILER_PREFIX}gcc${COMPILER_SUFFIX}) + set (CMAKE_CXX_COMPILER ${WITH_COMPILER_PREFIX}g++${COMPILER_SUFFIX}) + set (HAVE_COMPILER_GNU_COMPAT 1) + elseif (${COMPILER_TYPE} STREQUAL cc) + set (CMAKE_C_COMPILER ${WITH_COMPILER_PREFIX}cc${COMPILER_SUFFIX}) + set (CMAKE_CXX_COMPILER ${WITH_COMPILER_PREFIX}c++${COMPILER_SUFFIX}) + set (HAVE_COMPILER_GNU_COMPAT 1) + elseif (${COMPILER_TYPE} STREQUAL icc) + set (CMAKE_C_COMPILER ${WITH_COMPILER_PREFIX}icc${COMPILER_SUFFIX}) + set (CMAKE_CXX_COMPILER ${WITH_COMPILER_PREFIX}icpc${COMPILER_SUFFIX}) + set (HAVE_COMPILER_GNU_COMPAT 1) + else() + # Use blindly for C compiler and ++ for C++. + # At least this matches clang. + set (CMAKE_C_COMPILER ${WITH_COMPILER_PREFIX}${WITH_COMPILER_TYPE}) + set (CMAKE_CXX_COMPILER ${WITH_COMPILER_PREFIX}${COMPILER_TYPE}++${COMPILER_SUFFIX}) + if (${COMPILER_TYPE} STREQUAL clang) + set (HAVE_COMPILER_GNU_COMPAT 1) + endif() + endif() + message(STATUS "Compiler type: ${WITH_COMPILER_TYPE}. C: ${CMAKE_C_COMPILER}; C++: ${CMAKE_CXX_COMPILER}") + unset(USING_DEFAULT_COMPILER_PREFIX) +else() + message(STATUS "No WITH_COMPILER_PREFIX - using C++ compiler ${CMAKE_CXX_COMPILER}") +endif() + + +if (DEFINED WITH_SRT_TARGET) + set (TARGET_haisrt ${WITH_SRT_TARGET}) +endif() + +# When you use crosscompiling, you have to take care that PKG_CONFIG_PATH +# and CMAKE_PREFIX_PATH are set properly. + +# symbol exists in win32, but function does not. +if(WIN32) + if(ENABLE_INET_PTON) + set(CMAKE_REQUIRED_LIBRARIES ws2_32) + check_function_exists(inet_pton HAVE_INET_PTON) + add_definitions(-D_WIN32_WINNT=0x0600) + else() + add_definitions(-D_WIN32_WINNT=0x0501) + endif() +else() + check_function_exists(inet_pton HAVE_INET_PTON) +endif() +if (DEFINED HAVE_INET_PTON) + add_definitions(-DHAVE_INET_PTON=1) +endif() + +# Defines HAVE_PTHREAD_GETNAME_* and HAVE_PTHREAD_SETNAME_* +include(FindPThreadGetSetName) +FindPThreadGetSetName() + +if (ENABLE_MONOTONIC_CLOCK) + if (NOT ENABLE_MONOTONIC_CLOCK_DEFAULT) + message(FATAL_ERROR "Your platform does not support CLOCK_MONOTONIC. Build with -DENABLE_MONOTONIC_CLOCK=OFF.") + endif() + set (WITH_EXTRALIBS "${WITH_EXTRALIBS} ${MONOTONIC_CLOCK_LINKLIB}") + add_definitions(-DENABLE_MONOTONIC_CLOCK=1) +endif() + +if (ENABLE_ENCRYPTION) + if ("${USE_ENCLIB}" STREQUAL "gnutls") + set (SSL_REQUIRED_MODULES "gnutls nettle") + if (WIN32) + if (MINGW) + set (SSL_REQUIRED_MODULES "${SSL_REQUIRED_MODULES} zlib") + endif() + endif() + + pkg_check_modules (SSL REQUIRED ${SSL_REQUIRED_MODULES}) + + add_definitions( + -DUSE_GNUTLS=1 + ) + + link_directories( + ${SSL_LIBRARY_DIRS} + ) + elseif ("${USE_ENCLIB}" STREQUAL "mbedtls") + add_definitions(-DUSE_MBEDTLS=1) + if ("${SSL_LIBRARY_DIRS}" STREQUAL "") + set(MBEDTLS_PREFIX "${CMAKE_PREFIX_PATH}" CACHE PATH "The path of mbedtls") + find_package(MbedTLS REQUIRED) + set (SSL_INCLUDE_DIRS ${MBEDTLS_INCLUDE_DIR}) + set (SSL_LIBRARIES ${MBEDTLS_LIBRARIES}) + endif() + if ("${SSL_LIBRARIES}" STREQUAL "") + set (SSL_LIBRARIES mbedtls mbedcrypto) + endif() + message(STATUS "SSL enforced mbedtls: -I ${SSL_INCLUDE_DIRS} -l;${SSL_LIBRARIES}") + + foreach(LIB ${SSL_LIBRARIES}) + if(IS_ABSOLUTE ${LIB} AND EXISTS ${LIB}) + set (SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE} ${LIB}) + else() + set(SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE} "-l${LIB}") + endif() + endforeach() + else() # openssl + add_definitions(-DUSE_OPENSSL=1) + set (SSL_REQUIRED_MODULES "openssl1.1 libcrypto1.1") + # Try using pkg-config method first if enabled, + # fall back to find_package method otherwise + if (USE_OPENSSL_PC) + pkg_check_modules(SSL ${SSL_REQUIRED_MODULES}) + if (OPENSSL_USE_STATIC_LIBS) + # use `pkg-config --static xxx` found libs + set(SSL_LIBRARIES ${SSL_STATIC_LIBRARIES}) + endif() + endif() + if (SSL_FOUND) + # We have some cases when pkg-config is improperly configured + # When it doesn't ship the -L and -I options, and the CMAKE_PREFIX_PATH + # is set (also through `configure`), then we have this problem. If so, + # set forcefully the -I and -L contents to prefix/include and + # prefix/lib. + if ("${SSL_LIBRARY_DIRS}" STREQUAL "") + if (NOT "${CMAKE_PREFIX_PATH}" STREQUAL "") + message(STATUS "WARNING: pkg-config has incorrect prefix - enforcing target path prefix: ${CMAKE_PREFIX_PATH}") + set (SSL_LIBRARY_DIRS ${CMAKE_PREFIX_PATH}/${CMAKE_INSTALL_LIBDIR}) + set (SSL_INCLUDE_DIRS ${CMAKE_PREFIX_PATH}/include) + endif() + endif() + + link_directories( + ${SSL_LIBRARY_DIRS} + ) + message(STATUS "SSL via pkg-config: -L ${SSL_LIBRARY_DIRS} -I ${SSL_INCLUDE_DIRS} -l;${SSL_LIBRARIES}") + else() + find_package(OpenSSL REQUIRED) + set (SSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR}) + set (SSL_LIBRARIES ${OPENSSL_LIBRARIES}) + message(STATUS "SSL via find_package(OpenSSL): -I ${SSL_INCLUDE_DIRS} -l;${SSL_LIBRARIES}") + endif() + + endif() + + add_definitions(-DSRT_ENABLE_ENCRYPTION) + message(STATUS "ENCRYPTION: ENABLED, using: ${SSL_REQUIRED_MODULES}") + message (STATUS "SSL libraries: ${SSL_LIBRARIES}") +else() + message(STATUS "ENCRYPTION: DISABLED") +endif() + +if (USE_GNUSTL) + pkg_check_modules (GNUSTL REQUIRED gnustl) + link_directories(${GNUSTL_LIBRARY_DIRS}) + include_directories(${GNUSTL_INCLUDE_DIRS}) + set (SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE} ${GNUSTL_LIBRARIES} ${GNUSTL_LDFLAGS}) +endif() + +if (USING_DEFAULT_COMPILER_PREFIX) +# Detect if the compiler is GNU compatable for flags +if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Intel|Clang|AppleClang") + message(STATUS "COMPILER: ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) - GNU compat") + set(HAVE_COMPILER_GNU_COMPAT 1) + + # See https://gcc.gnu.org/projects/cxx-status.html + # At the bottom there's information about C++98, which is default up to 6.1 version. + # For all other compilers - including Clang - we state that the default C++ standard is AT LEAST 11. + if (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 6.1) + message(STATUS "NOTE: GCC ${CMAKE_CXX_COMPILER_VERSION} is detected with default C++98. Forcing C++11 on applications.") + set (FORCE_CXX_STANDARD 1) + elseif (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang|AppleClang") + message(STATUS "NOTE: CLANG ${CMAKE_CXX_COMPILER_VERSION} detected, unsure if >=C++11 is default, forcing C++11 on applications") + set (FORCE_CXX_STANDARD 1) + else() + message(STATUS "NOTE: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION} - assuming default C++11.") + endif() +else() + message(STATUS "COMPILER: ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) - NOT GNU compat") + set(HAVE_COMPILER_GNU_COMPAT 0) +endif() + +else() # Compiler altered by WITH_COMPILER_TYPE/PREFIX - can't rely on CMAKE_CXX_* + + # Force the C++ standard as C++11 + # HAVE_COMPILER_GNU_COMPAT was set in the handler of WITH_COMPILER_TYPE + set (FORCE_CXX_STANDARD 1) + message(STATUS "COMPILER CHANGED TO: ${COMPILER_TYPE} - forcing C++11 standard for apps") +endif() + +# Check for GCC Atomic Intrinsics and C++11 Atomics. +# Sets: +# HAVE_LIBATOMIC +# HAVE_LIBATOMIC_COMPILES +# HAVE_LIBATOMIC_COMPILES_STATIC +# HAVE_GCCATOMIC_INTRINSICS +# HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC +include(CheckGCCAtomicIntrinsics) +CheckGCCAtomicIntrinsics() +# HAVE_CXX_ATOMIC +# HAVE_CXX_ATOMIC_STATIC +include(CheckCXXAtomic) +CheckCXXAtomic() + +if (DISABLE_CXX11) + set (ENABLE_CXX11 0) +elseif( DEFINED ENABLE_CXX11 ) +else() + set (ENABLE_CXX11 1) +endif() + +function (srt_check_cxxstd stdval OUT_STD OUT_PFX) + + set (STDPFX c++) + if (stdval MATCHES "([^+]+\\++)([0-9]*)") + set (STDPFX ${CMAKE_MATCH_1}) + set (STDCXX ${CMAKE_MATCH_2}) + elseif (stdval MATCHES "[0-9]*") + set (STDCXX ${stdval}) + else() + set (STDCXX 0) + endif() + + # Handle C++98 < C++11 + # Please fix this around 2070 year. + if (${STDCXX} GREATER 80) + set (STDCXX 03) + endif() + + # return + set (${OUT_STD} ${STDCXX} PARENT_SCOPE) + set (${OUT_PFX} ${STDPFX} PARENT_SCOPE) +endfunction() + +if (NOT ENABLE_CXX11) + message(WARNING "Parts that require C++11 support will be disabled (srt-live-transmit)") + if (ENABLE_STDCXX_SYNC) + message(FATAL_ERROR "ENABLE_STDCXX_SYNC is set, but C++11 is disabled by ENABLE_CXX11") + endif() +elseif (ENABLE_STDCXX_SYNC) + add_definitions(-DENABLE_STDCXX_SYNC=1) + if (DEFINED USE_CXX_STD) + srt_check_cxxstd(${USE_CXX_STD} STDCXX STDPFX) + # If defined, make sure it's at least C++11 + if (${STDCXX} LESS 11) + message(FATAL_ERROR "If ENABLE_STDCXX_SYNC, then USE_CXX_STD must specify at least C++11") + endif() + else() + set (USE_CXX_STD 11) + endif() +endif() + +message(STATUS "STDCXX_SYNC: ${ENABLE_STDCXX_SYNC}") +message(STATUS "MONOTONIC_CLOCK: ${ENABLE_MONOTONIC_CLOCK}") + +if (ENABLE_SOCK_CLOEXEC) + add_definitions(-DENABLE_SOCK_CLOEXEC=1) +endif() + +if (ENABLE_NEW_RCVBUFFER) + add_definitions(-DENABLE_NEW_RCVBUFFER=1) + message(STATUS "RECEIVER_BUFFER: NEW") +else() + remove_definitions(-DENABLE_NEW_RCVBUFFER) + message(STATUS "RECEIVER_BUFFER: OLD") +endif() + +if (CMAKE_MAJOR_VERSION LESS 3) + set (FORCE_CXX_STANDARD_GNUONLY 1) +endif() + +if (DEFINED USE_CXX_STD) + srt_check_cxxstd(${USE_CXX_STD} STDCXX STDPFX) + + if (${STDCXX} EQUAL 0) + message(FATAL_ERROR "USE_CXX_STD: Must specify 03/11/14/17/20 possibly with c++/gnu++ prefix") + endif() + + if (NOT STDCXX STREQUAL "") + + if (${STDCXX} LESS 11) + if (ENABLE_STDCXX_SYNC) + message(FATAL_ERROR "If ENABLE_STDCXX_SYNC, then you can't USE_CXX_STD less than 11") + endif() + # Set back to 98 because cmake doesn't understand 03. + set (STDCXX 98) + # This enforces C++03 standard on SRT. + # Apps still use C++11 + + # Set this through independent flags + set (USE_CXX_STD_LIB ${STDCXX}) + set (FORCE_CXX_STANDARD 1) + if (NOT ENABLE_APPS) + set (USE_CXX_STD_APP ${STDCXX}) + message(STATUS "C++ STANDARD: library: C++${STDCXX}, apps disabled (examples will follow C++${STDCXX})") + else() + set (USE_CXX_STD_APP "") + message(STATUS "C++ STANDARD: library: C++${STDCXX}, but apps still at least C++11") + endif() + elseif (FORCE_CXX_STANDARD_GNUONLY) + # CMake is too old to handle CMAKE_CXX_STANDARD, + # use bare GNU options. + set (FORCE_CXX_STANDARD 1) + set (USE_CXX_STD_APP ${STDCXX}) + set (USE_CXX_STD_LIB ${STDCXX}) + message(STATUS "C++ STANDARD: using C++${STDCXX} for all - GNU only") + else() + # This enforces this standard on both apps and library, + # so set this as global C++ standard option + set (CMAKE_CXX_STANDARD ${STDCXX}) + unset (FORCE_CXX_STANDARD) + + # Do not set variables to not duplicate flags + set (USE_CXX_STD_LIB "") + set (USE_CXX_STD_APP "") + message(STATUS "C++ STANDARD: using C++${STDCXX} for all") + endif() + + message(STATUS "C++: Setting C++ standard for gnu compiler: lib: ${USE_CXX_STD_LIB} apps: ${USE_CXX_STD_APP}") + endif() +else() + set (USE_CXX_STD_LIB "") + set (USE_CXX_STD_APP "") +endif() + +if (FORCE_CXX_STANDARD) + message(STATUS "C++ STD: Forcing C++11 on applications") + if (USE_CXX_STD_APP STREQUAL "") + set (USE_CXX_STD_APP 11) + endif() + + if (USE_CXX_STD_LIB STREQUAL "" AND ENABLE_STDCXX_SYNC) + message(STATUS "C++ STD: Forcing C++11 on library, as C++11 sync requested") + set (USE_CXX_STD_LIB 11) + endif() +endif() + +# add extra warning flags for gccish compilers +if (HAVE_COMPILER_GNU_COMPAT) + set (SRT_GCC_WARN "-Wall -Wextra") +else() + # cpp debugging on Windows :D + #set (SRT_GCC_WARN "/showIncludes") +endif() + +if (USE_STATIC_LIBSTDCXX) + if (HAVE_COMPILER_GNU_COMPAT) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++") + else() + message(FATAL_ERROR "On non-GNU-compat compiler it's not known how to use static C++ standard library.") + endif() +endif() + + +# This options is necessary on some systems; on a cross-ARM compiler it +# has been detected, for example, that -lrt is necessary for some applications +# because clock_gettime is needed by some functions and it is alternatively +# provided by libc, but only in newer versions. This options is rarely necessary, +# but may help in several corner cases in unusual platforms. +if (WITH_EXTRALIBS) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${WITH_EXTRALIBS}") +endif() + +# CMake has only discovered in 3.3 version that some set-finder is +# necessary. Using variables for shortcut to a clumsy check syntax. + +set (srt_libspec_shared ${ENABLE_SHARED}) +set (srt_libspec_static ${ENABLE_STATIC}) + +set (srtpack_libspec_common) +if (srt_libspec_shared) + list(APPEND srtpack_libspec_common ${TARGET_srt}_shared) + +endif() +if (srt_libspec_static) + list(APPEND srtpack_libspec_common ${TARGET_srt}_static) +endif() + +set (SRT_SRC_HAICRYPT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/haicrypt) +set (SRT_SRC_SRTCORE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/srtcore) +set (SRT_SRC_COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/common) +set (SRT_SRC_TOOLS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tools) +set (SRT_SRC_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test) + +if(WIN32) + message(STATUS "DETECTED SYSTEM: WINDOWS; WIN32=1; PTW32_STATIC_LIB=1") + add_definitions(-DWIN32=1 -DPTW32_STATIC_LIB=1) +elseif(DARWIN) + message(STATUS "DETECTED SYSTEM: DARWIN") +elseif(BSD) + message(STATUS "DETECTED SYSTEM: BSD; BSD=1") + add_definitions(-DBSD=1) +elseif(LINUX) + add_definitions(-DLINUX=1) + message(STATUS "DETECTED SYSTEM: LINUX; LINUX=1" ) +elseif(ANDROID) + add_definitions(-DLINUX=1) + message(STATUS "DETECTED SYSTEM: ANDROID; LINUX=1" ) +elseif(CYGWIN) + add_definitions(-DCYGWIN=1) + message(STATUS "DETECTED SYSTEM: CYGWIN (posix mode); CYGWIN=1") +elseif(GNU) + add_definitions(-DGNU=1) + message(STATUS "DETECTED SYSTEM: GNU; GNU=1" ) +elseif(SUNOS) + add_definitions(-DSUNOS=1) + message(STATUS "DETECTED SYSTEM: SunOS|Solaris; SUNOS=1" ) +else() + message(FATAL_ERROR "Unsupported system: ${CMAKE_SYSTEM_NAME}") +endif() + +add_definitions( + -D_GNU_SOURCE + -DHAI_PATCH=1 + -DHAI_ENABLE_SRT=1 + -DSRT_VERSION="${SRT_VERSION}" +) + +if (LINUX) +# This is an option supported only on Linux + add_definitions(-DSRT_ENABLE_BINDTODEVICE) +endif() + +# This is obligatory include directory for all targets. This is only +# for private headers. Installable headers should be exclusively used DIRECTLY. +include_directories(${SRT_SRC_COMMON_DIR} ${SRT_SRC_SRTCORE_DIR} ${SRT_SRC_HAICRYPT_DIR}) + +if (ENABLE_LOGGING) + list(APPEND SRT_EXTRA_CFLAGS "-DENABLE_LOGGING=1") + if (ENABLE_HEAVY_LOGGING) + list(APPEND SRT_EXTRA_CFLAGS "-DENABLE_HEAVY_LOGGING=1") + endif() + if (ENABLE_HAICRYPT_LOGGING) + if (ENABLE_HAICRYPT_LOGGING STREQUAL 2) # Allow value 2 for INSECURE DEBUG logging + message(WARNING " *** ENABLED INSECURE HAICRYPT LOGGING - USE FOR TESTING ONLY!!! ***") + list(APPEND SRT_EXTRA_CFLAGS "-DENABLE_HAICRYPT_LOGGING=2") + else() + list(APPEND SRT_EXTRA_CFLAGS "-DENABLE_HAICRYPT_LOGGING=1") + endif() + endif() +endif() + +if (ENABLE_GETNAMEINFO) + list(APPEND SRT_EXTRA_CFLAGS "-DENABLE_GETNAMEINFO=1") +endif() + +# ENABLE_EXPERIMENTAL_BONDING is deprecated. Use ENABLE_BONDING. ENABLE_EXPERIMENTAL_BONDING is be removed in v1.6.0. +if (ENABLE_EXPERIMENTAL_BONDING) + message(DEPRECATION "ENABLE_EXPERIMENTAL_BONDING is deprecated. Please use ENABLE_BONDING instead.") + set (ENABLE_BONDING ON) +endif() + +if (ENABLE_BONDING) + list(APPEND SRT_EXTRA_CFLAGS "-DENABLE_BONDING=1") + message(STATUS "ENABLE_BONDING: ON") +else() + message(STATUS "ENABLE_BONDING: OFF") +endif() + +if (ENABLE_THREAD_CHECK) + add_definitions( + -DSRT_ENABLE_THREADCHECK=1 + -DFUGU_PLATFORM=1 + -I${WITH_THREAD_CHECK_INCLUDEDIR} + ) +endif() + +if (ENABLE_CLANG_TSA) + list(APPEND SRT_EXTRA_CFLAGS "-Wthread-safety") + message(STATUS "Clang TSA: Enabled") +endif() + +if (ENABLE_PROFILE) + if (HAVE_COMPILER_GNU_COMPAT) + # They are actually cflags, not definitions, but CMake is stupid enough. + add_definitions(-g -pg) + link_libraries(-g -pg) + else() + message(FATAL_ERROR "Profiling option is not supported on this platform") + endif() +endif() + +if (ENABLE_CODE_COVERAGE) + if (HAVE_COMPILER_GNU_COMPAT) + add_definitions(-g -O0 --coverage) + link_libraries(--coverage) + message(STATUS "ENABLE_CODE_COVERAGE: ON") + else() + message(FATAL_ERROR "ENABLE_CODE_COVERAGE: option is not supported on this platform") + endif() +endif() + +# On Linux pthreads have to be linked even when using C++11 threads +if (ENABLE_STDCXX_SYNC AND NOT LINUX) + message(STATUS "Pthread library: C++11") +elseif (PTHREAD_LIBRARY AND PTHREAD_INCLUDE_DIR) + message(STATUS "Pthread library: ${PTHREAD_LIBRARY}") + message(STATUS "Pthread include dir: ${PTHREAD_INCLUDE_DIR}") +elseif (MICROSOFT) + find_package(pthreads QUIET) + + if (NOT PTHREAD_INCLUDE_DIR OR NOT PTHREAD_LIBRARY) + #search package folders with GLOB to add as extra hint for headers + file(GLOB PTHREAD_PACKAGE_INCLUDE_HINT ./_packages/cinegy.pthreads-win*/sources) + if (PTHREAD_PACKAGE_INCLUDE_HINT) + message(STATUS "PTHREAD_PACKAGE_INCLUDE_HINT value: ${PTHREAD_PACKAGE_INCLUDE_HINT}") + endif() + + # find pthread header + find_path(PTHREAD_INCLUDE_DIR pthread.h HINTS C:/pthread-win32/include ${PTHREAD_PACKAGE_INCLUDE_HINT}) + + if (PTHREAD_INCLUDE_DIR) + message(STATUS "Pthread include dir: ${PTHREAD_INCLUDE_DIR}") + else() + message(FATAL_ERROR "Failed to find pthread.h. Specify PTHREAD_INCLUDE_DIR.") + endif() + + #search package folders with GLOB to add as extra hint for libs + file(GLOB PTHREAD_PACKAGE_LIB_HINT ./_packages/cinegy.pthreads-win*/runtimes/win-*/native/release) + if (PTHREAD_PACKAGE_LIB_HINT) + message(STATUS "PTHREAD_PACKAGE_LIB_HINT value: ${PTHREAD_PACKAGE_LIB_HINT}") + endif() + + #find pthread library + set(PTHREAD_LIB_SUFFIX "") + if (ENABLE_DEBUG) + set(PTHREAD_LIB_SUFFIX "d") + endif () + + set(PTHREAD_COMPILER_FLAG "") + if (MICROSOFT) + set(PTHREAD_COMPILER_FLAG "V") + elseif (MINGW) + set(PTHREAD_COMPILER_FLAG "G") + endif () + + foreach(EXHAND C CE SE) + foreach(COMPAT 1 2) + list(APPEND PTHREAD_W32_LIBRARY "pthread${PTHREAD_COMPILER_FLAG}${EXHAND}${PTHREAD_LIB_SUFFIX}${COMPAT}") + endforeach() + endforeach() + + find_library(PTHREAD_LIBRARY NAMES ${PTHREAD_W32_LIBRARY} pthread pthread_dll pthread_lib HINTS C:/pthread-win32/lib C:/pthread-win64/lib ${PTHREAD_PACKAGE_LIB_HINT}) + if (PTHREAD_LIBRARY) + message(STATUS "Pthread library: ${PTHREAD_LIBRARY}") + else() + message(FATAL_ERROR "Failed to find pthread library. Specify PTHREAD_LIBRARY.") + endif() + endif() +else () + find_package(Threads REQUIRED) + set(PTHREAD_LIBRARY ${CMAKE_THREAD_LIBS_INIT}) +endif() + +# This is required in some projects that add some other sources +# to the SRT library to be compiled together (aka "virtual library"). +if (DEFINED SRT_EXTRA_LIB_INC) + include(${SRT_EXTRA_LIB_INC}.cmake) + # Expected to provide variables: + # - SOURCES_srt_extra + # - EXTRA_stransmit +endif() + +# --------------------------------------------------------------------------- + +# --- +# Target: haicrypt. +# Completing sources and installable headers. Flag settings will follow. +# --- +if (ENABLE_ENCRYPTION) + set (HAICRYPT_FILELIST_MAF "filelist-${USE_ENCLIB}.maf") + + MafReadDir(haicrypt ${HAICRYPT_FILELIST_MAF} + SOURCES SOURCES_haicrypt + PUBLIC_HEADERS HEADERS_haicrypt + PROTECTED_HEADERS HEADERS_haicrypt + ) +endif() + +if (WIN32) + MafReadDir(common filelist_win32.maf + SOURCES SOURCES_common + PUBLIC_HEADERS HEADERS_srt_win32 + PROTECTED_HEADERS HEADERS_srt_win32 + ) + message(STATUS "WINDOWS detected: adding compat sources: ${SOURCES_common}") +endif() + + +# Make the OBJECT library for haicrypt and srt. Then they'll be bound into +# real libraries later, either one common, or separate. + +# This is needed for Xcode to properly handle CMake OBJECT Libraries +# From docs (https://cmake.org/cmake/help/latest/command/add_library.html#object-libraries): +# +# ... Some native build systems (such as Xcode) may not like targets that have only object files, +# so consider adding at least one real source file to any target that references $. +set(OBJECT_LIB_SUPPORT "${PROJECT_SOURCE_DIR}/cmake_object_lib_support.c") + +# NOTE: The "virtual library" is a library specification that cmake +# doesn't support (the library of OBJECT type is something in kind of that, +# but not fully supported - for example it doesn't support transitive flags, +# so this can't be used desired way). It's a private-only dependency type, +# where the project isn't compiled into any library file at all - instead, all +# of its source files are incorporated directly to the source list of the +# project that depends on it. In cmake this must be handled manually. + + +# --- +# Target: srt. DEFINITION ONLY. Haicrypt flag settings follow. +# --- + +if (ENABLE_SHARED AND MICROSOFT) + #add resource files to shared library, to set DLL metadata on Windows DLLs + set (EXTRA_WIN32_SHARED 1) + message(STATUS "WIN32: extra resource file will be added") +endif() + +MafReadDir(srtcore filelist.maf + SOURCES SOURCES_srt + PUBLIC_HEADERS HEADERS_srt + PROTECTED_HEADERS HEADERS_srt + PRIVATE_HEADERS HEADERS_srt_private +) + +# Auto generated version file and add it to the HEADERS_srt list. +if(DEFINED ENV{APPVEYOR_BUILD_NUMBER}) + set(SRT_VERSION_BUILD ON) + set(CI_BUILD_NUMBER_STRING $ENV{APPVEYOR_BUILD_NUMBER}) + message(STATUS "AppVeyor build environment detected: Adding build number to version header") +endif() +if(DEFINED ENV{TEAMCITY_VERSION}) + set(SRT_VERSION_BUILD ON) + set(CI_BUILD_NUMBER_STRING $ENV{CI_BUILD_COUNTER}) + message(STATUS "TeamCity build environment detected: Adding build counter to version header") +endif() + +configure_file("srtcore/version.h.in" "version.h" @ONLY) + +list(INSERT HEADERS_srt 0 "${CMAKE_CURRENT_BINARY_DIR}/version.h") +include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_library(srt_virtual OBJECT ${SOURCES_srt} ${SOURCES_srt_extra} ${HEADERS_srt} ${SOURCES_haicrypt} ${SOURCES_common}) + +if (ENABLE_SHARED) + # Set this to sources as well, as it won't be automatically handled + set_target_properties(srt_virtual PROPERTIES POSITION_INDEPENDENT_CODE 1) +endif() + +macro(srt_set_stdcxx targetname spec) + set (stdcxxspec ${spec}) + if (NOT "${stdcxxspec}" STREQUAL "") + if (FORCE_CXX_STANDARD_GNUONLY) + target_compile_options(${targetname} PRIVATE -std=c++${stdcxxspec}) + message(STATUS "C++ STD: ${targetname}: forced C++${stdcxxspec} standard - GNU option: -std=c++${stdcxxspec}") + else() + set_target_properties(${targetname} PROPERTIES CXX_STANDARD ${stdcxxspec}) + message(STATUS "C++ STD: ${targetname}: forced C++${stdcxxspec} standard - portable way") + endif() + else() + message(STATUS "APP: ${targetname}: using default C++ standard") + endif() +endmacro() + + +srt_set_stdcxx(srt_virtual "${USE_CXX_STD_LIB}") + +set (VIRTUAL_srt $) + +if (srt_libspec_shared) + add_library(${TARGET_srt}_shared SHARED ${OBJECT_LIB_SUPPORT} ${VIRTUAL_srt}) + # shared libraries need PIC + set (CMAKE_POSITION_INDEPENDENT_CODE ON) + set_property(TARGET ${TARGET_srt}_shared PROPERTY OUTPUT_NAME ${TARGET_srt}) + set_target_properties (${TARGET_srt}_shared PROPERTIES VERSION ${SRT_VERSION} SOVERSION ${SRT_VERSION_MAJOR}.${SRT_VERSION_MINOR}) + list (APPEND INSTALL_TARGETS ${TARGET_srt}_shared) + if (ENABLE_ENCRYPTION) + target_link_libraries(${TARGET_srt}_shared PRIVATE ${SSL_LIBRARIES}) + endif() + if (MICROSOFT) + target_link_libraries(${TARGET_srt}_shared PRIVATE ws2_32.lib) + if (OPENSSL_USE_STATIC_LIBS) + target_link_libraries(${TARGET_srt}_shared PRIVATE crypt32.lib) + else() + set_target_properties(${TARGET_srt}_shared PROPERTIES LINK_FLAGS "/DELAYLOAD:libeay32.dll") + endif() + elseif (MINGW) + target_link_libraries(${TARGET_srt}_shared PRIVATE wsock32 ws2_32) + elseif (APPLE) + set_property(TARGET ${TARGET_srt}_shared PROPERTY MACOSX_RPATH ON) + endif() + if (USE_GNUSTL) + target_link_libraries(${TARGET_srt}_shared PRIVATE ${GNUSTL_LIBRARIES} ${GNUSTL_LDFLAGS}) + endif() +endif() + +if (srt_libspec_static) + add_library(${TARGET_srt}_static STATIC ${OBJECT_LIB_SUPPORT} ${VIRTUAL_srt}) + + # For Windows, leave the name to be "srt_static.lib". + # Windows generates two different library files: + # - a usual static library for static linkage + # - a shared library exposer, which allows pre-resolution and later dynamic + # linkage when running the executable + # Both having unfortunately the same names created by MSVC compiler. + # It's not the case of Cygwin/MINGW - they are named there libsrt.a and libsrt.dll.a + if (MICROSOFT) + # Keep _static suffix. By unknown reason, the name must still be set explicitly. + set_property(TARGET ${TARGET_srt}_static PROPERTY OUTPUT_NAME ${TARGET_srt}_static) + else() + set_property(TARGET ${TARGET_srt}_static PROPERTY OUTPUT_NAME ${TARGET_srt}) + endif() + + list (APPEND INSTALL_TARGETS ${TARGET_srt}_static) + if (ENABLE_ENCRYPTION) + target_link_libraries(${TARGET_srt}_static PRIVATE ${SSL_LIBRARIES}) + endif() + if (MICROSOFT) + target_link_libraries(${TARGET_srt}_static PRIVATE ws2_32.lib) + if (OPENSSL_USE_STATIC_LIBS) + target_link_libraries(${TARGET_srt}_static PRIVATE crypt32.lib) + endif() + elseif (MINGW) + target_link_libraries(${TARGET_srt}_static PRIVATE wsock32 ws2_32) + endif() + if (USE_GNUSTL) + target_link_libraries(${TARGET_srt}_static PRIVATE ${GNUSTL_LIBRARIES} ${GNUSTL_LDFLAGS}) + endif() +endif() + +target_include_directories(srt_virtual PRIVATE ${SSL_INCLUDE_DIRS}) + +if (MICROSOFT) + if (OPENSSL_USE_STATIC_LIBS) + set (SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE} ws2_32.lib crypt32.lib) + else() + set (SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE} ws2_32.lib) + endif() +elseif (MINGW) + set (SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE} -lwsock32 -lws2_32) +endif() + +# Applying this to public includes is not transitive enough. +# On Windows, apps require this as well, so it's safer to +# spread this to all targets. +if (PTHREAD_INCLUDE_DIR) + include_directories(${PTHREAD_INCLUDE_DIR}) +endif() + +# Link libraries must be applied directly to the derivatives +# as virtual libraries (OBJECT-type) cannot have linkage declarations +# transitive or not. + +foreach(tar ${srtpack_libspec_common}) + message(STATUS "ADDING TRANSITIVE LINK DEP to:${tar} : ${PTHREAD_LIBRARY} ${dep}") + target_link_libraries (${tar} PUBLIC ${PTHREAD_LIBRARY} ${dep}) +endforeach() + + +set (SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE} ${PTHREAD_LIBRARY}) + +target_compile_definitions(srt_virtual PRIVATE -DSRT_EXPORTS ) +if (ENABLE_SHARED) + target_compile_definitions(srt_virtual PUBLIC -DSRT_DYNAMIC) +endif() + +if (srt_libspec_shared) + if (MICROSOFT) + target_link_libraries(${TARGET_srt}_shared PUBLIC Ws2_32.lib) + if (OPENSSL_USE_STATIC_LIBS) + target_link_libraries(${TARGET_srt}_shared PUBLIC crypt32.lib) + endif() + endif() +endif() + +# Required by some toolchains when statically linking this library if the +# GCC Atomic Intrinsics are being used. +if (HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC AND HAVE_LIBATOMIC) + if (srt_libspec_static) + target_link_libraries(${TARGET_srt}_static PUBLIC atomic) + endif() + if (srt_libspec_shared) + target_link_libraries(${TARGET_srt}_shared PUBLIC atomic) + endif() +elseif (HAVE_LIBATOMIC AND HAVE_LIBATOMIC_COMPILES_STATIC) + # This is a workaround for ANDROID NDK<17 builds, which need to link + # to libatomic when linking statically to the SRT library. + if (srt_libspec_static) + target_link_libraries(${TARGET_srt}_static PUBLIC atomic) + endif() +endif() + +# Cygwin installs the *.dll libraries in bin directory and uses PATH. + +set (INSTALL_SHARED_DIR ${CMAKE_INSTALL_LIBDIR}) +if (CYGWIN) + set (INSTALL_SHARED_DIR ${CMAKE_INSTALL_BINDIR}) +endif() + +message(STATUS "INSTALL DIRS: bin=${CMAKE_INSTALL_BINDIR} lib=${CMAKE_INSTALL_LIBDIR} shlib=${INSTALL_SHARED_DIR} include=${CMAKE_INSTALL_INCLUDEDIR}") + +install(TARGETS ${INSTALL_TARGETS} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${INSTALL_SHARED_DIR} +) +install(FILES ${HEADERS_srt} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/srt) +if (WIN32) + install(FILES ${HEADERS_srt_win32} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/srt/win) +endif() + +# --- +# That's all for target definition +# --- + +join_arguments(SRT_EXTRA_CFLAGS ${SRT_EXTRA_CFLAGS}) + +#message(STATUS "Target srt: LIBSPEC: ${srtpack_libspec_common} SOURCES: {${SOURCES_srt}} HEADERS: {${HEADERS_srt}}") + +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SRT_DEBUG_OPT} ${SRT_EXTRA_CFLAGS} ${SRT_GCC_WARN}") +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SRT_DEBUG_OPT} ${SRT_EXTRA_CFLAGS} ${SRT_GCC_WARN}") + +# PC file generation. +if (NOT DEFINED INSTALLDIR) + set (INSTALLDIR ${CMAKE_INSTALL_PREFIX}) + get_filename_component(INSTALLDIR ${INSTALLDIR} ABSOLUTE) +endif() + +# Required if linking a C application. +# This may cause trouble when you want to compile your app with static libstdc++; +# if your build requires it, you'd probably remove -lstdc++ from the list +# obtained by `pkg-config --libs`. +if(ENABLE_CXX_DEPS) + foreach(LIB ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}) + if(IS_ABSOLUTE ${LIB} AND EXISTS ${LIB}) + set(SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE} ${LIB}) + else() + set(SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE} "-l${LIB}") + endif() + endforeach() +endif() + +join_arguments(SRT_LIBS_PRIVATE ${SRT_LIBS_PRIVATE}) + +# haisrt.pc left temporarily for backward compatibility. To be removed in future! +# configure_file(scripts/srt.pc.in haisrt.pc @ONLY) +# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/haisrt.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +configure_file(scripts/srt.pc.in srt.pc @ONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/srt.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + +# Applications + +# If static is available, link apps against static one. +# Otherwise link against shared one. + +if (srt_libspec_static) + set (srt_link_library ${TARGET_srt}_static) + if (ENABLE_RELATIVE_LIBPATH) + message(STATUS "ENABLE_RELATIVE_LIBPATH=ON will be ignored due to static linking.") + endif() +elseif(srt_libspec_shared) + set (srt_link_library ${TARGET_srt}_shared) +else() + message(FATAL_ERROR "Either ENABLE_STATIC or ENABLE_SHARED has to be ON!") +endif() + +macro(srt_add_program_dont_install name) + add_executable(${name} ${ARGN}) + target_include_directories(${name} PRIVATE apps) + target_include_directories(${name} PRIVATE common) +endmacro() + +macro(srt_add_program name) + srt_add_program_dont_install(${name} ${ARGN}) + install(TARGETS ${name} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endmacro() + +macro(srt_make_application name) + + srt_set_stdcxx(${name} "${USE_CXX_STD_APP}") + + # This is recommended by cmake, but it doesn't work anyway. + # What is needed is that this below CMAKE_INSTALL_RPATH (yes, relative) + # is added as is. + # set (CMAKE_SKIP_RPATH FALSE) + # set (CMAKE_SKIP_BUILD_RPATH FALSE) + # set (CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + # set (CMAKE_INSTALL_RPATH "../${CMAKE_INSTALL_LIBDIR}") + # set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + # set (FORCE_RPATH BUILD_WITH_INSTALL_RPATH TRUE INSTALL_RPATH_USE_LINK_PATH TRUE) + + if (LINUX AND ENABLE_RELATIVE_LIBPATH AND NOT srt_libspec_static) + # This is only needed on Linux, on Windows (including Cygwin) the library file will + # be placed into the binrary directory anyway. + # XXX not sure about Mac. + # See this name used already in install(${TARGET_srt} LIBRARY DESTINATION...). + set(FORCE_RPATH LINK_FLAGS -Wl,-rpath,.,-rpath,../${CMAKE_INSTALL_LIBDIR} BUILD_WITH_INSTALL_RPATH TRUE INSTALL_RPATH_USE_LINK_PATH TRUE) + + set_target_properties(${name} PROPERTIES ${FORCE_RPATH}) + endif() + + target_link_libraries(${name} ${srt_link_library}) + if (USE_GNUSTL) + target_link_libraries(${name} PRIVATE ${GNUSTL_LIBRARIES} ${GNUSTL_LDFLAGS}) + endif() + if (srt_libspec_static AND CMAKE_DL_LIBS) + target_link_libraries(${name} ${CMAKE_DL_LIBS}) + endif() +endmacro() + +macro(srt_add_application name) # ARGN=sources... + srt_add_program(${name} apps/${name}.cpp ${ARGN}) + srt_make_application(${name}) + install(TARGETS ${name} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endmacro() + +## FIXME: transmitmedia.cpp does not build on OpenBSD +## Issue: https://github.com/Haivision/srt/issues/590 +if (BSD + AND ${SYSNAME_LC} MATCHES "^openbsd$") + set(ENABLE_APPS OFF) +endif() +## The applications currently require c++11. +if (NOT ENABLE_CXX11) + set(ENABLE_APPS OFF) +endif() + +if (ENABLE_APPS) + + message(STATUS "APPS: ENABLED, std=${USE_CXX_STD_APP}") + + # Make a virtual library of all shared app files + MafReadDir(apps support.maf + SOURCES SOURCES_support + ) + + # A special trick that makes the shared application sources + # to be compiled once for all applications. Maybe this virtual + # library should be changed into a static one and made useful + # for users. + add_library(srtsupport_virtual OBJECT ${SOURCES_support}) + srt_set_stdcxx(srtsupport_virtual "${USE_CXX_STD_APP}") + set (VIRTUAL_srtsupport $) + + # Applications + + srt_add_application(srt-live-transmit ${VIRTUAL_srtsupport}) + if (DEFINED EXTRA_stransmit) + set_target_properties(srt-live-transmit PROPERTIES COMPILE_FLAGS "${EXTRA_stransmit}") + endif() + srt_add_application(srt-file-transmit ${VIRTUAL_srtsupport}) + + if (MINGW) + # FIXME: with MINGW, it fails to build apps that require C++11 + # https://github.com/Haivision/srt/issues/177 + message(WARNING "On MinGW, some C++11 apps are blocked due to lacking proper C++11 headers for . FIX IF POSSIBLE.") + else() + # srt-multiplex temporarily blocked + #srt_add_application(srt-multiplex ${VIRTUAL_srtsupport}) + srt_add_application(srt-tunnel ${VIRTUAL_srtsupport}) + target_compile_definitions(srt-tunnel PUBLIC -DSRT_ENABLE_VERBOSE_LOCK) + endif() + + if (ENABLE_TESTING) + message(STATUS "DEVEL APPS (testing): ENABLED") + + macro(srt_add_testprogram name) + # Variables in macros are not local. Clear them forcefully. + set (SOURCES_app_indir "") + set (SOURCES_app "") + # Unlike Silvercat, in cmake you must know the full list + # of source files at the moment when defining the target + # and it can't be altered later. + # + # For testing applications, every application has its exclusive + # list of source files in its own Manifest file. + MafReadDir(testing ${name}.maf SOURCES SOURCES_app) + srt_add_program_dont_install(${name} ${SOURCES_app}) + endmacro() + + srt_add_testprogram(utility-test) + srt_set_stdcxx(utility-test "${USE_CXX_STD_APP}") + if (NOT WIN32) + # This program is symlinked under git-cygwin. + # Avoid misleading syntax error. + srt_add_testprogram(uriparser-test) + target_compile_options(uriparser-test PRIVATE -DTEST) + srt_set_stdcxx(uriparser-test "${USE_CXX_STD_APP}") + endif() + + srt_add_testprogram(srt-test-live) + srt_make_application(srt-test-live) + + srt_add_testprogram(srt-test-file) + srt_make_application(srt-test-file) + + srt_add_testprogram(srt-test-relay) + srt_make_application(srt-test-relay) + target_compile_definitions(srt-test-relay PUBLIC -DSRT_ENABLE_VERBOSE_LOCK) + + srt_add_testprogram(srt-test-multiplex) + srt_make_application(srt-test-multiplex) + + if (ENABLE_BONDING) + srt_add_testprogram(srt-test-mpbond) + srt_make_application(srt-test-mpbond) + endif() + + else() + message(STATUS "DEVEL APPS (testing): DISABLED") + endif() + + +else() + message(STATUS "APPS: DISABLED") +endif() + +if (ENABLE_EXAMPLES) + + # No examples should need C++11 + macro(srt_add_example mainsrc) + get_filename_component(name ${mainsrc} NAME_WE) + srt_add_program_dont_install(${name} examples/${mainsrc} ${ARGN}) + target_link_libraries(${name} ${srt_link_library} ${DEPENDS_srt}) + endmacro() + + srt_add_example(recvlive.cpp) + + srt_add_example(sendfile.cpp) + + srt_add_example(recvfile.cpp) + + srt_add_example(test-c-client.c) + + srt_add_example(example-client-nonblock.c) + + srt_add_example(test-c-server.c) + +if (ENABLE_BONDING) + srt_add_example(test-c-client-bonding.c) + + srt_add_example(test-c-server-bonding.c) +endif() + + srt_add_example(testcapi-connect.c) +endif() + + +if (ENABLE_UNITTESTS AND ENABLE_CXX11) + + if (${CMAKE_VERSION} VERSION_LESS "3.10.0") + message(STATUS "VERSION < 3.10 -- adding test using the old method") + set (USE_OLD_ADD_METHOD 1) + else() + message(STATUS "VERSION > 3.10 -- using NEW POLICY for in_list operator") + cmake_policy(SET CMP0057 NEW) # Support the new IN_LIST operator. + endif() + + + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + + find_package(GTest 1.8) + if (NOT GTEST_FOUND) + message(STATUS "GTEST not found! Fetching from git.") + include(googletest) + fetch_googletest( + ${PROJECT_SOURCE_DIR}/scripts + ${PROJECT_BINARY_DIR}/googletest + ) + set(GTEST_BOTH_LIBRARIES "gtest_main" CACHE STRING "Add gtest_main target") + endif() + + MafReadDir(test filelist.maf + HEADERS SOURCES_unittests + SOURCES SOURCES_unittests + ) + + srt_add_program_dont_install(test-srt ${SOURCES_unittests}) + srt_make_application(test-srt) + target_include_directories(test-srt PRIVATE ${SSL_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS}) + + target_link_libraries( + test-srt + ${GTEST_BOTH_LIBRARIES} + ${srt_link_library} + ${PTHREAD_LIBRARY} + ) + + if (USE_OLD_ADD_METHOD) + add_test( + NAME test-srt + COMMAND ${CMAKE_BINARY_DIR}/test-srt + ) + else() + gtest_add_tests( + test-srt + "" + AUTO + ) + endif() + + enable_testing() + +endif() + + +if (DEFINED SRT_EXTRA_APPS_INC) + include(${SRT_EXTRA_APPS_INC}.cmake) + # No extra variables expected. Just use the variables + # already provided and define additional targets. +endif() + +if (ENABLE_SHOW_PROJECT_CONFIG) + include(ShowProjectConfig) + ShowProjectConfig() +endif() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..239e25a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,58 @@ +## License + +By contributing code to the [SRT project](https://github.com/Haivision/srt/), you agree to license your contribution under the [MPLv2.0 License](LICENSE). + +## Issues + +Open a GitHub issue for anything you find or any questions you have. + +## Comments + +Comment on any GitHub issue, open or closed. The only guidelines here are to be friendly and welcoming. If you see that a question has been asked and you think you know the answer, don't wait! + +## Pull Requests + +Submit a pull request at any time, whether an issue has been created or not. It may be helpful to discuss your goals in an issue first, though many things can best be shown with code. Also do not hesitate to ask other users for opinion and discuss the ideas using the ticketing system before you start making your changes. This is especially important in these areas: + +* the build system and its variables +* the SRT library public API +* command line tools and their call syntax +* the reusable parts (such as utilities) +* SRT protocol definitions +* portability and platform-specific parts + +Please follow the [SRT Developer's Guide](docs/dev/developers-guide.md). + +## Code Style + +Please follow existing style. + +## Attribution + +This contributing guide is adapted from [VVV's guide](https://github.com/Varying-Vagrant-Vagrants/VVV/blob/develop/.github/CONTRIBUTING.md). + +## Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +* (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +* (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +* (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +* (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..14e2f77 --- /dev/null +++ b/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8a0da00 --- /dev/null +++ b/README.md @@ -0,0 +1,228 @@ +# Secure Reliable Transport (SRT) Protocol + +[About SRT](#what-is-srt) | [Features](#features) | [Getting Started](#getting-started-with-srt) | [Builds](#build-instructions) | [Sample Apps and Tools](#sample-applications-and-tools) | [Contribute](#contributing) | [License](#license) | [Releases](#release-history) + +

+ + SRT + +

+ +[![License: MPLv2.0][license-badge]](./LICENSE) +[![Latest release][release-badge]][github releases] +[![Debian Badge][debian-badge]][debian-package] +[![LGTM Code Quality][lgtm-quality-badge]][lgtm-project] +[![LGTM Alerts][lgtm-alerts-badge]][lgtm-project] +[![codecov][codecov-badge]][codecov-project] +[![Build Status Linux and macOS][travis-badge]][travis] +[![Build Status Windows][appveyor-badge]][appveyor] + +## What is SRT? + +**Secure Reliable Transport (SRT)** is a transport protocol for ultra low (sub-second) latency live video and audio streaming, as well as for generic bulk data transfer[^1]. SRT is available as an open-source technology with the code on GitHub, a published [Internet Draft](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01), and a growing [community of SRT users](https://www.srtalliance.org/). + +SRT is applied to contribution and distribution endpoints as part of a video stream workflow to deliver the best quality and lowest latency video at all times. + +| | | +| ------------- | ------------------------------------------------- | +| **S**ecure | Encrypts video streams | +| **R**eliable | Recovers from severe packet loss | +| **T**ransport | Dynamically adapts to changing network conditions | + +In live streaming configurations, the SRT protocol maintains a constant end-to-end latency. This allows the live stream’s signal characteristics to be recreated on the receiver side, reducing the need for buffering. As packets are streamed from source to destination, SRT detects and adapts to real-time network conditions between the two endpoints. It helps compensate for jitter and bandwidth fluctuations due to congestion over noisy networks. + +[SRT implements AES encryption](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-6) to protect the payload of the media streams, and offers various error recovery mechanisms for minimizing the packet loss that is typical of Internet connections, of which Automatic Repeat reQuest (ARQ) is the primary method. With ARQ, when a receiver detects that a packet is missing it sends an alert to the sender requesting retransmission of this missing packet. [Forward Error Correction (FEC)](./docs/features/packet-filtering-and-fec.md) and [Connection Bonding](./docs/features/bonding-quick-start.md), which adds seamless stream protection and hitless failover, are also supported by the protocol. + +

To learn more about the protocol subscribe to the Innovation Labs Blog on  slack logo

+ +

To ask a question join the conversation in the #development channel on  slack logo

+ +## Features + +> :point_down: Click on the ► button to expand a feature description. + +
+ Pristine Quality and Reliability + +

+ + No matter how unreliable your network, SRT can recover from severe packet loss and jitter, ensuring the integrity and quality of your video streams. + +

+
+ +
+ Low Latency + +

+ + SRT’s stream error correction is configurable to accommodate a user’s deployment conditions. Leveraging real-time IP communications development to extend traditional network error recovery practices, SRT delivers media with significantly lower latency than TCP/IP, while offering the speed of UDP transmission with greatly improved reliability. + +

+
+ +
+ Content Agnostic + +

+ + Unlike some other streaming protocols that only support specific video and audio formats, SRT is payload agnostic. Because SRT operates at the network transport level, acting as a wrapper around your content, it can transport any type of video format, codec, resolution, or frame rate. + +

+
+ +
+ Easy Firewall Traversal with Rendezvous Mode + +

+ + The handshaking process used by SRT supports outbound connections without the potential risks and dangers of permanent exterior ports being opened in a firewall, thereby maintaining corporate LAN security policies and minimizing the need for IT intervention. + +

+
+ +
+ AES Encryption + +

+ + Using 128/192/256-bit AES encryption trusted by governments and organizations around the world, SRT ensures that valuable content is protected end-to-end from contribution to distribution so that no unauthorized parties can listen. + +

+
+ +
+ Forward Error Correction (FEC) and Packet Filter API + +

+ + [SRT 1.4](https://github.com/Haivision/srt/releases/tag/v1.4.0) sees the introduction of the _packet filter API_. This mechanism allows custom processing to be performed on network packets on the sender side before they are sent, and on the receiver side once received from the network. The API allows users to write their own plugin, thereby extending the SRT protocol's capabilities even further with all kinds of different packet filtering. Users can manipulate the resulting packet filter data in any way, such as for custom encryption, packet inspection, or accessing data before it is sent. + + The first plugin created as an example of what can be achieved with the packet filter API is for Forward Error Correction (FEC) which, in certain use cases, can offer slightly lower latency than Automatic Repeat reQuest (ARQ). This plugin allows three different modes: + + - ARQ only – retransmits lost packets, + - FEC only – provides the overhead needed for FEC recovery on the receiver side, + - FEC and ARQ – retransmits lost packets that FEC fails to recover. + +

+
+ +
+ Connection Bonding + +

+ + Similar to SMPTE-2022-7 over managed networks, Connection Bonding adds seamless stream protection and hitless failover to the SRT protocol. This technology relies on more than one IP network path to prevent disruption to live video streams in the event of network congestion or outages, maintaining continuity of service. + + This is accomplished using the [socket groups](./docs/features/socket-groups.md) introduced in [SRT v1.5](https://github.com/Haivision/srt/releases/tag/v1.5.0). The general concept of socket groups means having a group that contains multiple sockets, where one operation for sending one data signal is applied to the group. Single sockets inside the group will take over this operation and do what is necessary to deliver the signal to the receiver. + + Two modes are supported: + + - [Broadcast](./docs/features/socket-groups.md#1-broadcast) - In *Broadcast* mode, data is sent redundantly over all the member links in a group. If one of the links fails or experiences network jitter and/or packet loss, the missing data will be received over another link in the group. Redundant packets are simply discarded at the receiver side. + + - [Main/Backup](./docs/features/bonding-main-backup.md) - In *Main/Backup* mode, only one (main) link at a time is used for data transmission while other (backup) connections are on standby to ensure the transmission will continue if the main link fails. The goal of Main/Backup mode is to identify a potential link break before it happens, thus providing a time window within which to seamlessly switch to one of the backup links. + +

+
+ +
+ Access Control (Stream ID) + +

+ + Access Control enables the upstream application to assign a Stream ID to individual SRT streams. By using a unique Stream ID, either automatically generated or customized, the upstream application can send multiple SRT streams to a single IP address and UDP port. The Stream IDs can then be used by a receiver to identify and differentiate between ingest streams, apply user password access methods, and in some cases even apply automation based on the naming of the Stream ID. For example, contribution could be sent to a video production workflow and monitoring to a monitoring service. + + For broadcasters, Stream ID is key to replacing RTMP for ingesting video streams, especially HEVC/H.265 content, into cloud service or CDNs that have a single IP socket (address + port) open for incoming video. + +

+
+ +## Getting Started with SRT + +| | | | +|:-----------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------:| +| [The SRT API](./docs#srt-api-documents) | [IETF Internet Draft](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01) | [Sample Apps](./docs#sample-applications) | +| Reference documentation for the SRT library API | The SRT Protocol Internet Draft | Instructions for using test apps (`srt-live-transmit`, `srt-file-transmit`, etc.) | +| [SRT Technical Overview](https://github.com/Haivision/srt/files/2489142/SRT_Protocol_TechnicalOverview_DRAFT_2018-10-17.pdf) | [SRT Deployment Guide](https://www.srtalliance.org/srt-deployment-guide/) | [SRT CookBook](https://srtlab.github.io/srt-cookbook) | +| Early draft technical overview (precursor to the Internet Draft) | A comprehensive overview of the protocol with deployment guidelines | Development notes on the SRT protocol | +| [Innovation Labs Blog](https://medium.com/innovation-labs-blog/tagged/secure-reliable-transport) | [SRTLab YouTube Channel](https://www.youtube.com/channel/UCr35JJ32jKKWIYymR1PTdpA) | [Slack](https://srtalliance.slack.com) | +| The blog on Medium with SRT-related technical articles | Technical YouTube channel with useful videos | Slack channels to get the latest updates and ask questions | + +### Additional Documentation + +- [Why SRT?](./docs/misc/why-srt-was-created.md) - A brief history and rationale for SRT by Marc Cymontkowski. +- [RTMP vs. SRT: Comparing Latency and Maximum Bandwidth](https://www.haivision.com/resources/white-paper/srt-versus-rtmp/) White Paper. +- [Documentation on GitHub](./docs#documentation-overview) with SRT API documents, features decsriptions, etc. +- The SRT Protocol Internet Draft: [Datatracker](https://datatracker.ietf.org/doc/draft-sharabayko-srt/) | [Latest Version](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01) | [Latest Working Copy](https://haivision.github.io/srt-rfc/draft-sharabayko-srt.html) | [GitHub Repo](https://github.com/Haivision/srt-rfc) + +## Build Instructions + +[Linux (Ubuntu/CentOS)](./docs/build/build-linux.md) | [Windows](./docs/build/build-win.md) | [macOS](./docs/build/build-macOS.md) | [iOS](./docs/build/build-iOS.md) | [Android](./docs/build/build-android.md) + +### Requirements + +* C++03 or above compliant compiler. +* CMake 2.8.12 or above as a build system. +* OpenSSL 1.1 to enable encryption, otherwise build with [`-DENABLE_ENCRYPTION=OFF`](./docs/build/build-options.md#enable_encryption). +* Multithreading is provided by either of the following: + * C++11: standard library (`std` by [`-DENABLE_STDCXX_SYNC=ON`](./docs/build/build-options.md#enable_stdcxx_sync) CMake option), + * C++03: Pthreads (for POSIX systems it's built in, for Windows there is a ported library). +* Tcl 8.5 is optional and is used by `./configure` script. Otherwise, use CMake directly. + +### Build Options + +For detailed descriptions of the build system and options, please read the [SRT Build Options](./docs/build/build-options.md) document. + +## Sample Applications and Tools + +The current repo provides [sample applications](./apps) and [code examples](./examples) that demonstrate the usage of the SRT library API. Among them are [`srt-live-transmit`](./apps/srt-live-transmit.cpp), [`srt-file-transmit`](./apps/srt-file-transmit.cpp), and other applications. The respective documentation can be found [here](./docs#sample-applications). Note that all samples are provided for instructional purposes, and should not be used in a production environment. + +The [`srt-xtransmit`](https://github.com/maxsharabayko/srt-xtransmit) utility is actively used for internal testing and performance evaluation. Among other features it supports dummy payload generation, traffic routings, and connection bonding. Additional details are available in the [`srt-xtransmit`](https://github.com/maxsharabayko/srt-xtransmit) repo itself. + +Python tools that might be useful during development are: + +- [`srt-stats-plotting`](https://github.com/mbakholdina/srt-stats-plotting) - A script designed to plot graphs based on SRT `.csv` statistics. +- [`lib-tcpdump-processing`](https://github.com/mbakholdina/lib-tcpdump-processing) - A library designed to process `.pcap(ng)` [tcpdump](https://www.tcpdump.org/) or [Wireshark](https://www.wireshark.org/) trace files and extract SRT packets of interest for further analysis. +- [`lib-srt-utils`](https://github.com/mbakholdina/lib-srt-utils) - A Python library containing supporting code for running SRT tests based on an experiment configuration. + +## Contributing + +Anyone is welcome to contribute. If you decide to get involved, please take a moment to review the guidelines: + +* [SRT Developer's Guide](docs/dev/developers-guide.md) +* [Contributing](CONTRIBUTING.md) +* [Reporting Issues](docs/dev/making-srt-better.md) + +For information on contributing to the [Internet Draft](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01) or to submit issues please go to the following [repo](https://github.com/Haivision/srt-rfc). The repo for contributing in [SRT CookBook](https://srtlab.github.io/srt-cookbook/) can be found [here](https://github.com/SRTLab/srt-cookbook/). + +## License + +By contributing code to the SRT project, you agree to license your contribution under the [MPLv2.0 License](LICENSE). + +## Release History + +- [Release notes](https://github.com/Haivision/srt/releases) +- [SRT versioning](./docs/dev/developers-guide.md#versioning) + + +[^1]: The term “live streaming” refers to continuous data transmission (MPEG-TS or equivalent) with latency management. Live streaming based on segmentation and transmission of files like in the HTTP Live Streaming (HLS) protocol (as described in RFC8216) is not part of this use case. File transmission in either message or buffer mode should be considered in this case. See [Section 7. Best Practices and Configuration Tips for Data Transmission via SRT](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-7) of the Internet Draft for details. Note that SRT is content agnostic, meaning that any type of data can be transmitted via its payload. + + +[appveyor-badge]: https://img.shields.io/appveyor/ci/Haivision/srt/master.svg?label=Windows +[appveyor]: https://ci.appveyor.com/project/Haivision/srt +[travis-badge]: https://img.shields.io/travis/Haivision/srt/master.svg?label=Linux/macOS +[travis]: https://travis-ci.org/Haivision/srt +[license-badge]: https://img.shields.io/badge/License-MPLv2.0-blue + +[lgtm-alerts-badge]: https://img.shields.io/lgtm/alerts/github/Haivision/srt +[lgtm-quality-badge]: https://img.shields.io/lgtm/grade/cpp/github/Haivision/srt +[lgtm-project]: https://lgtm.com/projects/g/Haivision/srt/ + +[codecov-project]: https://codecov.io/gh/haivision/srt +[codecov-badge]: https://codecov.io/gh/haivision/srt/branch/master/graph/badge.svg + +[github releases]: https://github.com/Haivision/srt/releases +[release-badge]: https://img.shields.io/github/release/Haivision/srt.svg + +[debian-badge]: https://badges.debian.net/badges/debian/testing/libsrt1/version.svg +[debian-package]: https://packages.debian.org/testing/libsrt1 diff --git a/cmake_object_lib_support.c b/cmake_object_lib_support.c new file mode 100644 index 0000000..dd1d890 --- /dev/null +++ b/cmake_object_lib_support.c @@ -0,0 +1,9 @@ +// DO NOT DELETE +// This file is needed for Xcode to properly handle CMake OBJECT Libraries +// From docs (https://cmake.org/cmake/help/latest/command/add_library.html#object-libraries): +// +// ... Some native build systems (such as Xcode) may not like targets that have only object files, +// so consider adding at least one real source file to any target that references $. + +// Just a dummy symbol to avoid compiler warnings +int srt_object_lib_dummy = 0; diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..f91e5c1 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,8 @@ +coverage: + status: + project: + default: + target: 40% + threshold: null + patch: false + changes: false diff --git a/configure b/configure new file mode 100644 index 0000000..796e0a1 --- /dev/null +++ b/configure @@ -0,0 +1,268 @@ +#!/usr/bin/tclsh + +# +# SRT - Secure, Reliable, Transport +# Copyright (c) 2018 Haivision Systems Inc. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# This is a general-purpose configure script, which is a user-friendly +# wrapper to call the "cmake" command. + +# There are two options that are handled specifically: +# +# --help: show the list of official options +# --prefix: alias to --cmake-install-prefix + +# The processing done automatically on all options by default is: +# Every option like: +# --long-c++-option +# --cmake-special-option=ON +# Turns into: +# -DLONG_CXX_OPTION=1 +# -DCMAKE_SPECIAL_OPTION=ON +# +# In the configuration file, "configure-data.tcl", you can add +# special processing for options and define explicit options +# in the "::options" dictionary. Explicit options (in contrast +# to "blind" options) have additional properties: +# +# - only those options are mentioned with --help +# - you can pass a value for this option without = character +# - you can specify --disable-option instead of --enable-option=0 +# +# In "configure-data.tcl", beside ::options, you can define "preprocess" and +# "postprocess" procedures. In "preprocess", use ::optval array to modify the +# list of options to be processed further. Additionally in "postprocess" +# procedure you can influence directly the options for "cmake" command in +# ::cmakeopt variable (modifying ::optval in "postprocess" is useless). + +# The idea is that CMakeLists.txt contains things that are highly +# customizable, but no system or option autodetection AWA "sensible +# defaults" are provided. This is done by this script. + + +set here [file dirname $argv0] + +set options "" +set toolchain_changers "" + +source $here/configure-data.tcl + +# Update alias with default alias +dict set alias --prefix --cmake-install-prefix= + +proc resolve opt { + set type arg + set pos [string first $opt =] + if { $pos == -1 } { + set type bool + set mark "" + } else { + set type arg + set mark [string range $opt $pos+1 end] + set opt [string range $opt 0 $pos-1] + } + set var [string toupper [string map {- _ + x} $opt]] + return [list --$opt $var $type $mark] +} + +# Check if a --disable option has its --enable counterpart. If so, +# then just invert the option. +proc resolve_disablers {} { + set enablers "" + set optkeys_len [llength $::optkeys] + for {set pos 0} {$pos < $optkeys_len} {incr pos} { + set opt [lindex $::optkeys $pos] + if { [string match --disable-* $opt] } { + set inverted enable-[string range $opt 10 end] + if { $inverted in [dict keys $::options] } { + lset ::optkeys $pos --$inverted + set val $::optval($opt) + unset ::optval($opt) + if { $val == "" || ![string is boolean $val] } { + set ::optval(--$inverted) 0 + } else { + set ::optval(--$inverted) [expr {!$val}] + } + + puts "NOTE: $opt changed into --$inverted=$::optval(--$inverted)" + } + } + } +} + +foreach {o desc} $options { + lassign [resolve $o] optname optvar opttype optmark + set opt($optname) [list $optvar $opttype $optmark] + set info($optname) $desc +} + + +if { $argv == "--help" || $argv == "-h" } { + puts stderr "Usage: ./configure \[options\]" + puts stderr "OPTIONS:" + foreach o [lsort [array names opt]] { + lassign $opt($o) unu type mark + set imark "" + if { $mark != "" } { + set imark "=$mark" + } + puts stderr "\t$o$imark - $info($o)" + } + + puts stderr "NOTE1: Option list may be incomplete. Refer to variables in CMakeLists.txt" + puts stderr "NOTE2: Non-internal options turn e.g. --enable-c++11 into cmake -DENABLE_CXX11=1" + puts stderr "NOTE3: You can use --disable-x instead of --enable-x=0 for the above options." + + exit 1 +} + +if { [info proc init] != "" } { + init +} + +#parray opt + +set saveopt "" +set optkeys "" + +set dryrun 0 +set type "" + +foreach a $argv { + if { [info exists val] } { unset val } + + if { $saveopt != "" } { + set optval($saveopt) $a + set saveopt "" + continue + } + + if { [string range $a 0 1] != "--" } { + error "Unexpected argument '$a'. Options must start with --" + } + + if { $a == "--dryrun" } { + set dryrun 1 + continue + } + + set type "" + + if { [set a1 [string first = $a]] != -1 } { + # Do not split. Options may include =. + set val [string range $a $a1+1 end] + set a [string range $a 0 $a1-1] + } + + if { [dict exists $::alias $a] } { + set aname [dict get $::alias $a] + if { [string first = $aname] != -1 } { + lassign [split $aname =] a aval + set type arg + } + } + + if { ![info exists opt($a)] } { + #puts stderr "WARNING: Unknown option: $a" + # But still, simply turn the option to assign-based use. + lassign [resolve [string range $a 2 end]] oname var + if { ![info exists val] && $type == "" } { + set type bool + } + } else { + lassign $opt($a) var type + } + + if { $type == "bool" } { + if { ![info exists val] } { + set val 1 + } + set optval($a) $val + } elseif { [info exists val] } { + set optval($a) $val + } else { + set saveopt $a + } + + lappend optkeys $a +} + +if { $saveopt != "" } { + error "Extra unhandled argument: $saveopt" +} + +# Save the original call into config-status.sh + +set ofd [open config-status.sh w] +puts $ofd "#!/bin/bash" +puts -nonewline $ofd "$argv0 " +foreach a $argv { + set len 1 + if {[catch {llength $a} len] || $len > 1 } { + puts -nonewline $ofd "'$a' " + } else { + puts -nonewline $ofd "$a " + } +} +puts $ofd "" +close $ofd +file attributes config-status.sh -permissions +x + +set cmakeopt "" + +resolve_disablers + +if { [info proc preprocess] != "" } { + preprocess +} + +# Check if there were new values added not added to optkeys +foreach a [array names optval] { + if { $a ni $optkeys } { + lappend optkeys $a + } +} + + +foreach a $optkeys { + + if { ![info exists optval($a)] } { + continue ;# user action might have removed it. + } + + if { ![info exists opt($a)] } { + #puts stderr "WARNING: Unknown option: $a" + # But still, simply turn the option to assign-based use. + lassign [resolve [string range $a 2 end]] oname var + if { ![info exists val] && $type == "" } { + set type bool + } + } else { + lassign $opt($a) var type + } + + set val $optval($a) + lappend cmakeopt "-D$var=$val" +} + + +if { [info proc postprocess] != "" } { + postprocess +} + +#puts "VARSPEC: $cmakeopt" + +set cmd [list cmake $here {*}$cmakeopt] +puts "Running: $cmd" +if { !$dryrun} { + if { [catch {exec 2>@stderr >@stdout {*}$cmd} result] } { + puts "CONFIGURE: cmake reported error: $result" + } +} else { + puts "(not really - dry run)" +} diff --git a/configure-data.tcl b/configure-data.tcl new file mode 100644 index 0000000..eace99d --- /dev/null +++ b/configure-data.tcl @@ -0,0 +1,409 @@ +# +# SRT - Secure, Reliable, Transport +# Copyright (c) 2018 Haivision Systems Inc. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# API description: + +# Expected variables: +# - options: dictionary "option-name" : "description" +# if there's '=' in option name, it expects an argument. Otherwise it's boolean. +# - alias: optional, you can make shortcuts to longer named options. Remember to use = in target name. +# +# Optional procedures: +# - preprocess: run before command-line arguments ($argv) are reviewed +# - postprocess: run after options are reviewed and all data filled in +# +# Available variables in postprocess: +# +# - optval (array): contains all option names with their assigned values +# - cmakeopt (scalar): a list of all options for "cmake" command line + +# Options processed here internally, not passed to cmake +set internal_options { + with-compiler-prefix= "set C/C++ toolchains gcc and g++" + with-compiler-type= "compiler type: gcc(default), cc, others simply add ++ for C++" + with-srt-name= "Override srt library name" + with-haicrypt-name= "Override haicrypt library name (if compiled separately)" + with-atomic= "Select implementation for atomics (compiler-intrinsics or sync-mutex)" +} + +# Options that refer directly to variables used in CMakeLists.txt +set cmake_options { + cygwin-use-posix "Should the POSIX API be used for cygwin. Ignored if the system isn't cygwin. (default: OFF)" + enable-c++11 "Should the c++11 parts (srt-live-transmit) be enabled (default: ON, with gcc < 4.7 OFF)" + enable-apps "Should the Support Applications be Built? (default: ON)" + enable-bonding "Enable 'bonding' SRT feature (default: OFF)" + enable-testing "Should developer testing applications be built (default: OFF)" + enable-profile "Should instrument the code for profiling. Ignored for non-GNU compiler. (default: OFF)" + enable-logging "Should logging be enabled (default: ON)" + enable-heavy-logging "Should heavy debug logging be enabled (default: OFF)" + enable-haicrypt-logging "Should logging in haicrypt be enabled (default: OFF)" + enable-shared "Should libsrt be built as a shared library (default: ON)" + enable-static "Should libsrt be built as a static library (default: ON)" + enable-relative-libpath "Should applications contain relative library paths, like ../lib (default: OFF)" + enable-getnameinfo "In-logs sockaddr-to-string should do rev-dns (default: OFF)" + enable-unittests "Enable Unit Tests (will download Google UT) (default: OFF)" + enable-encryption "Should encryption features be enabled (default: ON)" + enable-c++-deps "Extra library dependencies in srt.pc for C language (default: ON)" + use-static-libstdc++ "Should use static rather than shared libstdc++ (default: OFF)" + enable-inet-pton "Set to OFF to prevent usage of inet_pton when building against modern SDKs (default: ON)" + enable-code-coverage "Enable code coverage reporting (default: OFF)" + enable-monotonic-clock "Enforced clock_gettime with monotonic clock on GC CV /temporary fix for #729/ (default: OFF)" + enable-thread-check "Enable #include that implements THREAD_* macros" + enable-stdc++-sync "Use standard C++11 chrono/threads instead of pthread wrapper (default: OFF, on Windows: ON)" + use-openssl-pc "Use pkg-config to find OpenSSL libraries (default: ON)" + openssl-use-static-libs "Link OpenSSL statically (default: OFF)." + use-busy-waiting "Enable more accurate sending times at a cost of potentially higher CPU load (default: OFF)" + use-gnustl "Get c++ library/headers from the gnustl.pc" + enable-sock-cloexec "Enable setting SOCK_CLOEXEC on a socket (default: ON)" + enable-show-project-config "Enables use of ShowProjectConfig() in cmake (default: OFF)" + enable-new-rcvbuffer "Enables the new receiver buffer implementation (default: ON)" + enable-clang-tsa "Enable Clang's Thread-Safety-Analysis (default: OFF)" + atomic-use-srt-sync-mutex "Use mutex to implement atomics (alias: --with-atomic=sync-mutex) (default: OFF)" + + use-enclib "Encryption library to be used: openssl(default), gnutls, mbedtls" + enable-debug=<0,1,2> "Enable debug mode (0=disabled, 1=debug, 2=rel-with-debug)" + pkg-config-executable= "pkg-config executable" + openssl-crypto-library= "OpenSSL: Path to a libcrypto library." + openssl-include-dir= "OpenSSL: Path to includes." + openssl-ssl-library= "OpenSSL: Path to a libssl library." + pthread-include-dir= "PThread: Path to includes" + pthread-library= "PThread: Path to the pthread library." +} + +set options $internal_options$cmake_options + +# Just example. Available in the system. +set alias { + --prefix --cmake-install-prefix= +} + +proc pkg-config args { + return [string trim [exec pkg-config {*}$args]] +} + +proc flagval v { + set out "" + foreach o $v { + lappend out [string trim [string range $o 2 en]] + } + return $out +} + +set haicrypt_name "" +set srt_name "" + +proc preprocess {} { + + # Prepare windows basic path info + set ::CYGWIN 0 + set e [catch {exec uname -o} res] + # We have Cygwin, if uname -o returns "cygwin" and does not fail. + if { !$e && $res == "Cygwin" } { + set ::CYGWIN 1 + puts "CYGWIN DETECTED" + } + + set ::HAVE_LINUX [expr {$::tcl_platform(os) == "Linux"}] + set ::HAVE_DARWIN [expr {$::tcl_platform(os) == "Darwin"}] + + set ::CYGWIN_USE_POSIX 0 + if { "--cygwin-use-posix" in $::optkeys } { + set ::CYGWIN_USE_POSIX 1 + } + + set ::HAVE_WINDOWS 0 + if { $::tcl_platform(platform) == "windows" } { + puts "WINDOWS PLATFORM detected" + set ::HAVE_WINDOWS 1 + } + + if { $::CYGWIN && !$::CYGWIN_USE_POSIX } { + puts "CYGWIN - MINGW enforced" + # Make Cygwin tools see it right, to compile for MinGW + + if { "--with-compiler-prefix" ni $::optkeys } { + set ::optval(--with-compiler-prefix) /bin/x86_64-w64-mingw32- + } + + # Extract drive C: information + set drive_path [exec mount -p | tail -1 | cut {-d } -f 1] + set ::DRIVE_C $drive_path/c + set ::HAVE_WINDOWS 1 + } else { + + # Don't check for Windows, non-Windows parts will not use it. + set ::DRIVE_C C: + } + + # Alias to old name --with-gnutls, which enforces using gnutls instead of openssl + if { [info exists ::optval(--with-gnutls)] } { + unset ::optval(--with-gnutls) + set ::optval(--use-enclib) gnutls + puts "WARNING: --with-gnutls is a deprecated alias to --use-enclib=gnutls, please use the latter one" + } + + # Alias to old name --use-gnutls, which enforces using gnutls instead of openssl + if { [info exists ::optval(--use-gnutls)] } { + unset ::optval(--use-gnutls) + set ::optval(--use-enclib) gnutls + puts "WARNING: --use-gnutls is a deprecated alias to --use-enclib=gnutls, please use the latter one" + } + + if { [info exists ::optval(--with-target-path)] } { + set ::target_path $::optval(--with-target-path) + unset ::optval(--with-target-path) + puts "NOTE: Explicit target path: $::target_path" + } + + if { "--with-srt-name" in $::optkeys } { + set ::srt_name $::optval(--with-srt-name) + unset ::optval(--with-srt-name) + } + + if { "--with-haicrypt-name" in $::optkeys } { + set ::haicrypt_name $::optval(--with-haicrypt-name) + unset ::optval(--with-haicrypt-name) + } + + if { "--with-atomic" in $::optkeys } { + switch -- $::optval(--with-atomic) { + compiler-intrinsics { + } + + sync-mutex { + set ::optval(--atomic-use-srt-sync-mutex) 1 + } + + default { + puts "ERROR: --with-atomic option accepts two values: compiler-intrinsics (default) or sync-mutex" + exit 1 + } + } + + unset ::optval(--with-atomic) + } +} + +proc GetCompilerCommand {} { + # Expect that the compiler was set through: + # --with-compiler-prefix + # --cmake-c[++]-compiler + # (cmake-toolchain-file will set things up without the need to check things here) + + set compiler gcc + if { [info exists ::optval(--with-compiler-type)] } { + set compiler $::optval(--with-compiler-type) + } + + if { [info exists ::optval(--with-compiler-prefix)] } { + set prefix $::optval(--with-compiler-prefix) + return ${prefix}$compiler + } else { + return $compiler + } + + if { [info exists ::optval(--cmake-c-compiler)] } { + return $::optval(--cmake-c-compiler) + } + + if { [info exists ::optval(--cmake-c++-compiler)] } { + return $::optval(--cmake-c++-compiler) + } + + if { [info exists ::optval(--cmake-cxx-compiler)] } { + return $::optval(--cmake-cxx-compiler) + } + + puts "NOTE: Cannot obtain compiler, assuming toolchain file will do what's necessary" + + return "" +} + +proc postprocess {} { + + set iscross 0 + + # Check if there was any option that changed the toolchain. If so, don't apply any autodetection-based toolchain change. + set all_options [array names ::optval] + set toolchain_changed no + foreach changer { + --with-compiler-prefix + --with-compiler-type + --cmake-c-compiler + --cmake-c++-compiler + --cmake-cxx-compiler + --cmake-toolchain-file + } { + if { $changer in $all_options } { + puts "NOTE: toolchain changed by '$changer' option" + set toolchain_changed yes + break + } + } + + set cygwin_posix 0 + if { "--cygwin-use-posix" in $all_options } { + # Will enforce OpenSSL autodetection + set cygwin_posix 1 + } + + if { $toolchain_changed } { + # Check characteristics of the compiler - in particular, whether the target is different + # than the current target. + set compiler_path "" + set target_platform "" + set cmd [GetCompilerCommand] + if { $cmd != "" } { + set gcc_version [exec $cmd -v 2>@1] + set target "" + set compiler_path [file dirname $cmd] + foreach l [split $gcc_version \n] { + if { [string match Target:* $l] } { + set target [lindex $l 1] ;# [0]Target: [1]x86_64-some-things-further + set target_platform [lindex [split $target -] 0] ;# [0]x86_64 [1]redhat [2]linux + break + } + } + + if { $target_platform == "" } { + puts "NOTE: can't obtain target from '[file tail $cmd] -v': $l - ASSUMING HOST compiler" + } else { + if { $target_platform != $::tcl_platform(machine) } { + puts "NOTE: foreign target type detected ($target)" ;# - setting CROSSCOMPILING flag" + #lappend ::cmakeopt "-DHAVE_CROSSCOMPILER=1" + set iscross 1 + } + } + } else { + puts "CONFIGURE: default compiler used" + } + } + + if { $::srt_name != "" } { + lappend ::cmakeopt "-DTARGET_srt=$::srt_name" + } + + if { $::haicrypt_name != "" } { + lappend ::cmakeopt "-DTARGET_haicrypt=$::haicrypt_name" + } + + set have_openssl 0 + if { [lsearch -glob $::optkeys --openssl*] != -1 } { + set have_openssl 1 + } + + set have_gnutls 0 + if { [lsearch -glob $::optkeys --use-gnutls] != -1 } { + set have_gnutls 1 + } + + if { $have_openssl && $have_gnutls } { + puts "NOTE: SSL library is exclusively selectable. Thus, --use-gnutls option will be ignored" + set have_gnutls 0 + } + + if { $have_gnutls } { + lappend ::cmakeopt "-DUSE_GNUTLS=ON" + } + + if {$iscross} { + + proc check-target-path {path} { + puts "Checking path '$path'" + if { [file isdir $path] + && [file isdir $path/bin] + && [file isdir $path/include] + && ([file isdir $path/lib] || [file isdir $path/lib64]) } { + return yes + } + return no + } + + if { ![info exists ::target_path] } { + # Try to autodetect the target path by having the basic 3 directories. + set target_path "" + set compiler_prefix [file dirname $compiler_path] ;# strip 'bin' directory + puts "NOTE: no --with-target-path found, will try to autodetect at $compiler_path" + foreach path [list $compiler_path $compiler_prefix/$target] { + if { [check-target-path $path] } { + set target_path $path + puts "NOTE: target path detected: $target_path" + break + } + } + + if { $target_path == "" } { + puts "ERROR: Can't determine compiler's platform files root path (using compiler command path). Specify --with-target-path." + exit 1 + } + } else { + set target_path $::target_path + # Still, check if correct. + if { ![check-target-path $target_path] } { + puts "ERROR: path in --with-target-path does not contain typical subdirectories" + exit 1 + } + puts "NOTE: Using explicit target path: $target_path" + } + + # Add this for cmake, should it need for something + lappend ::cmakeopt "-DCMAKE_PREFIX_PATH=$target_path" + + # Add explicitly the path for pkg-config + # which lib + if { [file isdir $target_path/lib64/pkgconfig] } { + set ::env(PKG_CONFIG_PATH) $target_path/lib64/pkgconfig + puts "PKG_CONFIG_PATH: Found pkgconfig in lib64 for '$target_path' - using it" + } elseif { [file isdir $target_path/lib/pkgconfig] } { + set ::env(PKG_CONFIG_PATH) $target_path/lib/pkgconfig + puts "PKG_CONFIG_PATH: Found pkgconfig in lib for '$target_path' - using it" + } else { + puts "PKG_CONFIG_PATH: NOT changed, no pkgconfig in '$target_path'" + } + # Otherwise don't set PKG_CONFIG_PATH and we'll see. + } + + set use_brew 0 + if { $::HAVE_DARWIN && !$toolchain_changed } { + set use_brew 1 + } + if { $use_brew } { + foreach item $::cmakeopt { + if { [string first "Android" $item] != -1 } { + set use_brew 0 + break + } + } + } + if { $use_brew } { + if { $have_gnutls } { + # Use gnutls explicitly, as found in brew + set er [catch {exec brew info gnutls} res] + if { $er } { + error "Cannot find gnutls in brew" + } + } else { + # ON Darwin there's a problem with linking against the Mac-provided OpenSSL. + # This must use brew-provided OpenSSL. + # + if { !$have_openssl } { + + set er [catch {exec brew info openssl} res] + if { $er } { + error "You must have OpenSSL installed from 'brew' tool. The standard Mac version is inappropriate." + } + + lappend ::cmakeopt "-DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include" + lappend ::cmakeopt "-DOPENSSL_LIBRARIES=/usr/local/opt/openssl/lib/libcrypto.a" + } + } + } + +} + diff --git a/docs/API/API-functions.md b/docs/API/API-functions.md new file mode 100644 index 0000000..eb410c5 --- /dev/null +++ b/docs/API/API-functions.md @@ -0,0 +1,3362 @@ +# SRT API Functions + +

Library Initialization

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_startup](#srt_startup) | Called at the start of an application that uses the SRT library | +| [srt_cleanup](#srt_cleanup) | Cleans up global SRT resources before exiting an application | +| | | + + +

Creating and Configuring Sockets

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_socket](#srt_socket) | Deprecated | +| [srt_create_socket](#srt_create_socket) | Creates an SRT socket | +| [srt_bind](#srt_bind) | Binds a socket to a local address and port | +| [srt_bind_acquire](#srt_bind_acquire) | Acquires a given UDP socket instead of creating one | +| [srt_getsockstate](#srt_getsockstate) | Gets the current status of the socket | +| [srt_getsndbuffer](#srt_getsndbuffer) | Retrieves information about the sender buffer | +| [srt_close](#srt_close) | Closes the socket or group and frees all used resources | +| | | + +

Connecting

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_listen](#srt_listen) | Sets up the listening state on a socket | +| [srt_accept](#srt_accept) | Accepts a connection; creates/returns a new socket or group ID | +| [srt_accept_bond](#srt_accept_bond) | Accepts a connection pending on any sockets passed in the `listeners` array
of `nlisteners` size | +| [srt_listen_callback](#srt_listen_callback) | Installs/executes a callback hook on a socket created to handle the incoming connection
on a listening socket | +| [srt_connect](#srt_connect) | Connects a socket or a group to a remote party with a specified address and port | +| [srt_connect_bind](#srt_connect_bind) | Same as [`srt_bind`](#srt_bind) then [`srt_connect`](#srt_connect) if called with socket [`u`](#u) | +| [srt_connect_debug](#srt_connect_debug) | Same as [`srt_connect`](#srt_connect)but allows specifying ISN (developers only) | +| [srt_rendezvous](#srt_rendezvous) | Performs a rendezvous connection | +| [srt_connect_callback](#srt_connect_callback) | Installs/executes a callback hook on socket/group [`u`](#u) after connection resolution/failure | +| | | + +

Socket Group Management

+ +Since SRT v1.5.0. + +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [SRT_GROUP_TYPE](#SRT_GROUP_TYPE) | Group types collected in an [`SRT_GROUP_TYPE`](#SRT_GROUP_TYPE) enum | +| [SRT_SOCKGROUPCONFIG](#SRT_SOCKGROUPCONFIG) | Structure used to define entry points for connections for [`srt_connect_group`](#srt_connect_group) | +| [SRT_SOCKGROUPDATA](#SRT_SOCKGROUPDATA) | Most important structure for group member status | +| [SRT_MEMBERSTATUS](#SRT_MEMBERSTATUS) | Enumeration type that defines the state of a member connection in the group | +| [srt_create_group](#srt_create_group) | Creates a new group of type `type` | +| [srt_groupof](#srt_groupof) | Returns the group ID of a socket, or `SRT_INVALID_SOCK` | +| [srt_group_data](#srt_group_data) | Obtains the current member state of the group specified in `socketgroup` | +| [srt_connect_group](#srt_connect_group) | Similar to calling [`srt_connect`](#srt_connect) or [`srt_connect_bind`](#srt_connect_bind)
in a loop for every item in an array. | +| [srt_prepare_endpoint](#srt_prepare_endpoint) | Prepares a default [`SRT_SOCKGROUPCONFIG`](#SRT_SOCKGROUPCONFIG) object as an element of
an array for [`srt_connect_group`](#srt_connect_group) | +| [srt_create_config](#srt_create_config) | Creates a dynamic object for specifying socket options | +| [srt_delete_config](#srt_delete_config) | Deletes the configuration object | +| [srt_config_add](#srt_config_add) | Adds a configuration option to the configuration object | +| | | + +

Options and Properties

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_getpeername](#srt_getpeername) | Retrieves the remote address to which the socket is connected | +| [srt_getsockname](#srt_getsockname) | Extracts the address to which the socket was bound | +| [srt_getsockopt](#srt_getsockopt) | Gets the value of the given socket option (from a socket or a group) | +| [srt_getsockflag](#srt_getsockflag) | Gets the value of the given socket option (from a socket or a group) | +| [srt_setsockopt](#srt_setsockopt) | Sets a value for a socket option in the socket or group | +| [srt_setsockflag](#srt_setsockflag) | Sets a value for a socket option in the socket or group | +| [srt_getversion](#srt_getversion) | Get SRT version value | +| | | + +

Helper Data Types for Transmission

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [SRT_MSGCTRL](#SRT_MSGCTRL) | Used in [`srt_sendmsg2`](#srt_sendmsg) and [`srt_recvmsg2`](#srt_recvmsg2) calls;
specifies some extra parameters | +| | | + +

Transmission

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_send](#srt_send) | Sends a payload to a remote party over a given socket | +| [srt_sendmsg](#srt_sendmsg) | Sends a payload to a remote party over a given socket | +| [srt_sendmsg2](#srt_sendmsg2) | Sends a payload to a remote party over a given socket | +| [srt_recv](#srt_recv) | Extracts the payload waiting to be received | +| [srt_recvmsg](#srt_recvmsg) | Extracts the payload waiting to be received | +| [srt_recvmsg2](#srt_recvmsg2) | Extracts the payload waiting to be received | +| [srt_sendfile](#srt_sendfile) | Function dedicated to sending a file | +| [srt_recvfile](#srt_recvfile) | Function dedicated to receiving a file | +| | | + +

Performance Tracking

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_bstats](#srt_bstats) | Reports the current statistics | +| [srt_bistats](#srt_bistats) | Reports the current statistics | +| | | + +

Asynchronous Operations (Epoll)

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_epoll_create](#srt_epoll_create) | Creates a new epoll container | +| [srt_epoll_add_usock](#srt_epoll_add_usock) | Adds a user socket to a container, or updates an existing socket subscription | +| [srt_epoll_add_ssock](#srt_epoll_add_ssock) | Adds a system socket to a container, or updates an existing socket subscription | +| [srt_epoll_update_usock](#srt_epoll_update_usock) | Adds a user socket to a container, or updates an existing socket subscription | +| [srt_epoll_update_ssock](#srt_epoll_update_ssock) | Adds a system socket to a container, or updates an existing socket subscription | +| [srt_epoll_remove_usock](#srt_epoll_remove_usock) | Removes a specified user socket from an epoll container; clears all readiness states for that socket | +| [srt_epoll_remove_ssock](#srt_epoll_remove_ssock) | Removes a specified system socket from an epoll container; clears all readiness states for that socket | +| [srt_epoll_wait](#srt_epoll_wait) | Blocks the call until any readiness state occurs in the epoll container | +| [srt_epoll_uwait](#srt_epoll_uwait) | Blocks a call until any readiness state occurs in the epoll container | +| [srt_epoll_clear_usocks](#srt_epoll_clear_usocks) | removes all SRT ("user") socket subscriptions from the epoll container identified by [`eid`](#eid) | +| [srt_epoll_set](#srt_epoll_set) | Allows setting or retrieving flags that change the default behavior of the epoll functions | +| [srt_epoll_release](#srt_epoll_release) | Deletes the epoll container | +| | | + +

Logging Control

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_setloglevel](#srt_setloglevel) | Sets the minimum severity for logging | +| [srt_addlogfa](#srt_addlogfa) | Add a functional area (FA), which is an additional filtering mechanism for logging | +| [srt_dellogfa](#srt_dellogfa) | Delete a functional area (FA), which is an additional filtering mechanism for logging | +| [srt_resetlogfa](#srt_resetlogfa) | Reset a functional area (FA), which is an additional filtering mechanism for logging | +| [srt_setloghandler](#srt_setloghandler) | Replaces default standard stream for error logging | +| [srt_setlogflags](#srt_setlogflags) | Allows configuring parts of log information that are not to be passed | +| | | + +

Time Access

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_time_now](#srt_time_now) | Get time in microseconds elapsed since epoch using SRT internal clock
(steady or monotonic clock) | +| [srt_connection_time](#srt_connection_time) | Get connection time in microseconds elapsed since epoch using SRT internal clock
(steady or monotonic clock) | +| [srt_clock_type](#srt_clock_type) | Get the type of clock used internally by SRT | +| | | + +

Diagnostics

+ +| *Function / Structure* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [srt_getlasterror](#srt_getlasterror) | Get the numeric code of the last error | +| [srt_strerror](#srt_strerror) | Returns a string message that represents a given SRT error code and possibly
the `errno` value, if not 0 | +| [srt_getlasterror_str](#srt_getlasterror_str) | Gets the text message for the last error | +| [srt_clearlasterror](#srt_clearlasterror) | Clears the last error | +| [srt_rejectreason_str](#srt_rejectreason_str) | Returns a constant string for the reason of the connection rejected, as per given code ID | +| [srt_setrejectreason](#srt_setrejectreason) | Sets the rejection code on the socket | +| [srt_getrejectreason](#srt_getrejectreason) | Provides a detailed reason for a failed connection attempt | +| | | + +

Rejection Reasons

+ +| *Rejection Reason* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +| [SRT_REJ_UNKNOWN](#SRT_REJ_UNKNOWN) | A fallback value for cases when there was no connection rejected | +| [SRT_REJ_SYSTEM](#SRT_REJ_SYSTEM) | A system function reported a failure | +| [SRT_REJ_PEER](#SRT_REJ_PEER) | The connection has been rejected by peer, but no further details are available | +| [SRT_REJ_RESOURCE](#SRT_REJ_RESOURCE) | A problem with resource allocation (usually memory) | +| [SRT_REJ_ROGUE](#SRT_REJ_ROGUE) | The data sent by one party to another cannot be properly interpreted | +| [SRT_REJ_BACKLOG](#SRT_REJ_BACKLOG) | The listener's backlog has exceeded | +| [SRT_REJ_IPE](#SRT_REJ_IPE) | Internal Program Error | +| [SRT_REJ_CLOSE](#SRT_REJ_CLOSE) | The listener socket received a request as it is being closed | +| [SRT_REJ_VERSION](#SRT_REJ_VERSION) | A party did not satisfy the minimum version requirement that had been set up for a connection | +| [SRT_REJ_RDVCOOKIE](#SRT_REJ_RDVCOOKIE) | Rendezvous cookie collision | +| [SRT_REJ_BADSECRET](#SRT_REJ_BADSECRET) | Both parties have defined a passprhase for connection and they differ | +| [SRT_REJ_UNSECURE](#SRT_REJ_UNSECURE) | Only one connection party has set up a password | +| [SRT_REJ_MESSAGEAPI](#SRT_REJ_MESSAGEAPI) | The value for [`SRTO_MESSAGEAPI`](API-socket-options.md#SRTO_MESSAGEAPI) flag is different on both connection parties | +| [SRT_REJ_FILTER](#SRT_REJ_FILTER) | The [`SRTO_PACKETFILTER`](API-socket-options.md#SRTO_PACKETFILTER) option has been set differently on both connection parties | +| [SRT_REJ_GROUP](#SRT_REJ_GROUP) | The group type or some group settings are incompatible for both connection parties | +| [SRT_REJ_TIMEOUT](#SRT_REJ_TIMEOUT) | The connection wasn't rejected, but it timed out | +| | | + +

Error Codes

+ +| *Error Code* | *Description* | +|:------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------- | +[`SRT_EUNKNOWN`](#srt_eunknown) | Internal error when setting the right error code | +[`SRT_SUCCESS`](#srt_success) | The value set when the last error was cleared and no error has occurred since then | +[`SRT_ECONNSETUP`](#srt_econnsetup) | General setup error resulting from internal system state | +[`SRT_ENOSERVER`](#srt_enoserver) | Connection timed out while attempting to connect to the remote address | +[`SRT_ECONNREJ`](#srt_econnrej) | Connection has been rejected | +[`SRT_ESOCKFAIL`](#srt_esockfail) | An error occurred when trying to call a system function on an internally used UDP socket | +[`SRT_ESECFAIL`](#srt_esecfail) | A possible tampering with the handshake packets was detected, or encryption request
wasn't properly fulfilled. | +[`SRT_ESCLOSED`](#srt_esclosed) | A socket that was vital for an operation called in blocking mode has been closed
during the operation | +[`SRT_ECONNFAIL`](#srt_econnfail) | General connection failure of unknown details | +[`SRT_ECONNLOST`](#srt_econnlost) | The socket was properly connected, but the connection has been broken | +[`SRT_ENOCONN`](#srt_enoconn) | The socket is not connected | +[`SRT_ERESOURCE`](#srt_eresource) | System or standard library error reported unexpectedly for unknown purpose | +[`SRT_ETHREAD`](#srt_ethread) | System was unable to spawn a new thread when requried | +[`SRT_ENOBUF`](#srt_enobuf) | System was unable to allocate memory for buffers | +[`SRT_ESYSOBJ`](#srt_esysobj) | System was unable to allocate system specific objects | +[`SRT_EFILE`](#srt_efile) | General filesystem error (for functions operating with file transmission) | +[`SRT_EINVRDOFF`](#srt_einvrdoff) | Failure when trying to read from a given position in the file | +[`SRT_ERDPERM`](#srt_erdperm) | Read permission was denied when trying to read from file | +[`SRT_EINVWROFF`](#srt_einvwroff) | Failed to set position in the written file | +[`SRT_EWRPERM`](#srt_ewrperm) | Write permission was denied when trying to write to a file | +[`SRT_EINVOP`](#srt_einvop) | Invalid operation performed for the current state of a socket | +[`SRT_EBOUNDSOCK`](#srt_eboundsock) | The socket is currently bound and the required operation cannot be performed in this state | +[`SRT_ECONNSOCK`](#srt_econnsock) | The socket is currently connected and therefore performing the required operation is not possible | +[`SRT_EINVPARAM`](#srt_einvparam) | Call parameters for API functions have some requirements that were not satisfied | +[`SRT_EINVSOCK`](#srt_einvsock) | The API function required an ID of an entity (socket or group) and it was invalid | +[`SRT_EUNBOUNDSOCK`](#srt_eunboundsock) | The operation to be performed on a socket requires that it first be explicitly bound | +[`SRT_ENOLISTEN`](#srt_enolisten) | The socket passed for the operation is required to be in the listen state | +[`SRT_ERDVNOSERV`](#srt_erdvnoserv) | The required operation cannot be performed when the socket is set to rendezvous mode | +[`SRT_ERDVUNBOUND`](#srt_erdvunbound) | An attempt was made to connect to a socket set to rendezvous mode that was not first bound | +[`SRT_EINVALMSGAPI`](#srt_einvalmsgapi) | The function was used incorrectly in the message API | +[`SRT_EINVALBUFFERAPI`](#srt_einvalbufferapi) | The function was used incorrectly in the stream (buffer) API | +[`SRT_EDUPLISTEN`](#srt_eduplisten) | The port tried to be bound for listening is already busy | +[`SRT_ELARGEMSG`](#srt_elargemsg) | Size exceeded | +[`SRT_EINVPOLLID`](#srt_einvpollid) | The epoll ID passed to an epoll function is invalid | +[`SRT_EPOLLEMPTY`](#srt_epollempty) | The epoll container currently has no subscribed sockets | +[`SRT_EASYNCFAIL`](#srt_easyncfail) | General asynchronous failure (not in use currently) | +[`SRT_EASYNCSND`](#srt_easyncsnd) | Sending operation is not ready to perform | +[`SRT_EASYNCRCV`](#srt_easyncrcv) | Receiving operation is not ready to perform | +[`SRT_ETIMEOUT`](#srt_etimeout) | The operation timed out | +[`SRT_ECONGEST`](#srt_econgest) | With [`SRTO_TSBPDMODE`](API-socket-options.md#SRTO_TSBPDMODE) and [`SRTO_TLPKTDROP`](API-socket-options.md#SRTO_TLPKTDROP) set to true,
some packets were dropped by sender | +[`SRT_EPEERERR`](#srt_epeererr) | Receiver peer is writing to a file that the agent is sending | +| | | + + + +## Library Initialization + +* [srt_startup](#srt_startup) +* [srt_cleanup](#srt_cleanup) + + +### srt_startup +``` +int srt_startup(void); +``` + +This function shall be called at the start of an application that uses the SRT +library. It provides all necessary platform-specific initializations, sets up +global data, and starts the SRT GC thread. If this function isn't explicitly +called, it will be called automatically when creating the first socket. However, +relying on this behavior is strongly discouraged. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------------- | +| 0 | Successfully run, or already started | +| 1 | This is the first startup, but the GC thread is already running | +| -1 | Failed | +| | | + +| Errors | | +|:----------------------------- |:--------------------------------------------------------------- | +| [`SRT_ECONNSETUP`](#srt_econnsetup) | With error code set, reported when required system resource(s) failed to initialize.
This is currently used only on Windows to report a failure from `WSAStartup`. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_cleanup +``` +int srt_cleanup(void); +``` + +This function cleans up all global SRT resources and shall be called just before +exiting the application that uses the SRT library. This cleanup function will still +be called from the C++ global destructor, if not called by the application, although +relying on this behavior is strongly discouraged. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------------- | +| 0 | A possibility to return other values is reserved for future use | +| | | + +**IMPORTANT**: Note that the startup/cleanup calls have an instance counter. +This means that if you call [`srt_startup`](#srt_startup) multiple times, you need to call the +`srt_cleanup` function exactly the same number of times. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + + + +## Creating and Configuring Sockets + +* [srt_socket](#srt_socket) +* [srt_create_socket](#srt_create_socket) +* [srt_bind](#srt_bind) +* [srt_bind_acquire](#srt_bind_acquire) +* [srt_getsockstate](#srt_getsockstate) +* [srt_getsndbuffer](#srt_getsndbuffer) +* [srt_close](#srt_close) + + +### srt_socket +``` +SRTSOCKET srt_socket(int af, int type, int protocol); +``` + +Old and deprecated version of [`srt_create_socket`](#srt_create_socket). All arguments are ignored. + +**NOTE** changes with respect to UDT version: + +* In UDT (and SRT versions before 1.4.2) the `af` parameter was specifying the +socket family (`AF_INET` or `AF_INET6`). This is now not required; this parameter +is decided at the call of [`srt_connect`](#srt_connect) or [`srt_bind`](#srt_bind). + +* In UDT the `type` parameter was used to specify the file or message mode +using `SOCK_STREAM` or `SOCK_DGRAM` symbols (with the latter being misleading, +as the message mode has nothing to do with UDP datagrams and it's rather +similar to the SCTP protocol). In SRT these two modes are available by setting +[`SRTO_TRANSTYPE`](API-socket-options.md#SRTO_TRANSTYPE). The default is `SRTT_LIVE`. If, however, you set +[`SRTO_TRANSTYPE`](API-socket-options.md#SRTO_TRANSTYPE) to `SRTT_FILE` for file mode, you can then leave the +[`SRTO_MESSAGEAPI`](API-socket-options.md#SRTO_MESSAGEAPI) option as false (default), which corresponds to "stream" mode +(TCP-like), or set it to true, which corresponds to "message" mode (SCTP-like). + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_create_socket +``` +SRTSOCKET srt_create_socket(); +``` + +Creates an SRT socket. + +Note that socket IDs always have the `SRTGROUP_MASK` bit clear. + +| Returns | | +|:----------------------------- |:------------------------------------------------------- | +| Socket ID | A valid socket ID on success | +| `SRT_INVALID_SOCK` | (`-1`) on error | +| | | + +| Errors | | +|:----------------------------- |:------------------------------------------------------------ | +| [`SRT_ENOBUF`](#srt_enobuf) | Not enough memory to allocate required resources . | +| | | + +**NOTE:** This is probably a design flaw (:warning:   **BUG?**). Usually underlying system +errors are reported by [`SRT_ECONNSETUP`](#srt_econnsetup). + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + + +--- + +### srt_bind +``` +int srt_bind(SRTSOCKET u, const struct sockaddr* name, int namelen); +``` + +Binds a socket to a local address and port. Binding specifies the local network +interface and the UDP port number to be used for the socket. When the local +address is a form of `INADDR_ANY`, then it's bound to all interfaces. When the +port number is 0, then the port number will be system-allocated if necessary. + +This call is obligatory for a listening socket before calling [`srt_listen`](#srt_listen) +and for rendezvous mode before calling [`srt_connect`](#srt_connect); otherwise it's +optional. For a listening socket it defines the network interface and the port where +the listener should expect a call request. In the case of rendezvous mode (when the +socket has set [`SRTO_RENDEZVOUS`](API-socket-options.md#SRTO_RENDEZVOUS) to +true both parties connect to one another) it defines the network interface and port +from which packets will be sent to the peer, and the port to which the peer is +expected to send packets. + +For a connecting socket this call can set up the outgoing port to be used in the +communication. It is allowed that multiple SRT sockets share one local outgoing +port, as long as [`SRTO_REUSEADDR`](API-socket-options.md#SRTO_REUSEADDRS) +is set to *true* (default). Without this call the port will be automatically +selected by the system. + +**NOTE**: This function cannot be called on a socket group. If you need to +have the group-member socket bound to the specified source address before +connecting, use [`srt_connect_bind`](#srt_connect_bind) for that purpose. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| `SRT_ERROR` | (-1) on error, otherwise 0 | +| | | + +| Errors | | +|:---------------------------------------- |:-------------------------------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket passed as [`u`](#u) designates no valid socket | +| [`SRT_EINVOP`](#srt_einvop) | Socket already bound | +| [`SRT_ECONNSETUP`](#srt_econnsetup) | Internal creation of a UDP socket failed | +| [`SRT_ESOCKFAIL`](#srt_esockfail) | Internal configuration of a UDP socket (`bind`, `setsockopt`) failed | +| [`SRT_EBINDCONFLICT`](#srt_ebindconflict)| Binding specification conflicts with existing one | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_bind_acquire + +``` +int srt_bind_acquire(SRTSOCKET u, UDPSOCKET udpsock); +``` + +A version of [`srt_bind`](#srt_bind) that acquires a given UDP socket instead of creating one. + +The UDP socket being acquired MUST NOT be a [connected socket](https://man7.org/linux/man-pages/man2/connect.2.html) +(not associated with the socket name of a peer), +because SRT needs to be able to set the destination address by itself. +See [#2178](https://github.com/Haivision/srt/issues/2178) for more information. + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_getsockstate + +``` +SRT_SOCKSTATUS srt_getsockstate(SRTSOCKET u); +``` + +Gets the current status of the socket. Possible states are: + +| State | Description | +|:----------------------------------------------- |:----------------------------------------------------------------- | +| `SRTS_INIT` | Created, but not bound. | +| `SRTS_OPENED` | Created and bound, but not in use yet. | +| `SRTS_LISTENING` | Socket is in listening state. | +| `SRTS_CONNECTING` | The connect operation was initiated, but not yet finished. This may also mean that it has timed out;
you can only know that after getting a socket error report from [`srt_epoll_wait`](#srt_epoll_wait). In blocking mode
it's not possible because [`srt_connect`](#srt_connect) does not return until the socket is connected or failed due
to timeout or interrupted call. | +| `SRTS_CONNECTED` | The socket is connected and ready for transmission. | +| `SRTS_BROKEN` | The socket was connected, but the connection was broken. | +| `SRTS_CLOSING` | The socket may still be open and active, but closing is requested, so no further operations will
be accepted (active operations will be completed before closing) | +| `SRTS_CLOSED` | The socket has been closed, but not yet removed by the GC thread. | +| `SRTS_NONEXIST` | The specified number does not correspond to a valid socket. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_getsndbuffer + +``` +int srt_getsndbuffer(SRTSOCKET sock, size_t* blocks, size_t* bytes); +``` + +Retrieves information about the sender buffer. + +**Arguments**: + +* `sock`: Socket to test +* `blocks`: Written information about buffer blocks in use +* `bytes`: Written information about bytes in use + +This function can be used for diagnostics. It is especially useful when the +socket needs to be closed asynchronously. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_close + +``` +int srt_close(SRTSOCKET u); +``` + +Closes the socket or group and frees all used resources. Note that underlying +UDP sockets may be shared between sockets, so these are freed only with the +last user closed. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| `SRT_ERROR` | (-1) in case of error, otherwise 0 | +| | | + +| Errors | | +|:------------------------------- |:----------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket [`u`](#u) indicates no valid socket ID | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + + + +## Connecting + +* [srt_listen](#srt_listen) +* [srt_accept](#srt_accept) +* [srt_accept_bond](#srt_accept_bond) +* [srt_listen_callback](#srt_listen_callback) +* [srt_connect](#srt_connect) +* [srt_connect_bind](#srt_connect_bind) +* [srt_connect_debug](#srt_connect_debug) +* [srt_rendezvous](#srt_rendezvous) +* [srt_connect_callback](#srt_connect_callback) + +### srt_listen +``` +int srt_listen(SRTSOCKET u, int backlog); +``` + +This sets up the listening state on a socket with a backlog setting that +defines how many sockets may be allowed to wait until they are accepted +(excessive connection requests are rejected in advance). + +The following important options may change the behavior of the listener +socket and the [`srt_accept`](#srt_accept) function: + +* [`srt_listen_callback`](#srt_listen_callback) installs a user function that will +be called before [`srt_accept`](#srt_accept) can happen +* [`SRTO_GROUPCONNECT`](API-socket-options.md#SRTO_GROUPCONNECT) option allows +the listener socket to accept group connections + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| `SRT_ERROR` | (-1) in case of error, otherwise 0. | +| | | + +| Errors | | +|:--------------------------------------- |:-------------------------------------------------------------------------------------------- | +| [`SRT_EINVPARAM`](#srt_einvparam) | Value of `backlog` is 0 or negative. | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket [`u`](#u) indicates no valid SRT socket. | +| [`SRT_EUNBOUNDSOCK`](#srt_eunboundsock) | [`srt_bind`](#srt_bind) has not yet been called on that socket. | +| [`SRT_ERDVNOSERV`](#srt_erdvnoserv) | [`SRTO_RENDEZVOUS`](API-socket-options.md#SRTO_RENDEZVOUS) flag is set to true on specified socket. | +| [`SRT_EINVOP`](#srt_einvop) | Internal error (should not happen when [`SRT_EUNBOUNDSOCK`](#srt_eunboundsock) is reported). | +| [`SRT_ECONNSOCK`](#srt_econnsock) | The socket is already connected. | +| [`SRT_EDUPLISTEN`](#srt_eduplisten) | The address used in [`srt_bind`](#srt_bind) by this socket is already occupied by another listening socket.
Binding multiple sockets to one IP address and port is allowed, as long as
[`SRTO_REUSEADDR`](API-socket-options.md#SRTO_REUSEADDRS) is set to true, but only one of these sockets can be set up as a listener. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_accept + +``` +SRTSOCKET srt_accept(SRTSOCKET lsn, struct sockaddr* addr, int* addrlen); +``` + +Accepts a pending connection, then creates and returns a new socket or +group ID that handles this connection. The group and socket can be +distinguished by checking the `SRTGROUP_MASK` bit on the returned ID. + +* `lsn`: the listener socket previously configured by [`srt_listen`](#srt_listen) +* `addr`: the IP address and port specification for the remote party +* `addrlen`: INPUT: size of `addr` pointed object. OUTPUT: real size of the +returned object + +**NOTE:** `addr` is allowed to be NULL, in which case it's understood that the +application is not interested in the address from which the connection originated. +Otherwise `addr` should specify an object into which the address will be written, +and `addrlen` must also specify a variable to contain the object size. Note also +that in the case of group connection only the initial connection that +establishes the group connection is returned, together with its address. As +member connections are added or broken within the group, you can obtain this +information through [`srt_group_data`](#srt_group_data) or the data filled by +[`srt_sendmsg2`](#srt_sendmsg) and [`srt_recvmsg2`](#srt_recvmsg2). + +If the `lsn` listener socket is configured for blocking mode +([`SRTO_RCVSYN`](API-socket-options.md#SRTO_RCVSYN) set to true, default), +the call will block until the incoming connection is ready. Otherwise, the +call always returns immediately. The `SRT_EPOLL_IN` epoll event should be +checked on the `lsn` socket prior to calling this function in that case. + +If the pending connection is a group connection (initiated on the peer side by +calling the connection function using a group ID, and permitted on the listener +socket by the [`SRTO_GROUPCONNECT`](API-socket-options.md#SRTO_GROUPCONNECT) +flag), then the value returned is a group ID. This function then creates a new +group, as well as a new socket for this connection, that will be added to the +group. Once the group is created this way, further connections within the same +group, as well as sockets for them, will be created in the background. The +[`SRT_EPOLL_UPDATE`](#SRT_EPOLL_UPDATE) event is raised on the `lsn` socket when +a new background connection is attached to the group, although it's usually for +internal use only. + +| Returns | | +|:----------------------------- |:----------------------------------------------------------------------- | +| socket/group ID | On success, a valid SRT socket or group ID to be used for transmission. | +| `SRT_ERROR` | (-1) on failure | +| | | + +| Errors | | +|:--------------------------------- |:----------------------------------------------------------------------- | +| [`SRT_EINVPARAM`](#srt_einvparam) | NULL specified as `addrlen`, when `addr` is not NULL | +| [`SRT_EINVSOCK`](#srt_einvsock) | `lsn` designates no valid socket ID. | +| [`SRT_ENOLISTEN`](#srt_enolisten) | `lsn` is not set up as a listener ([`srt_listen`](#srt_listen) not called). | +| [`SRT_EASYNCRCV`](#srt_easyncrcv) | No connection reported so far. This error is reported only in the non-blocking mode | +| [`SRT_ESCLOSED`](#srt_esclosed) | The `lsn` socket has been closed while the function was blocking the call. Including when the socket was closed just at the
moment when a connection was made (i.e., the socket got closed during processing) | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_accept_bond + +``` +SRTSOCKET srt_accept_bond(const SRTSOCKET listeners[], int nlisteners, int msTimeOut); +``` + +Accepts a pending connection, like [`srt_accept`](#srt_accept), but pending on any of the +listener sockets passed in the `listeners` array of `nlisteners` size. + +**Arguments**: + +* `listeners`: array of listener sockets (all must be setup by [`srt_listen`](#srt_listen)) +* `nlisteners`: size of the `listeners` array +* `msTimeOut`: timeout in [ms] or -1 to block forever + +This function is for blocking mode only - for non-blocking mode you should simply +call [`srt_accept`](#srt_accept) on the first listener socket that reports readiness, +and this function is actually a friendly shortcut that uses waiting on epoll and +[`srt_accept`](#srt_accept) internally. This function supports an important use +case for accepting a group connection, for which every member connection is expected +to be established over a different listener socket. + +Note that there's no special set of settings required or rejected for this function. +Group-member connections for the same group can always be established over various +different listener sockets when all those listeners are hosted by the same application. +The group management is global for the application, so a connection reporting in for +an already connected group gets discovered, and the connection will be handled in the +background. This occurs regardless of which listener socket the call was made to, +as long as the connection is accepted according to any additional conditions. + +This function has nothing to do with the groups. You can use it in any case when +you have one service that accepts connections to multiple endpoints. Note also +that the settings as to whether listeners should accept or reject socket or group +connections should be applied to the listener sockets appropriately prior to +calling this function. + +| Returns | | +|:----------------------------- |:---------------------------------------------------------------------- | +| SRT socket
group ID | On success, a valid SRT socket or group ID to be used for transmission | +| `SRT_ERROR` | (-1) on failure | +| | | + +| Errors | | +|:--------------------------------- |:------------------------------------------------------------ | +| [`SRT_EINVPARAM`](#srt_einvparam) | NULL specified as `listeners` or `nlisteners` < 1 | +| [`SRT_EINVSOCK`](#srt_einvsock) | Any socket in `listeners` designates no valid socket ID. Can also mean *Internal Error* when
an error occurred while creating an accepted socket (:warning:   **BUG?**) | +| [`SRT_ENOLISTEN`](#srt_enolisten) | Any socket in `listeners` is not set up as a listener ([`srt_listen`](#srt_listen) not called, or the listener socket
has already been closed) | +| [`SRT_ETIMEOUT`](#srt_etimeout) | No connection reported on any listener socket as the timeout has been reached. This error is only
reported when `msTimeOut` is not -1 | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_listen_callback + +``` +int srt_listen_callback(SRTSOCKET lsn, srt_listen_callback_fn* hook_fn, void* hook_opaque); +``` + +This call installs a callback hook, which will be executed on a socket that is +automatically created to handle the incoming connection on the listening socket +(and is about to be returned by [`srt_accept`](#srt_accept)), but before the +connection has been accepted. + +**Arguments**: + +* `lsn`: Listening socket where you want to install the callback hook +* `hook_fn`: The callback hook function pointer +* `hook_opaque`: The pointer value that will be passed to the callback function + +| Returns | | +|:----------------------------- |:---------------------------------------------------------- | +| 0 | Successful | +| -1 | Error | +| | | + +| Errors | | +|:--------------------------------- |:----------------------------------------- | +| [`SRT_EINVPARAM`](#srt_einvparam) | Reported when `hook_fn` is a null pointer | +| | | + +The callback function has the signature as per this type definition: +``` +typedef int srt_listen_callback_fn(void* opaque, SRTSOCKET ns, int hs_version + const struct sockaddr* peeraddr, const char* streamid); +``` + +The callback function gets the following parameters passed: + +* `opaque`: The pointer passed as `hook_opaque` when registering +* `ns`: The freshly created socket to handle the incoming connection +* `hs_version`: The handshake version (usually 5, pre-1.3 versions of SRT use 4) +* `peeraddr`: The address of the incoming connection +* `streamid`: The value set to [`SRTO_STREAMID`](API-socket-options.md#SRTO_STREAMID) option set on the peer side + +Note that SRT versions that use handshake version 4 are incapable of using +any extensions, such as `streamid`. However they do support encryption. +Note also that the SRT version isn't extracted at this point. However you can +prevent connections with versions that are too old by using the +[`SRTO_MINVERSION`](API-socket-options.md#SRTO_MINVERSION) option. + +The callback function is given an opportunity to: + +* use the passed information (`streamid` and peer address) to decide + what to do with this connection +* alter any options on the socket, which could not be set properly + beforehand on the listening socket to be derived by the accepted socket, + and won't be allowed to be altered after the socket is returned by + [`srt_accept`](#srt_accept) + +Note that normally the returned socket has already set all derived options from +the listener socket. The moment when this callback is called is when the conclusion +handshake has been already received from the caller party, but not yet interpreted +(the `streamid` field is extracted from it prematurely). When, for example, you set +a passphrase on the socket at this point, the Key Material processing will happen +against this passphrase, after the callback function is finished. + +The callback function shall return 0, if the connection is to be accepted. +If you return -1, **or** if the function throws an exception, this will be +understood as a request to reject the incoming connection. In this case the +about-to-be-accepted socket will be silently deleted and [`srt_accept`](#srt_accept) +will not report it. Note that in case of non-blocking mode the epoll bits for +read-ready on the listener socket will not be set if the connection is rejected, +including when rejected from this user function. + +**IMPORTANT**: This function is called in the receiver worker thread, which +means that it must do its checks and operations as quickly as possible. Every +delay you create in this function will burden the processing of the incoming data +on the associated UDP socket. In the case of a listener socket this means the +listener socket itself and every socket accepted off this listener socket. +Avoid any extensive search operations. It is best to cache in memory whatever +database you have to check against the data received in `streamid` or `peeraddr`. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_connect + +``` +int srt_connect(SRTSOCKET u, const struct sockaddr* name, int namelen); +``` + +Connects a socket or a group to a remote party with a specified address and port. + +**Arguments**: + +* [`u`](#u): can be an SRT socket or SRT group, both freshly created and not yet + used for any connection, except possibly [`srt_bind`](#srt_bind) on the socket +* `name`: specification of the remote address and port +* `namelen`: size of the object passed by `name` + +**NOTES:** + +1. The socket used here may be [bound by `srt_bind`](#srt_bind) before connecting, +or binding and connection can be done in one function ([`srt_connect_bind`](#srt_connect_bind)), +such that it uses a predefined network interface or local outgoing port. This is optional +in the case of a caller-listener arrangement, but obligatory for a rendezvous arrangement. +If not used, the binding will be done automatically to `INADDR_ANY` (which binds on all +interfaces) and port 0 (which makes the system assign the port automatically). + +2. This function is used for both connecting to the listening peer in a caller-listener +arrangement, and calling the peer in rendezvous mode. For the latter, the +[`SRTO_RENDEZVOUS`](API-socket-options.md#SRTO_RENDEZVOUS) flag must be set +to true prior to calling this function, and binding, as described in #1, +is in this case obligatory (see `SRT_ERDVUNBOUND` below). + +3. When [`u`](#u) is a group, then this call can be done multiple times, each time +for another member connection, and a new member SRT socket will be created +automatically for every call of this function. + +4. If you want to connect a group to multiple links at once and use blocking +mode, you might want to use [`srt_connect_group`](#srt_connect_group) instead. +This function also allows you to use additional settings, available only for groups. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| `SRT_ERROR` | (-1) in case of error | +| 0 | In case when used for [`u`](#u) socket | +| Socket ID | Created for connection for [`u`](#u) group | +| | | + +| Errors | | +|:------------------------------------- |:----------------------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket [`u`](#u) indicates no valid socket ID | +| [`SRT_ERDVUNBOUND`](#srt_erdvunbound) | Socket [`u`](#u) is in rendezvous mode, but it wasn't bound (see note #2) | +| [`SRT_ECONNSOCK`](#srt_econnsock) | Socket [`u`](#u) is already connected | +| [`SRT_ECONNREJ`](#srt_econnrej) | Connection has been rejected | +| [`SRT_ENOSERVER`](#srt_enoserver) | Connection has been timed out (see [`SRTO_CONNTIMEO`](API-socket-options.md#SRTO_CONNTIMEO)) | +| [`SRT_ESCLOSED`](#srt_esclosed) | The socket [`u`](#u) has been closed while the function was blocking the call | +| | | + +If the `u` socket is configured for blocking mode (when +[`SRTO_RCVSYN`](API-socket-options.md#SRTO_RCVSYN) is set to true, default), +the call will block until the connection succeeds or fails. The "early" errors +[`SRT_EINVSOCK`](#srt_einvsock), [`SRT_ERDVUNBOUND`](#srt_erdvunbound) and +[`SRT_ECONNSOCK`](#srt_econnsock) are reported in both modes immediately. Other +errors are "late" failures and can only be reported in blocking mode. + +In non-blocking mode, a successful connection can be recognized by the +`SRT_EPOLL_OUT` epoll event flag and a "late" failure by the `SRT_EPOLL_ERR` +flag. Note that the socket state in the case of a failed connection remains +`SRTS_CONNECTING` in that case. + +In the case of "late" failures you can additionally call +[`srt_getrejectreason`](#srt_getrejectreason) to get detailed error +information. Note that in blocking mode only for the `SRT_ECONNREJ` error +this function may return any additional information. In non-blocking +mode a detailed "late" failure cannot be distinguished, and therefore it +can also be obtained from this function. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_connect_bind + +``` +int srt_connect_bind(SRTSOCKET u, const struct sockaddr* source, + const struct sockaddr* target, int len); +``` + +This function does the same as first [`srt_bind`](#srt_bind) then +[`srt_connect`](#srt_connect), if called with [`u`](#u) being a socket. +If [`u`](#u) is a group, then it will execute [`srt_bind`](#srt_bind) +first on the automatically created socket for the connection. + +**Arguments**: + +* [`u`](#u): Socket or group to connect +* `source`: Address to bind [`u`](#u) to +* `target`: Address to connect +* `len`: size of the original structure of `source` and `target` + +| Returns | | +|:----------------------------- |:-------------------------------------------------------- | +| `SRT_ERROR` | (-1) in case of error | +| 0 | In case when used for [`u`](#u) socket | +| Socket ID | Created for connection for [`u`](#u) group | +| | | + +| Errors | | +|:---------------------------------------- |:-------------------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket passed as [`u`](#u) designates no valid socket | +| [`SRT_EINVOP`](#srt_einvop) | Socket already bound | +| [`SRT_ECONNSETUP`](#srt_econnsetup) | Internal creation of a UDP socket failed | +| [`SRT_ESOCKFAIL`](#srt_esockfail) | Internal configuration of a UDP socket (`bind`, `setsockopt`) failed | +| [`SRT_ERDVUNBOUND`](#srt_erdvunbound) | Internal error ([`srt_connect`](#srt_connect) should not report it after [`srt_bind`](#srt_bind) was called) | +| [`SRT_ECONNSOCK`](#srt_econnsock) | Socket [`u`](#u) is already connected | +| [`SRT_ECONNREJ`](#srt_econnrej) | Connection has been rejected | +| [`SRT_EBINDCONFLICT`](#srt_ebindconflict)| Binding specification conflicts with existing one | +| | | + + +**IMPORTANT**: It's not allowed to bind and connect the same socket to two +different families (that is, both `source` and `target` must be `AF_INET` or +`AF_INET6`), although you may mix links over IPv4 and IPv6 in one group. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_connect_debug + +``` +int srt_connect_debug(SRTSOCKET u, const struct sockaddr* name, int namelen, int forced_isn); +``` + +This function is for developers only and can be used for testing. It does the +same thing as [`srt_connect`](#srt_connect), with the exception that it allows +specifying the Initial Sequence Number for data transmission. Normally this value +is generated randomly. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_rendezvous +``` +int srt_rendezvous(SRTSOCKET u, const struct sockaddr* local_name, int local_namelen, + const struct sockaddr* remote_name, int remote_namelen); +``` +Performs a rendezvous connection. This is a shortcut for doing bind locally, +setting the [`SRTO_RENDEZVOUS`](API-socket-options.md#SRTO_RENDEZVOUS) option +to true, and doing [`srt_connect`](#srt_connect). + +**Arguments**: + +* [`u`](#u): socket to connect +* `local_name`: specifies the local network interface and port to bind +* `remote_name`: specifies the remote party's IP address and port + +| Returns | | +|:----------------------------- |:-------------------------------------------------------- | +| `SRT_ERROR` | (-1) in case of error, otherwise 0 | +| | | + +| Errors | | +|:------------------------------------- |:-------------------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket passed as [`u`](#u) designates no valid socket | +| [`SRT_EINVOP`](#srt_einvop) | Socket already bound | +| [`SRT_ECONNSETUP`](#srt_econnsetup) | Internal creation of a UDP socket failed | +| [`SRT_ESOCKFAIL`](#srt_esockfail) | Internal configuration of a UDP socket (`bind`, `setsockopt`) failed | +| [`SRT_ERDVUNBOUND`](#srt_erdvunbound) | Internal error ([`srt_connect`](#srt_connect) should not report it after [`srt_bind`](#srt_bind) was called) | +| [`SRT_ECONNSOCK`](#srt_econnsock) | Socket [`u`](#u) is already connected | +| [`SRT_ECONNREJ`](#srt_econnrej) | Connection has been rejected | +| | | + +**IMPORTANT**: Establishing a rendezvous connection to two different families is not +allowed (that is, both `local_name` and `remote_name` must be `AF_INET` or `AF_INET6`). + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_connect_callback +``` +int srt_connect_callback(SRTSOCKET u, srt_connect_callback_fn* hook_fn, void* hook_opaque); +``` + +This call installs a callback hook, which will be executed on a given [`u`](#u) +socket or all member sockets of a [`u`](#u) group, just after a pending connection +in the background has been resolved and the connection has failed. Note that this +function is not guaranteed to be called if the [`u`](#u) socket is set to blocking +mode ([`SRTO_RCVSYN`](API-socket-options.md#SRTO_RCVSYN) option set to true). +It is guaranteed to be called when a socket is in non-blocking mode, or when you +use a group. + +This function is mainly intended to be used with group connections. Note that even +if you use a group connection in blocking mode, after the group is considered +connected the member connections still continue in background. Also, when some +connections are still pending and others have failed, the blocking call for +[`srt_connect_group`](#srt_connect_group) will not exit until at least one of +them succeeds or all fail - in such a case those failures also happen only in +the background, while the connecting function blocks until all connections are +resolved. When all links fail, you will only get a general error code for the +group. This mechanism allows you to get individual errors for particular member +connection failures. + +**Arguments**: + +* [`u`](#u): Socket or group that will be used for connecting and for which the hook is installed +* `hook_fn`: The callback hook function pointer +* `hook_opaque`: The pointer value that will be passed to the callback function + + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| 0 | Successful | +| -1 | Error | +| | | + +| Errors | | +|:---------------------------------- |:------------------------------------------| +| [`SRT_EINVPARAM`](#srt_einvparam) | Reported when `hook_fn` is a null pointer | +| | | + + +The callback function signature has the following type definition: + +``` +typedef void srt_connect_callback_fn(void* opaq, SRTSOCKET ns, int errorcode, const struct sockaddr* peeraddr, int token); +``` + +**Arguments**: + +* `opaq`: The pointer passed as `hook_opaque` when registering +* `ns`: The socket for which the connection process was resolved +* [`errorcode`](#error-codes): The error code, same as for [`srt_connect`](#srt_connect) for blocking mode +* `peeraddr`: The target address passed to [`srt_connect`](#srt_connect) call +* `token`: The token value, if it was used for group connection, otherwise -1 + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + + + +## Socket Group Management + + * [SRT_GROUP_TYPE](#SRT_GROUP_TYPE) + * [SRT_SOCKGROUPCONFIG](#SRT_SOCKGROUPCONFIG) + * [SRT_SOCKGROUPDATA](#SRT_SOCKGROUPDATA) + * [SRT_MEMBERSTATUS](#SRT_MEMBERSTATUS) + +### SRT_GROUP_TYPE + +The following group types are collected in an [`SRT_GROUP_TYPE`](#SRT_GROUP_TYPE) enum: + +* `SRT_GTYPE_BROADCAST`: broadcast type, all links are actively used at once; +* `SRT_GTYPE_BACKUP`: backup type, idle links take over connection on disturbance. + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### SRT_SOCKGROUPCONFIG + +This structure is used to define entry points for connections for the +[`srt_connect_group`](#srt_connect_group) function: + +``` +typedef struct SRT_GroupMemberConfig_ +{ + SRTSOCKET id; + struct sockaddr_storage srcaddr; + struct sockaddr_storage peeraddr; + uint16_t weight; + SRT_SOCKOPT_CONFIG* config; + int errorcode; + int token; +} SRT_SOCKGROUPCONFIG; +``` + +where: + +* `id`: member socket ID (filled back as output) +* `srcaddr`: address to which `id` should be bound +* `peeraddr`: address to which `id` should be connected +* `weight`: the weight parameter for the link (group-type dependent) +* `config`: the configuration object, if used (see [`srt_create_config()`](#srt_create_config)) +* [`errorcode`](#error-codes): status of the connecting operation +* `token`: An integer value unique for every connection, or -1 if unused + +The `srt_prepare_endpoint` sets these fields to default values. After that +you can change the value of `weight` and `config` and `token` fields. The +`weight` parameter's meaning is dependent on the group type: + +* BROADCAST: not used +* BACKUP: positive value of link priority (the greater, the more preferred) + +In any case, the allowed value for `weight` is between 0 and 32767. + +The `config` parameter is used to provide options to be set separately on a socket +for a particular connection (see [`srt_create_config()`](#srt_create_config)). + +The `token` value is intended to allow the application to more easily identify +a particular connection. If you don't use it and leave the default value of -1, +the library will set a unique value for the next connection (a 32-bit unsigned +number that will overflow by itself; the default value will be skipped). +The application can also set a unique value by itself and keep the same +value for the same connection. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### SRT_SOCKGROUPDATA + +The most important structure for the group member status is [`SRT_SOCKGROUPDATA`](#SRT_SOCKGROUPDATA): + +```c++ +typedef struct SRT_SocketGroupData_ +{ + SRTSOCKET id; + struct sockaddr_storage peeraddr; + SRT_SOCKSTATUS sockstate; + uint16_t weight; + SRT_MEMBERSTATUS memberstate; + int result; + int token; +} SRT_SOCKGROUPDATA; +``` + +where: + +* `id`: member socket ID +* `peeraddr`: address to which `id` should be connected +* `sockstate`: current connection status (see [`srt_getsockstate`](#srt_getsockstate) +* `weight`: current weight value set on the link +* `memberstate`: current state of the member (see below) +* `result`: result of the operation (if this operation recently updated this structure) +* `token`: A token value set for that connection (see [`SRT_SOCKGROUPCONFIG`](#SRT_SOCKGROUPCONFIG)) + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### SRT_MEMBERSTATUS + +The enumeration type that defines the state of a member +connection in a group: + +* `SRT_GST_PENDING`: The connection is in progress, so the socket +is not currently being used for transmission, even potentially, +and still has a chance to fail and transit into `SRT_GST_BROKEN` +without turning into `SRT_GST_IDLE` + +* `SRT_GST_IDLE`: The connection is established and ready to +take over transmission, but it's not used for transmission at +the moment. This state may last for a short moment in the case of +broadcast group. In backup group this state +defines a backup link that is ready to take over when the +currently active (running) link becomes unstable. + +* `SRT_GST_RUNNING`: The connection is established and at least +one packet has already been sent or received over it. + +* `SRT_GST_BROKEN`: The connection was broken. Broken connections are not to be +revived. Note also that it is only possible to see this state if it is read by +[`srt_sendmsg2`](#srt_sendmsg) or [`srt_recvmsg2`](#srt_recvmsg2) just after +the link failure has been detected. Otherwise, the broken link simply +disappears from the member list. + +Note that internally the member state is separate for sending and receiving. If +the `memberstate` field of [`SRT_SOCKGROUPDATA`](#SRT_SOCKGROUPDATA) is +`SRT_GST_RUNNING`, it means that this is the state in at least one +direction, while in the other direction it may be `SRT_GST_IDLE`. In all +other cases the states should be the same in both directions. + +States should normally start with `SRT_GST_PENDING` and then turn into +`SRT_GST_IDLE`. Once a new link is used for sending data, the state becomes +`SRT_GST_RUNNING`. In the case of the `SRT_GTYPE_BACKUP` type group, if a link +is in the `SRT_GST_RUNNING` state, but another link is chosen to remain +as the only active one, this link will be "silenced" (its state will +become `SRT_GST_IDLE`). + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### Functions to Be Used on Groups + + * [srt_create_group](#srt_create_group) + * [srt_groupof](#srt_groupof) + * [srt_group_data](#srt_group_data) + * [srt_connect_group](#srt_connect_group) + * [srt_prepare_endpoint](#srt_prepare_endpoint) + * [srt_create_config](#srt_create_config) + * [srt_delete_config](#srt_delete_config) + * [srt_config_add](#srt_config_add) + +#### srt_create_group + +``` +SRTSOCKET srt_create_group(SRT_GROUP_TYPE type); +``` + +Creates a new group of type `type`. Is typically called on the +caller side to be next used for connecting to a remote SRT listener. +The group ID is of the same domain as the socket ID, with the exception that +the `SRTGROUP_MASK` bit is set on it, unlike for socket ID. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| `SRTSOCKET` | Group SRT socket ID. | +| `SRT_INVALID_SOCK` | On error or if bonding API is disabled. | +| | | + + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +#### srt_groupof + +``` +SRTSOCKET srt_groupof(SRTSOCKET member); +``` + +Retrieves the group SRT socket ID that corresponds to the member socket ID `member`. + + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| `SRTSOCKET` | Corresponding group SRT socket ID of the member socket. | +| `SRT_INVALID_SOCK` | The socket doesn't exist, it is not a member of any grou, or bonding API is disabled. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +#### srt_group_data + +``` +int srt_group_data(SRTSOCKET socketgroup, SRT_SOCKGROUPDATA output[], size_t* inoutlen); +``` + +**Arguments**: + +* `socketgroup` an existing socket group ID +* `output` points to an output array +* `inoutlen` points to a variable that stores the size of the `output` array, + and is set to the filled array's size + +This function obtains the current member state of the group specified in +`socketgroup`. The `output` should point to an array large enough to hold all +the elements. The `inoutlen` should point to a variable initially set to the size +of the `output` array. The current number of members will be written back to `inoutlen`. + +If the size of the `output` array is enough for the current number of members, +the `output` array will be filled with group data and the function will return +the number of elements filled. Otherwise the array will not be filled and +`SRT_ERROR` will be returned. + +This function can be used to get the group size by setting `output` to `NULL`, +and providing `socketgroup` and `inoutlen`. + +| Returns | | +|:----------------------------- |:-------------------------------------------------- | +| # of elements | The number of data elements filled, on success | +| -1 | Error | +| | | + + +| Errors | | +|:---------------------------------- |:--------------------------------------------------------- | +| [`SRT_EINVPARAM`](#srt_einvparam) | Reported if `socketgroup` is not an existing group ID. Or if bonding API is disabled. | +| [`SRT_ELARGEMSG`](#srt_elargemsg) | Reported if `inoutlen` if less than the size of the group | +| | | + + +| in:output | in:inoutlen | returns | out:output | out:inoutlen | Error | +|:---------:|:--------------:|:------------:|:----------:|:------------:|:---------------------------------:| +| NULL | NULL | -1 | NULL | NULL | [`SRT_EINVPARAM`](#srt_einvparam) | +| NULL | ptr | 0 | NULL | group.size() | ✖️ | +| ptr | NULL | -1 | ✖️ | NULL | [`SRT_EINVPARAM`](#srt_einvparam) | +| ptr | ≥ group.size | group.size() | group.data | group.size | ✖️ | +| ptr | < group.size | -1 | ✖️ | group.size | [`SRT_ELARGEMSG`](#srt_elargemsg) | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +#### srt_connect_group + +``` +int srt_connect_group(SRTSOCKET group, + SRT_SOCKGROUPCONFIG name [], int arraysize); +``` + +This function does almost the same as calling [`srt_connect`](#srt_connect) or +[`srt_connect_bind`](#srt_connect_bind) (when the source was specified for +[`srt_prepare_endpoint`](#srt_prepare_endpoint)) in a loop for every item specified +in the `name` array. However if blocking mode is being used, the first call to +[`srt_connect`](#srt_connect) would block until the connection is established, +whereas this function blocks until any of the specified connections is established. + +If the group nonblocking mode is set ([`SRTO_RCVSYN`](API-socket-options.md#SRTO_RCVSYN) +option), there's no difference, except that the [`SRT_SOCKGROUPCONFIG`](#SRT_SOCKGROUPCONFIG) +structure allows adding extra configuration data used by groups. Note also that +this function accepts only groups, not sockets. + +The elements of the `name` array need to be prepared with the use of the +[`srt_prepare_endpoint`](#srt_prepare_endpoint) function. Note that it is +**NOT** required that every target address specified is of the same family. + +Return value and errors in this function are the same as in [`srt_connect`](#srt_connect), +although this function reports success when at least one connection has +succeeded. If none has succeeded, this function reports an [`SRT_ECONNLOST`](#srt_econnlost) +error. Particular connection states can be obtained from the `name` +array upon return from the [`errorcode`](#error-codes) field. + +The fields of [`SRT_SOCKGROUPCONFIG`](#SRT_SOCKGROUPCONFIG) structure have the following meaning: + +**Input**: + +* `id`: unused, should be -1 (default when created by [`srt_prepare_endpoint`](#srt_prepare_endpoint)) +* `srcaddr`: address to bind before connecting, if specified (see below for details) +* `peeraddr`: target address to connect +* `weight`: weight value to be set on the link +* `config`: socket options to be set on the socket before connecting +* [`errorcode`](#error-codes): unused, should be [`SRT_SUCCESS`](#srt_success) (default) +* `token`: An integer value unique for every connection, or -1 if unused + +**Output**: + +* `id`: The socket created for that connection (-1 if failed to create) +* `srcaddr`: unchanged +* `peeraddr`: unchanged +* `weight`: unchanged +* `config`: unchanged (the object should be manually deleted upon return) +* [`errorcode`](#error-codes): status of connection for that link ([`SRT_SUCCESS`](#srt_success) if succeeded) +* `token`: same as in input, or a newly created token value if input was -1 + +| Returns | | +|:----------------------------- |:-------------------------------------------------- | +| `SRT_SOCKET` | The socket ID of the first connected member. | +| -1 | Error | +| | | + + +| Errors | | +|:---------------------------------- |:--------------------------------------------------------- | +| [`SRT_EINVPARAM`](#srt_einvparam) | Reported if `socketgroup` is not an existing group ID. Or if bonding API is disabled. | +| [`SRT_ECONNLOST`](#srt_econnlost) | Reported if none of member sockets has connected. | +| | | + +The procedure of connecting for every connection definition specified +in the `name` array is performed the following way: + +1. The socket for this connection is first created + +2. Socket options derived from the group are set on that socket. + +3. If `config` is not NULL, configuration options stored there are set on that socket. + +4. If source address is specified (that is `srcaddr` value is **not** +default empty, as described in [`SRT_SOCKGROUPCONFIG`](#SRT_SOCKGROUPCONFIG), +then the binding operation is done on the socket (see [`srt_bind`](#srt_bind)). + +5. The socket is added to the group as a member. + +6. The socket is connected to the target address, as specified +in the `peeraddr` field. + +During this process there can be errors at any stage. There are two +possibilities as to what may happen in this case: + +1. If creation of a new socket has failed, which may only happen due to +problems with system resources, then the whole loop is interrupted and no +further items in the array are processed. All sockets that got created until +then, and for which the connection attempt has at least successfully started, +remain group members, although the function will return immediately with an +error status (that is, without waiting for the first successful connection). If +your application wants to do any partial recovery from this situation, it can +only use the epoll mechanism to wait for readiness. + +2. In any other case, if an error occurs at any stage of the above process, the +processing is interrupted for this very array item only, the socket used for it +is immediately closed, and the processing of the next elements continues. In the case +of a connection process, it also passes two stages - parameter check and the process +itself. Failure at the parameter check breaks this process, while if the check +passes, this item is considered correctly processed, even if the connection +attempt is going to fail later. If this function is called in blocking mode, +it then blocks until at least one connection reports success, or if all of them +fail. The status of connections that continue in the background after this function +exits can then be checked by [`srt_group_data`](#srt_group_data). + +As member socket connections are running in the background, for determining +if a particular connection has succeeded or failed it is recommended +to use [`srt_connect_callback`](#srt_connect_callback). In this case the +`token` callback function parameter will be the same as the `token` value used +for the particular item in the `name` connection table. + +The `token` value doesn't have any limitations except that the -1 value is +a "trap representation", that is, when set on input it will make the internals +define a unique value for the `token`. Your application can also set unique values, +in which case the `token` value will be preserved. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +#### srt_prepare_endpoint + +``` +SRT_SOCKGROUPCONFIG srt_prepare_endpoint(const struct sockaddr* src /*nullable*/, + const struct sockaddr* dst, int namelen); +``` + +This function prepares a default [`SRT_SOCKGROUPCONFIG`](#SRT_SOCKGROUPCONFIG) object as an element +of the array you can prepare for [`srt_connect_group`](#srt_connect_group) function, filled with +additional data: + +**Arguments**: + +* `src`: address to which the newly created socket should be bound +* `dst`: address to which the newly created socket should connect +* `namelen`: size of both `src` and `dst` + +The following fields are set by this function: + +* `id`: -1 (unused for input) +* `srcaddr`: default empty (see below) or copied from `src` +* `peeraddr`: copied from `dst` +* `weight`: 0 +* `config`: `NULL` +* [`errorcode`](#error-codes): [`SRT_SUCCESS`](#srt_success) + +The default empty `srcaddr` is set the following way: + +* `ss_family` set to the same value as `dst->sa_family` +* empty address (`INADDR_ANY` for IPv4 and `in6addr_any` for IPv6) +* port number 0 + +If `src` is not NULL, then `srcaddr` is copied from `src`. Otherwise +it will remain as default empty. + +The `dst` parameter is obligatory. If `src` parameter is not NULL, +then both `dst` and `src` must have the same value of `sa_family`. + +Note though that this function has no possibility of reporting errors - these +would be reported only by [`srt_connect_group`](#srt_connect_group), separately +for every individual connection, and the status can be obtained from +the [`errorcode`](#error-codes) field. + +Note that the `errorcode` field of the `SRT_SOCKGROUPCONFIG` returned would be set to `SRT_EINVOP` +if the bonding API is disabled (`ENABLE_BONDING=OFF`). + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +#### srt_create_config + +``` +SRT_SOCKOPT_CONFIG* srt_create_config(); +``` + +Creates a dynamic object for specifying the socket options. You can add options +to be set on the socket by [`srt_config_add`](#srt_config_add) and then mount this +object into the `config` field in [`SRT_SOCKGROUPCONFIG`](#SRT_SOCKGROUPCONFIG) +object for that particular connection. After the object is no longer needed, you +should delete it using [`srt_delete_config`](#srt_delete_config). + +| Returns | | +|:----------------------------- |:------------------------------------------------------------------ | +| Pointer | The pointer to the created object (memory allocation errors apply) | +| NULL | If bonding API is disabled. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +#### srt_delete_config + +``` +void srt_delete_config(SRT_SOCKOPT_CONFIG* c); +``` + +Deletes the configuration object. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +#### srt_config_add + +``` +int srt_config_add(SRT_SOCKOPT_CONFIG* c, SRT_SOCKOPT opt, void* val, int len); +``` + +Adds a configuration option to the configuration object. + +Parameters have meanings similar to [`srt_setsockflag`](#srt_setsockflag). Note +that not every option is allowed to be set this way. However, the option (if allowed) +isn't checked if it doesn't violate other preconditions. This will be checked when +the option is being set on the socket, which may fail as a part of the connection +process done by [`srt_connect_group`](#srt_connect_group). + +This function should be used when this option must be set individually on a socket +and differently for a particular link. If you need to set some option the same way +on every socket, you should instead set this option on the whole group. + +The following options are allowed to be set on the member socket: + +* [`SRTO_SNDBUF`](API-socket-options.md#SRTO_SNDBUF): Allows for larger sender buffer for slower links +* [`SRTO_RCVBUF`](API-socket-options.md#SRTO_RCVBUF): Allows for larger receiver buffer for longer recovery +* [`SRTO_UDP_RCVBUF`](API-socket-options.md#SRTO_UDP_RCVBUF): UDP receiver buffer, if this link has a big flight window +* [`SRTO_UDP_SNDBUF`](API-socket-options.md#SRTO_UDP_SNDBUF): UDP sender buffer, if this link has a big flight window +* [`SRTO_SNDDROPDELAY`](API-socket-options.md#SRTO_SNDDROPDELAY): When particular link tends to drop too eagerly +* [`SRTO_NAKREPORT`](API-socket-options.md#SRTO_NAKREPORT): If you don't want NAKREPORT to work for this link +* [`SRTO_CONNTIMEO`](API-socket-options.md#SRTO_CONNTIMEO): If you want to give more time to connect on this link +* [`SRTO_LOSSMAXTTL`](API-socket-options.md#SRTO_LOSSMAXTTL): If this link tends to suffer from UDP reordering +* [`SRTO_PEERIDLETIMEO`](API-socket-options.md#SRTO_PEERIDLETIMEO): If you want to be more tolerant for temporary outages +* [`SRTO_GROUPSTABTIMEO`](API-socket-options.md#SRTO_GROUPSTABTIMEO): To set ACK jitter tolerance per individual link + + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| 0 | Success | +| -1 | Failure | +| | | + +| Errors | | +|:---------------------------------- |:--------------------------------------------------------------------- | +| [`SRT_EINVPARAM`](#srt_einvparam) | This option is not allowed to be set on a socket being a group member. Or if bonding API is disabled. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + + + +## Options and Properties + +* [srt_getpeername](#srt_getpeername) +* [srt_getsockname](#srt_getsockname) +* [srt_getsockopt, srt_getsockflag](#srt_getsockopt-srt_getsockflag) +* [srt_setsockopt, srt_setsockflag](#srt_setsockopt-srt_setsockflag) +* [srt_getversion](#srt_getversion) + +**NOTE**: For more information, see [SRT API Socket Options, Getting and Setting Options](API-socket-options.md#getting-and-setting-options). + +### srt_getpeername +``` +int srt_getpeername(SRTSOCKET u, struct sockaddr* name, int* namelen); +``` + +Retrieves the remote address to which the socket is connected. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| `SRT_ERROR` | (-1) in case of error, otherwise 0 | +| | | + +| Errors | | +|:------------------------------- |:------------------------------------------------------------------------ | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket [`u`](#u) indicates no valid socket ID | +| [`SRT_ENOCONN`](#srt_enoconn) | Socket [`u`](#u) isn't connected, so there's no remote address to return | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_getsockname +``` +int srt_getsockname(SRTSOCKET u, struct sockaddr* name, int* namelen); +``` + +Extracts the address to which the socket was bound. Although you should know +the address(es) that you have used for binding yourself, this function can be +useful for extracting the local outgoing port number when it was specified as 0 +with binding for system autoselection. With this function you can extract the +port number after it has been autoselected. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| `SRT_ERROR` | (-1) in case of error, otherwise 0 | +| | | + +| Errors | | +|:------------------------------- |:---------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket [`u`](#u) indicates no valid socket ID | +| [`SRT_ENOCONN`](#srt_enoconn) | Socket [`u`](#u) isn't bound, so there's no local address to return
(:warning:   **BUG?** It should rather be [`SRT_EUNBOUNDSOCK`](#srt_eunboundsock)) | +| | | + +Example + +```c++ +sockaddr_storage name; +int namelen = sizeof sockaddr_storage; +int res = srt_getsockname(m_listener_sock, (sockaddr*) &name, &namelen); +// IPv4: namelen == sockaddr_in. +// IPv6: namelen == sockaddr_in6. +if (res < 0) { + std::cerr << "Error " << srt_getlasterror_str() << '\n'; +} +``` + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_getsockopt +### srt_getsockflag + +```c++ +int srt_getsockopt(SRTSOCKET u, int level /*ignored*/, SRT_SOCKOPT opt, void* optval, int* optlen); +int srt_getsockflag(SRTSOCKET u, SRT_SOCKOPT opt, void* optval, int* optlen); +``` + +Gets the value of the given socket option (from a socket or a group). + +The first version ([`srt_getsockopt`](#srt_getsockopt)) follows the BSD socket +API convention, although the "level" parameter is ignored. The second version +([`srt_getsockflag`](#srt_getsockflag)) omits the "level" parameter completely. + +Options correspond to various data types (see [API-socket-options.md](./API-socket-options.md)). +A variable `optval` of the appropriate data type has to be passed. +The integer value of `optlen` should originally contain the size of the `optval` type provided; +on return, it will be set to the size of the value returned. +For most options, it will be the size of an integer. Some options, however, use types `bool`, `int64_t`, `C string`, etc. +(see [API-socket-options.md](./API-socket-options.md#sockopt_types)). + +The application is responsible for allocating sufficient memory space as defined and pointed to by `optval`. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| `SRT_ERROR` | (-1) in case of error, otherwise 0 | +| | | + +| Errors | | +|:-------------------------------- |:---------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket [`u`](#u) indicates no valid socket ID | +| [`SRT_EINVOP`](#srt_einvop) | Option `opt` indicates no valid option | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- +### srt_setsockopt +### srt_setsockflag + +```c++ +int srt_setsockopt(SRTSOCKET u, int level /*ignored*/, SRT_SOCKOPT opt, const void* optval, int optlen); +int srt_setsockflag(SRTSOCKET u, SRT_SOCKOPT opt, const void* optval, int optlen); +``` + +Sets a value for a socket option in the socket or group. + +The first version ([`srt_setsockopt`](#srt_setsockopt)) follows the BSD socket +API convention, although the "level" parameter is ignored. The second version +([`srt_setsockflag`](#srt_setsockflag)) omits the "level" parameter completely. + +Options correspond to various data types, so you need to know what data type is +assigned to a particular option, and to pass a variable of the appropriate data +type with the option value to be set. + +Please note that some of the options can only be set on sockets or only on +groups, although most of the options can be set on the groups so that they +are then derived by the member sockets. + +| Returns | | +|:----------------------------- |:----------------------------------------------- | +| `SRT_ERROR` | (-1) in case of error, otherwise 0 | +| | | + +| Errors | | +|:----------------------------------- |:--------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket [`u`](#u) indicates no valid socket ID | +| [`SRT_EINVPARAM`](#srt_einvparam) | Option `opt` indicates no valid option | +| [`SRT_EBOUNDSOCK`](#srt_eboundsock) | Tried to set an option with PRE_BIND restriction on a bound socket. | +| [`SRT_ECONNSOCK`](#srt_econnsock) | Tried to set an option with PRE_BIND or PRE restriction on a socket in connecting/listening/connected state. | +| | | + +**NOTE*: Various other errors may result from problems when setting a +specific option (see option description in [API-socket-options.md](./API-socket-options.md) for details). + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_getversion + +``` +uint32_t srt_getversion(); +``` + +Get SRT version value. The version format in hex is 0xXXYYZZ for x.y.z in human +readable form, where x = ("%d", (version>>16) & 0xff), etc. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| SRT Version | Unsigned 32-bit integer | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + + + +## Helper Data Types for Transmission + +* [SRT_MSGCTRL](#SRT_MSGCTRL) + +**NOTE:** There might be a difference in terminology used in [Internet Draft](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01) and current documentation. +Please consult [Data Transmission Modes](https://tools.ietf.org/html/draft-sharabayko-srt-01#section-4.2) +and [Best Practices and Configuration Tips for Data Transmission via SRT](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-7) +sections of the Internet Draft additionally. The current section is going to be reworked accordingly. + +### SRT_MSGCTRL + +The [`SRT_MSGCTRL`](#SRT_MSGCTRL) structure: + +```c++ +typedef struct SRT_MsgCtrl_ +{ + int flags; // Left for future + int msgttl; // TTL for a message, default -1 (no TTL limitation) + int inorder; // Whether a message is allowed to supersede a partially lost one. Unused in stream and live mode + int boundary; // 0:mid pkt, 1(01b):end of frame, 2(11b):complete frame, 3(10b): start of frame + int64_t srctime; // Source time, in microseconds since SRT internal clock epoch + int32_t pktseq; // Sequence number of the first packet in received message (unused for sending) + int32_t msgno; // Message number (output value for both sending and receiving) + SRT_SOCKGROUPDATA* grpdata; // Pointer to group data array + size_t grpdata_size; // Size of the group array +} SRT_MSGCTRL; +``` + +The [`SRT_MSGCTRL`](#SRT_MSGCTRL) structure is used in [`srt_sendmsg2`](#srt_sendmsg) +and [`srt_recvmsg2`](#srt_recvmsg2) calls and specifies some special extra parameters: + +- `flags`: [IN, OUT]. RESERVED FOR FUTURE USE (should be 0). This is +intended to specify some special options controlling the details of how the +called function should work. + +- `msgttl`: [IN]. In **message** and **live mode** only, specifies the TTL for +sending messages (in `[ms]`). Not used for receiving messages. If this value +is not negative, it defines the maximum time up to which this message should +stay scheduled for sending. If TTL has expired, the message sending and further retransmissions are discarded, even +if it has never been sent so far. + +- `inorder`: [IN]. In **message mode** only, specifies that sent messages should +be extracted by the receiver in the order of sending. This can be meaningful if +a packet loss has happened, and a particular message must wait for retransmission +so that it can be reassembled and then delivered. When this flag is false, the +message can be delivered even if there are any previous messages still waiting +for completion. + +- `boundary`: RESERVED FOR FUTURE USE. Intended to be used in a special mode +when you are allowed to send or retrieve a part of the message. + +- `srctime`: + - [OUT] Receiver only. Specifies the time when the packet was intended to be +delivered to the receiving application (in microseconds since SRT clock epoch). + - [IN] Sender only. Specifies the application-provided timestamp to be associated +with the packet. If not provided (specified as 0), the current time of +SRT internal clock is used. + - For details on how to use `srctime` please refer to the (Time Access)[#time-access] section. + +- `pktseq`: Receiver only. Reports the sequence number for the packet carrying +out the payload being returned. If the payload is carried out by more than one +UDP packet, only the sequence of the first one is reported. Note that in +**live mode** there's always one UDP packet per message. + +- `msgno`: Message number that can be sent by both sender and receiver, +although it is required that this value remain monotonic in subsequent send calls. +Normally message numbers start with 1 and increase with every message sent. + +- `grpdata` and `grpdata_size`: Pointer and size of the group array. For single +socket connections these values should remain NULL and 0 respectively. When you +call [`srt_sendmsg2`](#srt_sendmsg) or [`srt_recvmsg2`](#srt_recvmsg2) function +for a group, you should pass an array here so that you can retrieve the status of +particular member sockets. If you pass an array that is too small, your `grpdata_size` +field will be rewritten with the current number of members, but without filling in +the array. For details, see the [SRT Connection Bonding: Quick Start](../features/bonding-intro.md) and +[SRT Connection Bonding: Socket Groups](../features/socket-groups.md) documents. + +**Helpers for [`SRT_MSGCTRL`](#SRT_MSGCTRL):** + +``` +void srt_msgctrl_init(SRT_MSGCTRL* mctrl); +const SRT_MSGCTRL srt_msgctrl_default; +``` + +Helpers for getting an object of [`SRT_MSGCTRL`](#SRT_MSGCTRL) type ready to use. +The first is a function that fills the object with default values. The second is +a constant object and can be used as a source for assignment. Note that you cannot +pass this constant object into any of the API functions because they require it +to be mutable, as they use some fields to output values. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + + + +## Transmission + +* [srt_send, srt_sendmsg, srt_sendmsg2](#srt_send-srt_sendmsg-srt_sendmsg2) +* [srt_recv, srt_recvmsg, srt_recvmsg2](#srt_recv-srt_recvmsg-srt_recvmsg2) +* [srt_sendfile, srt_recvfile](#srt_sendfile-srt_recvfile) + +**NOTE:** There might be a difference in terminology used in [Internet Draft](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01) and current documentation. +Please consult [Data Transmission Modes](https://tools.ietf.org/html/draft-sharabayko-srt-01#section-4.2) +and [Best Practices and Configuration Tips for Data Transmission via SRT](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-7) +sections of the Internet Draft additionally. The current section is going to be reworked accordingly. + + +### srt_send +### srt_sendmsg +### srt_sendmsg2 + +``` +int srt_send(SRTSOCKET u, const char* buf, int len); +int srt_sendmsg(SRTSOCKET u, const char* buf, int len, int ttl/* = -1*/, int inorder/* = false*/); +int srt_sendmsg2(SRTSOCKET u, const char* buf, int len, SRT_MSGCTRL *mctrl); +``` + +Sends a payload to a remote party over a given socket. + +**Arguments**: + +* [`u`](#u): Socket used to send. The socket must be connected for this operation. +* `buf`: Points to the buffer containing the payload to send. +* `len`: Size of the payload specified in `buf`. +* `ttl`: Time (in `[ms]`) to wait for a successful delivery. See description of +the [`SRT_MSGCTRL::msgttl`](#SRT_MSGCTRL) field. +* `inorder`: Required to be received in the order of sending. See +[`SRT_MSGCTRL::inorder`](#SRT_MSGCTRL). +* `mctrl`: An object of [`SRT_MSGCTRL`](#SRT_MSGCTRL) type that contains extra +parameters, including `ttl` and `inorder`. + +The way this function works is determined by the mode set in options, and it has +specific requirements: + +1. In **file/stream mode**, the payload is byte-based. You are not required to +know the size of the data, although they are only guaranteed to be received +in the same byte order. + +2. In **file/message mode**, the payload that you send using this function is +a single message that you intend to be received as a whole. In other words, a +single call to this function determines a message's boundaries. + +3. In **live mode**, you are only allowed to send up to the length of +`SRTO_PAYLOADSIZE`, which can't be larger than 1456 bytes (1316 default). + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| Size | Size of the data sent, if successful | +| `SRT_ERROR` | In case of error (-1) | +| | | + +**NOTE**: Note that in **file/stream mode** the returned size may be less than `len`, +which means that it didn't send the whole contents of the buffer. You would need to +call this function again with the rest of the buffer next time to send it completely. +In both **file/message** and **live mode** the successful return is always equal to `len`. + +| Errors | | +|:--------------------------------------------- |:------------------------------------------------------------------------------------------------------------------- | +| [`SRT_ENOCONN`](#srt_enoconn) | Socket [`u`](#u) used when the operation is not connected. | +| [`SRT_ECONNLOST`](#srt_econnlost) | Socket [`u`](#u) used for the operation has lost its connection. | +| [`SRT_EINVALMSGAPI`](#srt_einvalmsgapi) | Incorrect API usage in **message mode**:
**live mode**: trying to send more bytes at once than `SRTO_PAYLOADSIZE` or wrong source time
was provided. | +| [`SRT_EINVALBUFFERAPI`](#srt_einvalbufferapi) | Incorrect API usage in **stream mode** (reserved for future use):
The congestion controller object used for this mode doesn't use any restrictions on this call,
but this may change. | +| [`SRT_ELARGEMSG`](#srt_elargemsg) | Message to be sent can't fit in the sending buffer (that is, it exceeds the current total space in the
sending buffer in bytes). This means that the sender buffer is too small, or the application is
trying to send a larger message than initially predicted. | +| [`SRT_EASYNCSND`](#srt_easyncsnd) | There's no free space currently in the buffer to schedule the payload. This is only reported in
non-blocking mode ([`SRTO_SNDSYN`](API-socket-options.md#SRTO_SNDSYN) set to false); in blocking mode the call is blocked until
enough free space in the sending buffer becomes available. | +| [`SRT_ETIMEOUT`](#srt_etimeout) | The condition described above still persists and the timeout has passed. This is only reported in
blocking mode when [`SRTO_SNDTIMEO`](API-socket-options.md#SRTO_SNDTIMEO) is set to a value other than -1. | +| [`SRT_EPEERERR`](#srt_epeererr) | This is reported only in the case where, as a stream is being received by a peer, the
[`srt_recvfile`](#srt_recvfile) function encounters an error during a write operation on a file. This is reported by
a `UMSG_PEERERROR` message from the peer, and the agent sets the appropriate flag internally.
This flag persists up to the moment when the connection is broken or closed. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_recv +### srt_recvmsg +### srt_recvmsg2 + + +``` +int srt_recv(SRTSOCKET u, char* buf, int len); +int srt_recvmsg(SRTSOCKET u, char* buf, int len); +int srt_recvmsg2(SRTSOCKET u, char *buf, int len, SRT_MSGCTRL *mctrl); +``` + +Extracts the payload waiting to be received. Note that [`srt_recv`](#srt_recv) and +[`srt_recvmsg`](#srt_recvmsg) are identical functions, two different names being +kept for historical reasons. In the UDT predecessor the application was required +to use either the `UDT::recv` version for **stream mode** and `UDT::recvmsg` for +**message mode**. In SRT this distinction is resolved internally by the +[`SRTO_MESSAGEAPI`](API-socket-options.md#SRTO_MESSAGEAPI) flag. + +**Arguments**: + +* [`u`](#u): Socket used to send. The socket must be connected for this operation. +* `buf`: Points to the buffer to which the payload is copied. +* `len`: Size of the payload specified in `buf`. +* `mctrl`: An object of [`SRT_MSGCTRL`](#SRT_MSGCTRL) type that contains extra +parameters. + +The way this function works is determined by the mode set in options, and it has +specific requirements: + +1. In **file/stream mode**, as many bytes as possible are retrieved, that is, +only so many bytes that fit in the buffer and are currently available. Any +data that is available but not extracted this time will be available next time. + +2. In **file/message mode**, exactly one message is retrieved, with the +boundaries defined at the moment of sending. If some parts of the messages are +already retrieved, but not the whole message, nothing will be received (the +function blocks or returns [`SRT_EASYNCRCV`](#srt_easyncrcv)). If the message +to be returned does not fit in the buffer, nothing will be received and +the error is reported. + +3. In **live mode**, the function behaves as in **file/message mode**, although the +number of bytes retrieved will be at most the maximum payload of one MTU. +The [`SRTO_PAYLOADSIZE`](API-socket-options.md#SRTO_PAYLOADSIZE) value configured by the sender +is not negotiated, and not known to the receiver. +The [`SRTO_PAYLOADSIZE`](API-socket-options.md#SRTO_PAYLOADSIZE) value set on the SRT receiver +is mainly used for heuristics. However, the receiver is prepared to receive +the whole MTU as configured with [`SRTO_MSS`](API-socket-options.md#SRTO_MSS). +In this mode, however, with default settings of [`SRTO_TSBPDMODE`](API-socket-options.md#SRTO_TSBPDMODE) +and [`SRTO_TLPKTDROP`](API-socket-options.md#SRTO_TLPKTDROP), the message will be +received only when its time to play has come, and until then it will be kept in the +receiver buffer. Also, when the time to play has come for a message that is next to +the currently lost one, it will be delivered and the lost one dropped. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| Size | Size (\>0) of the data received, if successful. | +| 0 | If the connection has been closed | +| `SRT_ERROR` | (-1) when an error occurs | +| | | + +| Errors | | +|:--------------------------------------------- |:--------------------------------------------------------- | +| [`SRT_ENOCONN`](#srt_enoconn) | Socket [`u`](#u) used for the operation is not connected. | +| [`SRT_ECONNLOST`](#srt_econnlost) | Socket [`u`](#u) used for the operation has lost connection (this is reported only if the connection
was unexpectedly broken, not when it was closed by the foreign host). | +| [`SRT_EINVALMSGAPI`](#srt_einvalmsgapi) | Incorrect API usage in **message mode**:
-- **live mode**: size of the buffer is less than [`SRTO_PAYLOADSIZE`](API-socket-options.md#SRTO_PAYLOADSIZE) | +| [`SRT_EINVALBUFFERAPI`](#srt_einvalbufferapi) | Incorrect API usage in **stream mode**:
• Currently not in use. File congestion control used for **stream mode** does not restrict
the parameters. :warning:   **???** | +| [`SRT_ELARGEMSG`](#srt_elargemsg) | Message to be sent can't fit in the sending buffer (that is, it exceeds the current total space in
the sending buffer in bytes). This means that the sender buffer is too small, or the application
is trying to send a larger message than initially intended. | +| [`SRT_EASYNCRCV`](#srt_easyncrcv) | There are no data currently waiting for delivery. This happens only in non-blocking mode
(when [`SRTO_RCVSYN`](API-socket-options.md#SRTO_RCVSYN) is set to false). In blocking mode the call is blocked until the data are ready.
How this is defined, depends on the mode:
• In **live mode** (with [`SRTO_TSBPDMODE`](API-socket-options.md#SRTO_TSBPDMODE) on), at least one packet must be present in the receiver
buffer and its time to play be in the past
• In **file/message mode**, one full message must be available, the next one waiting if there are no
messages with `inorder` = false, or possibly the first message ready with `inorder` = false
• In **file/stream mode**, it is expected to have at least one byte of data still not extracted | +| [`SRT_ETIMEOUT`](#srt_etimeout) | The readiness condition described above is still not achieved and the timeout has passed.
This is only reported in blocking mode when[`SRTO_RCVTIMEO`](API-socket-options.md#SRTO_RCVTIMEO) is set to a value other than -1. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_sendfile +### srt_recvfile + +``` +int64_t srt_sendfile(SRTSOCKET u, const char* path, int64_t* offset, int64_t size, int block); +int64_t srt_recvfile(SRTSOCKET u, const char* path, int64_t* offset, int64_t size, int block); +``` + +These are functions dedicated to sending and receiving a file. You need to call +this function just once for the whole file, although you need to know the size of +the file prior to sending, and also define the size of a single block that should +be internally retrieved and written into a file in a single step. This influences +only the performance of the internal operations; from the application perspective +you just have one call that exits only when the transmission is complete. + +**Arguments**: + +* [`u`](#u): Socket used for transmission. The socket must be connected. +* `path`: Path to the file that should be read or written. +* `offset`: Needed to pass or retrieve the offset used to read or write to a file +* `size`: Size of transfer (file size, if offset is at 0) +* `block`: Size of the single block to read at once before writing it to a file + +The following values are recommended for the `block` parameter: + +``` +#define SRT_DEFAULT_SENDFILE_BLOCK 364000 +#define SRT_DEFAULT_RECVFILE_BLOCK 7280000 +``` + +You need to pass them to the [`srt_sendfile`](#srt_sendfile) or +[`srt_recvfile`](#srt_recvfile) function if you don't know what value to chose. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| Size | The size (\>0) of the transmitted data of a file. It may be less than `size`, if the size was greater
than the free space in the buffer, in which case you have to send rest of the file next time. | +| -1 | in case of error | +| | | + +| Errors | | +|:--------------------------------------------- |:----------------------------------------------------------------------------- | +| [`SRT_ENOCONN`](#srt_enoconn) | Socket [`u`](#u) used for the operation is not connected. | +| [`SRT_ECONNLOST`](#srt_econnlost) | Socket [`u`](#u) used for the operation has lost its connection. | +| [`SRT_EINVALBUFFERAPI`](#srt_einvalbufferapi) | When socket has [`SRTO_MESSAGEAPI`](API-socket-options.md#SRTO_MESSAGEAPI) = true or [`SRTO_TSBPDMODE`](API-socket-options.md#SRTO_TSBPDMODE) = true.
(:warning:   **BUG?**: Looxlike MESSAGEAPI isn't checked) | +| [`SRT_EINVRDOFF`](#srt_einvrdoff) | There is a mistake in `offset` or `size` parameters, which should match the index availability
and size of the bytes available since `offset` index. This is actually reported for [`srt_sendfile`](#srt_sendfile)
when the `seekg` or `tellg` operations resulted in error. | +| [`SRT_EINVWROFF`](#srt_einvwroff) | Like above, reported for [`srt_recvfile`](#srt_recvfile) and `seekp`/`tellp`. | +| [`SRT_ERDPERM`](#srt_erdperm) | The read from file operation has failed ([`srt_sendfile`](#srt_sendfile)). | +| [`SRT_EWRPERM`](#srt_ewrperm) | The write to file operation has failed ([`srt_recvfile`](#srt_recvfile)). | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + + + +## Performance Tracking + +* [srt_bstats, srt_bistats](#srt_bstats-srt_bistats) + +**Sequence Numbers:** +The sequence numbers used in SRT are 32-bit "circular numbers" with the most significant +bit not included. For example 0x7FFFFFFF shifted forward by 3 becomes 2. As far as +any comparison is concerned, it can be thought of as a "distance" which is an integer +value expressing an offset to be added to one sequence number in order to get the +second one. This distance is only valid as long as the threshold value isn't exceeded, +so it's understood that all sequence numbers that are anywhere taken into account are +systematically updated and kept in the range between 0 and half of the maximum 0x7FFFFFFF. +Hence, the distance counting procedure always assumes that the sequence number are in +the required range already, so for a numbers like 0x7FFFFFF0 and 0x10, for which the +"numeric difference" would be 0x7FFFFFE0, the "distance" is 0x20. + + +### srt_bstats +### srt_bistats +``` +// Performance monitor with Byte counters for better bitrate estimation. +int srt_bstats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear); + +// Performance monitor with Byte counters and instantaneous stats instead of moving averages for Snd/Rcvbuffer sizes. +int srt_bistats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear, int instantaneous); +``` + +Reports the current statistics + +**Arguments**: + +* [`u`](#u): Socket from which to get statistics +* `perf`: Pointer to an object to be written with the statistics +* `clear`: 1 if the statistics should be cleared after retrieval +* `instantaneous`: 1 if the statistics should use instant data, not moving averages + +`SRT_TRACEBSTATS` is an alias to `struct CBytePerfMon`. For a complete description +of the fields please refer to [SRT Statistics](statistics.md). + + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| 0 | Success | +| -1 | Failure | +| | | + +| Errors | | +|:----------------------------------- |:----------------------------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Invalid socket ID provided. +| [`SRT_ECONNLOST`](#srt_econnlost) | Connection lost (group socket). +| [`SRT_ENOCONN`](#srt_enoconn) | Not connected (group socket). +| | | + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + + + +## Asynchronous Operations (Epoll) + +* [srt_epoll_create](#srt_epoll_create) +* [srt_epoll_add_usock, srt_epoll_add_ssock, srt_epoll_update_usock, srt_epoll_update_ssock](#srt_epoll_add_usock-srt_epoll_add_ssock-srt_epoll_update_usock-srt_epoll_update_ssock) +* [srt_epoll_remove_usock, srt_epoll_remove_ssock](#srt_epoll_remove_usock-srt_epoll_remove_ssock) +* [srt_epoll_wait](#srt_epoll_wait) +* [srt_epoll_uwait](#srt_epoll_uwait) +* [srt_epoll_clear_usocks](#srt_epoll_clear_usocks) +* [srt_epoll_set](#srt_epoll_set) +* [srt_epoll_release](#srt_epoll_release) + +The epoll system is currently the only method for using multiple sockets in one +thread with having the blocking operation moved to epoll waiting so that it can +block on multiple sockets at once. That is, instead of blocking a single reading +or writing operation, as it's in blocking mode, it blocks until at least one of +the sockets subscribed for a single waiting call in given operation mode is ready +to do this operation without blocking. It's usually combined with setting the +nonblocking mode on a socket. In SRT this is set separately for reading and +writing ([`SRTO_RCVSYN`](API-socket-options.md#SRTO_RCVSYN) and +[`SRTO_SNDSYN`](API-socket-options.md#SRTO_SNDSYN) respectively). This is +to ensure that if there is internal error in the application (or even possibly +a bug in SRT that has reported a spurious readiness report) the operation will end +up with an error rather than cause blocking, which would be more dangerous for the +application ([`SRT_EASYNCRCV`](#srt_easyncrcv) and [`SRT_EASYNCSND`](#srt_easyncsnd) +respectively). + +The epoll system, similar to the one on Linux, relies on [`eid`](#eid) objects +managed internally in SRT, which can be subscribed to particular sockets and the +readiness status of particular operations. The [`srt_epoll_wait`](#srt_epoll_wait) +function can then be used to block until any readiness status in the whole +[`eid`](#eid) is set. + + +### srt_epoll_create +``` +int srt_epoll_create(void); +``` + +Creates a new epoll container. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| valid EID | Success | +| -1 | Failure | +| | | + +| Errors | | +|:----------------------------------- |:--------------------------------------------------------------------- | +| [`SRT_ECONNSETUP`](#srt_econnsetup) | System operation failed or not enough space to create a new epoll. System error might happen on
systems that use a special method for the system part of epoll (`epoll_create()`, `kqueue()`),
and therefore associated resources, like epoll on Linux. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_epoll_add_usock +### srt_epoll_add_ssock +### srt_epoll_update_usock +### srt_epoll_update_ssock + +``` +int srt_epoll_add_usock(int eid, SRTSOCKET u, const int* events); +int srt_epoll_add_ssock(int eid, SYSSOCKET s, const int* events); +int srt_epoll_update_usock(int eid, SRTSOCKET u, const int* events); +int srt_epoll_update_ssock(int eid, SYSSOCKET s, const int* events); +``` + +Adds a socket to a container, or updates an existing socket subscription. + +The `_usock` suffix refers to a user socket (SRT socket). +The `_ssock` suffix refers to a system socket. + +The `_add_` functions add new sockets. The `_update_` functions act on a socket that +is in the container already and just allow changes in the subscription details. For +example, if you have already subscribed a socket with [`SRT_EPOLL_OUT`](#SRT_EPOLL_OUT) +to wait until it's connected, to change it into poll for read-readiness, you use this +function on that same socket with a variable set to [`SRT_EPOLL_IN`](#SRT_EPOLL_IN). +This will not only change the event type which is polled on the socket, but also +remove any readiness status for flags that are no longer set. It is discouraged +to perform socket removal and adding back (instead of using `_update_`) because +this way you may miss an event that could happen in the brief moment between +these two calls. + +**Arguments**: + +* `eid`: epoll container id +* `u`: SRT socket +* `s`(#s): system socket +* `events`: points to + * a variable set to epoll flags (see below) to use only selected events + * NULL if you want to subscribe a socket for all events in level-triggered mode + +Possible epoll flags are the following: + + * `SRT_EPOLL_IN`: report readiness for reading or incoming connection on a listener socket + * `SRT_EPOLL_OUT`: report readiness for writing or a successful connection + * `SRT_EPOLL_ERR`: report errors on the socket + * `SRT_EPOLL_UPDATE`: an important event has happened that requires attention + * `SRT_EPOLL_ET`: the event will be edge-triggered + +All flags except [`SRT_EPOLL_ET`](#SRT_EPOLL_ET) are event type flags (important for functions +that expect only event types and not other flags). + +The [`SRT_EPOLL_IN`](#SRT_EPOLL_IN), [`SRT_EPOLL_OUT`](#SRT_EPOLL_OUT) and +[`SRT_EPOLL_ERR`](#SRT_EPOLL_ERR) events are by default **level-triggered**. +With [`SRT_EPOLL_ET`](#SRT_EPOLL_ET) flag they become **edge-triggered**. + +The [`SRT_EPOLL_UPDATE`](#SRT_EPOLL_UPDATE) flag is always edge-triggered. It +designates a special event that happens on a group, or on a listener socket that +has the [`SRTO_GROUPCONNECT`](API-socket-options.md#SRTO_GROUPCONNECT) flag +set to allow group connections. This flag is triggered in the following situations: + +* for group connections, when a new link has been established for a group that +is already connected (that is, has at least one connection established), +[`SRT_EPOLL_UPDATE`](#SRT_EPOLL_UPDATE) is reported for the listener socket +accepting the connection. This is intended for internal use only. An initial +connection results in reporting the group connection on that listener. But +when the group is already connected, [`SRT_EPOLL_UPDATE`](#SRT_EPOLL_UPDATE) +is reported instead. + +* when one of a group's member connection has been broken + +Note that at this time the edge-triggered mode is supported only for SRT +sockets, not for system sockets. + +In the **edge-triggered** mode the function will only return socket states that +have changed since the last call of the waiting function. All events reported +in a particular call of the waiting function will be cleared in the internal +flags and will not be reported until the internal signalling logic clears this +state and raises it again. + +In the **level-triggered** mode the function will always return the readiness +state as long as it lasts, until the internal signalling logic clears it. + +Note that when you use [`SRT_EPOLL_ET`](#SRT_EPOLL_ET) flag in one subscription +call, it defines edge-triggered mode for all events passed together with it. +However, if you want to have some events reported as edge-triggered and others +as level-triggered, you can do two separate subscriptions for the same socket. + +**IMPORTANT**: The [`srt_epoll_wait`](#srt_epoll_wait) function does not report +[`SRT_EPOLL_UPDATE`](#SRT_EPOLL_UPDATE) events. If you need the ability to get +any possible flag, you must use [`srt_epoll_wait`](#srt_epoll_wait). Note that +this function doesn't work with system file descriptors. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| 0 | Success | +| -1 | Failure | +| | | + +| Errors | | +|:----------------------------------- |:----------------------------------------------------------------- | +| [`SRT_EINVPOLLID`](#srt_einvpollid) | [`eid`](#eid) parameter doesn't refer to a valid epoll container | +| | | + +:warning:   **BUG?**: for `add_ssock` the system error results in an empty `CUDTException()` +call which actually results in [`SRT_SUCCESS`](#srt_success). For cases like that +the [`SRT_ECONNSETUP`](#srt_econnsetup) code is predicted. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_epoll_remove_usock +### srt_epoll_remove_ssock + +``` +int srt_epoll_remove_usock(int eid, SRTSOCKET u); +int srt_epoll_remove_ssock(int eid, SYSSOCKET s); +``` + +Removes a specified socket from an epoll container and clears all readiness +states recorded for that socket. + +The `_usock` suffix refers to a user socket (SRT socket). +The `_ssock` suffix refers to a system socket. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| 0 | Success | +| -1 | Failure | +| | | + +| Errors | | +|:----------------------------------- |:----------------------------------------------------------------- | +| [`SRT_EINVPOLLID`](#srt_einvpollid) | [`eid`](#eid) parameter doesn't refer to a valid epoll container | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_epoll_wait +``` +int srt_epoll_wait(int eid, SRTSOCKET* readfds, int* rnum, SRTSOCKET* writefds, int* wnum, int64_t msTimeOut, + SYSSOCKET* lrfds, int* lrnum, SYSSOCKET* lwfds, int* lwnum); +``` + +Blocks the call until any readiness state occurs in the epoll container. + +Readiness can be on a socket in the container for the event type as per +subscription. Note that in the case when a particular event was subscribed with +[`SRT_EPOLL_ET`](#SRT_EPOLL_ET) flag, this event, once reported in this function, +will be cleared internally. + +The first readiness state causes this function to exit, but all ready sockets +are reported. This function blocks until the timeout specified in the `msTimeOut` +parameter. If timeout is 0, it exits immediately after checking. If timeout is +-1, it blocks indefinitely until a readiness state occurs. + +**Arguments**: + +* `eid`: epoll container +* `readfds` and `rnum`: A pointer and length of an array to write SRT sockets that are read-ready +* `writefds` and `wnum`: A pointer and length of an array to write SRT sockets that are write-ready +* `msTimeOut`: Timeout specified in milliseconds, or special values (0 or -1) +* `lwfds` and `lwnum`: A pointer and length of an array to write system sockets that are read-ready +* `lwfds` and `lwnum`: A pointer and length of an array to write system sockets that are write-ready + +Note that the following flags are reported: + +* [`SRT_EPOLL_IN`](#SRT_EPOLL_IN) as read-ready (also a listener socket ready to accept) +* [`SRT_EPOLL_OUT`](#SRT_EPOLL_OUT) as write-ready (also a connected socket) +* [`SRT_EPOLL_ERR`](#SRT_EPOLL_ERR) as both read-ready and write-ready +* [`SRT_EPOLL_UPDATE`](#SRT_EPOLL_UPDATE) is not reported + +There is no space here to report sockets for which it's already known that the operation +will end up with error (although such a state is known internally). If an error occurred +on a socket then that socket is reported in both read-ready and write-ready arrays, +regardless of what event types it was subscribed for. Usually then you subscribe the +given socket for only read readiness, for example ([`SRT_EPOLL_IN`](#SRT_EPOLL_IN)), +but pass both arrays for read and write readiness.This socket will not be reported +in the write readiness array even if it's write ready (because this isn't what it +was subscribed for), but it will be reported there, if the next operation on this +socket is about to be erroneous. On such sockets you can still perform an operation, +just you should expect that it will always report an error. On the other hand that's +the only way to know what kind of error has occurred on the socket. + +| Returns | | +|:----------------------------- |:------------------------------------------------------------ | +| Number | The number (\>0) of ready sockets, of whatever kind (if any) | +| -1 | Error | +| | | + +| Errors | | +|:----------------------------------- |:------------------------------------------------------------------- | +| [`SRT_EINVPOLLID`](#srt_einvpollid) | [`eid`](#eid) parameter doesn't refer to a valid epoll container | +| [`SRT_ETIMEOUT`](#srt_etimeout) | Up to `msTimeOut` no sockets subscribed in [`eid`](#eid) were ready. This is reported only if `msTimeOut`
was \>=0, otherwise the function waits indefinitely. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_epoll_uwait +``` +int srt_epoll_uwait(int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut); +``` + +This function blocks a call until any readiness state occurs in the epoll container. +Unlike [`srt_epoll_wait`](#srt_epoll_wait), it can only be used with [`eid`](#eid) +subscribed to user sockets (SRT sockets), not system sockets. + +This function blocks until the timeout specified in `msTimeOut` parameter. If +timeout is 0, it exits immediately after checking. If timeout is -1, it blocks +indefinitely until a readiness state occurs. + +**Arguments**: + +* `eid`: epoll container +* `fdsSet` : A pointer to an array of `SRT_EPOLL_EVENT` +* `fdsSize` : The size of the fdsSet array +* `msTimeOut` : Timeout specified in milliseconds, or special values (0 or -1): + * 0: Don't wait, return immediately (report any sockets currently ready) + * -1: Wait indefinitely. + +| Returns | | +|:----------------------------- |:-------------------------------------------------------------------------------------------------------------------------------------- | +| Number | The number of user socket (SRT socket) state changes that have been reported in `fdsSet`,
if this number isn't greater than `fdsSize` | +| `fdsSize` + 1 | This means that there was not enough space in the output array to report all events.
For events subscribed with the [`SRT_EPOLL_ET`](#SRT_EPOLL_ET) flag only those will be cleared that were reported.
Others will wait for the next call. | +| 0 | If no readiness state was found on any socket and the timeout has passed
(this is not possible when waiting indefinitely) | +| -1 | Error | +| | | + +| Errors | | +|:----------------------------------- |:----------------------------------------------------------------- | +| [`SRT_EINVPOLLID`](#srt_einvpollid) | [`eid`](#eid) parameter doesn't refer to a valid epoll container | +| [`SRT_EINVPARAM`](#srt_einvparam) | One of possible usage errors:
* `fdsSize` is < 0
* `fdsSize` is > 0 and `fdsSet` is a null pointer
* [`eid`](#eid) was subscribed to any system socket | +| | | + +**IMPORTANT**: This function reports timeout by returning 0, not by [`SRT_ETIMEOUT`](#srt_etimeout) error. + +The `SRT_EPOLL_EVENT` structure: + +``` +typedef struct SRT_EPOLL_EVENT_ +{ + SRTSOCKET fd; + int events; +} SRT_EPOLL_EVENT; +``` + +* `fd`: the user socket (SRT socket) +* [`events`](#events): event flags that report readiness of this socket - a combination +of [`SRT_EPOLL_IN`](#SRT_EPOLL_IN), [`SRT_EPOLL_OUT`](#SRT_EPOLL_OUT) and [`SRT_EPOLL_ERR`](#SRT_EPOLL_ERR). +See [srt_epoll_add_usock](#srt_epoll_add_usock) for details. + +Note that when [`SRT_EPOLL_ERR`](#SRT_EPOLL_ERR) is set, the underlying socket error +can't be retrieved with `srt_getlasterror()`. The socket will be automatically +closed and its state can be verified with a call to [`srt_getsockstate`](#srt_getsockstate). + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_epoll_clear_usocks +``` +int srt_epoll_clear_usocks(int eid); +``` + +This function removes all SRT ("user") socket subscriptions from the epoll +container identified by [`eid`](#eid). + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| 0 | Success | +| -1 | Failure | +| | | + +| Errors | | +|:----------------------------------- |:----------------------------------------------------------------- | +| [`SRT_EINVPOLLID`](#srt_einvpollid) | [`eid`](#eid) parameter doesn't refer to a valid epoll container | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_epoll_set +``` +int32_t srt_epoll_set(int eid, int32_t flags); +``` + +This function allows setting or retrieving flags that change the default +behavior of the epoll functions. All default values for these flags are 0. +The following flags are available: + +* `SRT_EPOLL_ENABLE_EMPTY`: allows the [`srt_epoll_wait`](#srt_epoll_wait) and +[`srt_epoll_uwait`](#srt_epoll_uwait) functions to be called with the EID not +subscribed to any socket. The default behavior of these function is to report +error in this case. + +* `SRT_EPOLL_ENABLE_OUTPUTCHECK`: Forces the [`srt_epoll_wait`](#srt_epoll_wait) +and [`srt_epoll_uwait`](#srt_epoll_uwait) functions to check if the output array +is not empty. For [`srt_epoll_wait`](#srt_epoll_wait) it is still allowed that +either system or user array is empty, as long as EID isn't subscribed to this +type of socket/fd. [`srt_epoll_uwait`](#srt_epoll_uwait) only checks if +the general output array is not empty. + +**Arguments**: + + * `eid`: the epoll container id + * `flags`: a nonzero set of the above flags, or special values: + * 0: clear all flags (set all defaults) + * -1: do not modify any flags + +| Returns | | +|:----------------------------- |:-------------------------------------------------------------------------- | +| | This function returns the state of the flags at the time before the call | +| -1 | Special value in case when an error occurred | +| | | + +| Errors | | +|:----------------------------------- |:----------------------------------------------------------------- | +| [`SRT_EINVPOLLID`](#srt_einvpollid) | [`eid`](#eid) parameter doesn't refer to a valid epoll container | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_epoll_release +``` +int srt_epoll_release(int eid); +``` + +Deletes the epoll container. + +| Returns | | +|:----------------------------- |:-------------------------------------------------------------- | +| | The number (\>0) of ready sockets, of whatever kind (if any) | +| -1 | Error | +| | | + +| Errors | | +|:----------------------------------- |:----------------------------------------------------------------- | +| [`SRT_EINVPOLLID`](#srt_einvpollid) | [`eid`](#eid) parameter doesn't refer to a valid epoll container | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + + + +## Logging Control + +* [srt_setloglevel](#srt_setloglevel) +* [srt_addlogfa, srt_dellogfa, srt_resetlogfa](#srt_addlogfa-srt_dellogfa-srt_resetlogfa) +* [srt_setloghandler](#srt_setloghandler) +* [srt_setlogflags](#srt_setlogflags) + +SRT has a widely used system of logs, as this is usually the only way to determine +how the internals are working without changing the rules by the act of tracing. +Logs are split into levels (5 levels out of those defined by syslog are in use) +and additional filtering is possible on an FA (functional area). By default only +entries up to the *Note* log level are displayed and from all FAs. + +Logging can only be manipulated globally, with no regard to a specific +socket. This is because lots of operations in SRT are not dedicated to any +particular socket, and some are shared between sockets. + +### srt_setloglevel + +``` +void srt_setloglevel(int ll); +``` + +Sets the minimum severity for logging. A particular log entry is displayed only +if it has a severity greater than or equal to the minimum. Setting this value +to `LOG_DEBUG` turns on all levels. + +The constants for this value are those from `` +(for Windows, refer to `common/win/syslog_defs.h`). The only meaningful ones are: + +* `LOG_DEBUG`: Highly detailed and very frequent messages +* `LOG_NOTICE`: Occasionally displayed information +* `LOG_WARNING`: Unusual behavior +* `LOG_ERR`: Abnormal behavior +* `LOG_CRIT`: Error that makes the current socket unusable + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_addlogfa +### srt_dellogfa +### srt_resetlogfa + +```c++ +void srt_addlogfa(int fa); +void srt_dellogfa(int fa); +void srt_resetlogfa(const int* fara, size_t fara_size); +``` + +A functional area (FA) is an additional filtering mechanism for logging. You can +set up logging to display logs only from selected FAs. The list of FAs is +collected in the `srt.h` file, as identified by the `SRT_LOGFA_` prefix. They are +not enumerated here because they may be changed very often. + +All FAs are turned on by default, except potentially dangerous ones +(such as `SRT_LOGFA_HAICRYPT`). The reason is that they may display either +some security information that shall remain in memory only (so, only +if strictly required for development), or some duplicated information +(so you may want to turn one FA on, while turning off the others). + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_setloghandler + +```c++ +void srt_setloghandler(void* opaque, SRT_LOG_HANDLER_FN* handler); +typedef void SRT_LOG_HANDLER_FN(void* opaque, int level, const char* file, int line, const char* area, const char* message); +``` + +By default logs are printed to standard error stream. This function replaces +the sending to a stream with a handler function that will receive them. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_setlogflags + +```c++ +void srt_setlogflags(int flags); +``` + +When you set a log handler with [`srt_setloghandler`](#srt_setloghandler), you +may also want to configure which parts of the log information you do not wish to +be passed in the log line (the `message` parameter). A user's logging facility may, +for example, not wish to get the current time or log level marker, as it +will provide this information on its own. + +The following flags are available, as collected in the `logging_api.h` public header: + +- `SRT_LOGF_DISABLE_TIME`: Do not provide the time in the header +- `SRT_LOGF_DISABLE_THREADNAME`: Do not provide the thread name in the header +- `SRT_LOGF_DISABLE_SEVERITY`: Do not provide severity information in the header +- `SRT_LOGF_DISABLE_EOL`: Do not add the end-of-line character to the log line + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + +## Time Access + +* [srt_time_now](#srt_time_now) +* [srt_connection_time](#srt_connection_time) + +The following set of functions is intended to retrieve timestamps from the clock +used by SRT. + +The sender can pass the timestamp in `MSGCTRL::srctime` of the `srt_sendmsg2(..)` +function together with the packet being submitted to SRT. If the `srctime` value +is not provided (the default value of 0 is set), SRT will use the internal clock +and assign packet submission time as the packet timestamp. If the sender wants to +explicitly assign a timestamp to a certain packet this timestamp MUST be taken +from SRT Time Access functions. The time value provided MUST equal or exceed the +connection start time (`srt_connection_time(..)`) of the SRT socket passed +to `srt_sendmsg2(..)`. + +The current time value of the SRT internal clock can be retrieved using +the `srt_time_now()` function. + +There are two known cases where you might want to use `srctime`: + +1. SRT passthrough (for stream gateways). +You may wish to simply retrieve packets from an SRT source and pass them transparently +to an SRT output (possibly re-encrypting). In that case, every packet you read should +preserve the original value of `srctime` as obtained from [`srt_recvmsg2`](#srt_recvmsg2), +and the original `srctime` for each packet should be then passed to [`srt_sendmsg2`](#srt_sendmsg). +This mechanism could be used to avoid jitter resulting from varying differences between +the time of receiving and sending the same packet. + +2. Stable timing source. +In the case of a live streaming procedure, when spreading packets evenly into the stream, +you might want to predefine times for every single packet to keep time intervals perfectly equal. +Or, if you believe that your input signal delivers packets at the exact times that should be +assigned to them, you might want to preserve these times at the SRT receiving side +to avoid jitter that may result from varying time differences between the packet arrival +and the moment when sending it over SRT. In such cases you might do the following: + + - At the packet arrival time, grab the current time at that moment using `srt_time_now()`. + + - When you want a pre-calculated packet time, use a private relative time counter + set at the moment when the connection was made. From the moment when your first packet + is ready, start pre-calculating packet times relative to the connection start time obtained + from `srt_connection_time()`. Although you still have to synchronize sending times with these + predefined times, by explicitly specifying the source time you avoid the jitter + resulting from a lost accuracy due to waiting time and unfortunate thread scheduling. + +Note that `srctime` uses an internally defined clock that is intended to be monotonic +(the definition depends on the build flags, see below). Because of that **the application +should not define this time basing on values obtained from the system functions for getting +the current system time** (such as `time`, `ftime` or `gettimeofday`). To avoid problems and +misunderstanding you should rely exclusively on time values provided by the +`srt_time_now()` and `srt_connection_time()` functions. + +The clock used by the SRT internal clock is determined by the following build flags: +- `ENABLE_MONOTONIC` makes use of `CLOCK_MONOTONIC` with `clock_gettime` function. +- `ENABLE_STDXXX_SYNC` makes use of `std::chrono::steady_clock`. + +The default is currently to use the system clock as the internal SRT clock, +although it's highly recommended to use one of the above monotonic clocks, +as system clock is vulnerable to time modifications during transmission. + +### srt_time_now + +```c++ +int64_t srt_time_now(); +``` + +Get time in microseconds elapsed since epoch using SRT internal clock (steady or monotonic clock). + +| Returns | | +|:----------------------------- |:------------------------------------------------------------------------ | +| | Current time in microseconds elapsed since epoch of SRT internal clock. | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_connection_time + +```c++ +int64_t srt_connection_time(SRTSOCKET sock); +``` + +Get connection time in microseconds elapsed since epoch using SRT internal clock +(steady or monotonic clock). The connection time represents the time when SRT socket +was open to establish a connection. Milliseconds elapsed since connection start time +can be determined using [**Performance tracking**](#Performance-tracking) functions +and `msTimeStamp` value of the `SRT_TRACEBSTATS` (see [SRT Statistics](statistics.md)). + +| Returns | | +|:----------------------------- |:--------------------------------------------------------------------------- | +| | Connection time in microseconds elapsed since epoch of SRT internal clock | +| -1 | Error | +| | | + +| Errors | | +|:--------------------------------- |:---------------------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket `sock` is not an ID of a valid SRT socket | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_clock_type + +```c +int srt_clock_type(void); +``` + +Get the type of clock used internally by SRT to be used only for informtational peurpose. +Using any time source except for [`srt_time_now()`](#srt_time_now) and [`srt_connection_time(SRTSOCKET)`](#srt_connection_time) +to timestamp packets submitted to SRT is not recommended and must be done with awareness and at your own risk. + +| Returns | Clock Type | Description | +| :------ | :---------------------------------- | :------------------------------------------| +| 0 | `SRT_SYNC_CLOCK_STDCXX_STEADY` | C++11 `std::chrono::steady_clock` | +| 1 | `SRT_SYNC_CLOCK_GETTIME_MONOTONIC` | `clock_gettime` with `CLOCK_MONOTONIC` | +| 2 | `SRT_SYNC_CLOCK_WINQPC` | Windows `QueryPerformanceCounter(..)` | +| 3 | `SRT_SYNC_CLOCK_MACH_ABSTIME` | `mach_absolute_time()` | +| 4 | `SRT_SYNC_CLOCK_POSIX_GETTIMEOFDAY` | POSIX `gettimeofday(..)` | +| 5 | `SRT_SYNC_CLOCK_AMD64_RDTSC` | `asm("rdtsc" ..)` | +| 6 | `SRT_SYNC_CLOCK_IA32_RDTSC` | `asm volatile("rdtsc" ..)` | +| 7 | `SRT_SYNC_CLOCK_IA64_ITC` | `asm("mov %0=ar.itc" ..)` | + +| Errors | | +|:--------------------------------- |:---------------------------------------------------------- | +| None | | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + + +## Diagnostics + +* [srt_getlasterror_str](#srt_getlasterror_str) +* [srt_getlasterror](#srt_getlasterror) +* [srt_strerror](#srt_strerror) +* [srt_clearlasterror](#srt_clearlasterror) +* [srt_getrejectreason](#srt_getrejectreason) +* [srt_rejectreason_str](#srt_rejectreason_str) +* [srt_setrejectreason](#srt_setrejectreason) + +General notes concerning the `getlasterror` diagnostic functions: when an API +function ends up with error, this error information is stored in a thread-local +storage. This means that you'll get the error of the operation that was last +performed as long as you call this diagnostic function just after the failed +function has returned. In any other situation the information provided by the +diagnostic function is undefined. + +**NOTE**: There are lists of rejection reasons and error codes at the bottom of this section. + + +### srt_getlasterror + +``` +int srt_getlasterror(int* errno_loc); +``` + +Get the numeric code of the last error. Additionally, in the variable passed as +`errno_loc` the system error value is returned, or 0 if there was no system error +associated with the last error. The system error is: + + * On POSIX systems, the value from `errno` + * On Windows, the result from `GetLastError()` call + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_strerror +``` +const char* srt_strerror(int code, int errnoval); +``` + +Returns a string message that represents a given SRT error code and possibly the +`errno` value, if not 0. + +**NOTE:** *This function isn't thread safe. It uses a static variable to hold the +error description. There's no problem with using it in a multithreaded environment, +as long as only one thread in the whole application calls this function at the +moment* + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_getlasterror_str +``` +const char* srt_getlasterror_str(void); +``` + +Get the text message for the last error. It's a shortcut to calling first +`srt_getlasterror` and then passing the returned value into [`srt_strerror`](#srt_strerror). +Note that, contrary to [`srt_strerror`](#srt_strerror), this function is thread safe. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_clearlasterror + +``` +void srt_clearlasterror(void); +``` + +This function clears the last error. After this call, `srt_getlasterror` will +report a "successful" code. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_rejectreason_str + +``` +const char* srt_rejectreason_str(enum SRT_REJECT_REASON id); +``` + +Returns a constant string for the reason of the connection rejected, as per given +code ID. It provides a system-defined message for values below `SRT_REJ_E_SIZE`. +For other values below `SRT_REJC_PREDEFINED` it returns the string for +[`SRT_REJ_UNKNOWN`](#SRT_REJ_UNKNOWN). For values since `SRT_REJC_PREDEFINED` on, +returns "Application-defined rejection reason". + +The actual messages assigned to the internal rejection codes, that is, less than +`SRT_REJ_E_SIZE`, can be also obtained from the `srt_rejectreason_msg` array. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_setrejectreason + +``` +int srt_setrejectreason(SRTSOCKET sock, int value); +``` + +Sets the rejection code on the socket. This call is only useful in the listener +callback. The code from `value` set this way will be set as a rejection reason +for the socket. After the callback rejects the connection, the code will be passed +back to the caller peer with the handshake response. + +Note that allowed values for this function begin with `SRT_REJC_PREDEFINED` +(that is, you cannot set a system rejection code). For example, your application +can inform the calling side that the resource specified under the `r` key in the +StreamID string (see [`SRTO_STREAMID`](API-socket-options.md#SRTO_STREAMID)) +is not available - it then sets the value to `SRT_REJC_PREDEFINED + 404`. + +| Returns | | +|:----------------------------- |:--------------------------------------------------------- | +| 0 | Error | +| -1 | Success | +| | | + +| Errors | | +|:--------------------------------- |:-------------------------------------------- | +| [`SRT_EINVSOCK`](#srt_einvsock) | Socket `sock` is not an ID of a valid socket | +| [`SRT_EINVPARAM`](#srt_einvparam) | `value` is less than `SRT_REJC_PREDEFINED` | +| | | + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### srt_getrejectreason + +``` +int srt_getrejectreason(SRTSOCKET sock); +``` +This function provides a more detailed reason for a failed connection attempt. It +shall be called after a connecting function (such as [`srt_connect`](#srt_connect)) +has returned an error, the code for which is [`SRT_ECONNREJ`](#srt_econnrej). If +[`SRTO_RCVSYN`](API-socket-options.md#SRTO_RCVSYN) has been set on the socket +used for the connection, the function should also be called when the +[`SRT_EPOLL_ERR`](#SRT_EPOLL_ERR) event is set for this socket. It returns +a numeric code, which can be translated into a message by +[`srt_rejectreason_str`](#srt_rejectreason_str). + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### Rejection Reasons + + +#### SRT_REJ_UNKNOWN + +A fallback value for cases when there was no connection rejected. + + +#### SRT_REJ_SYSTEM + +One system function reported a failure. Usually this means some system +error or lack of system resources to complete the task. + + +#### SRT_REJ_PEER + +The connection has been rejected by peer, but no further details are available. +This usually means that the peer doesn't support rejection reason reporting. + + +#### SRT_REJ_RESOURCE + +A problem with resource allocation (usually memory). + + +#### SRT_REJ_ROGUE + +The data sent by one party to another cannot be properly interpreted. This +should not happen during normal usage, unless it's a bug, or some weird +events are happening on the network. + + +#### SRT_REJ_BACKLOG + +The listener's backlog has exceeded its queue limit (there are many other callers +waiting for the opportunity of being connected and wait in the queue, which has +reached its limit). + + +#### SRT_REJ_IPE + +Internal Program Error. This should not happen during normal usage and it +usually means a bug in the software (although this can be reported by both +local and foreign host). + + +#### SRT_REJ_CLOSE + +The listener socket was able to receive your request, but at this moment it +is being closed. It's likely that your next attempt will result in a timeout. + + +#### SRT_REJ_VERSION + +One party of the connection has set up a minimum version that is required for +that connection, but the other party didn't satisfy this requirement. + + +#### SRT_REJ_RDVCOOKIE + +Rendezvous cookie collision. This normally should never happen, or the +probability that it will happen is negligible. However this can also be +a result of a misconfiguration in that you are trying to make a +rendezvous connection where both parties try to bind to the same IP +address, or both are local addresses of the same host. In such a case +the sent handshake packets are returning to the same host as if they +were sent by the peer (i.e. a party is sending to itself). When this happens, +this reject reason will be reported by every attempt. + + +#### SRT_REJ_BADSECRET + +Both parties have defined a passphrase for connection, but they differ. + + +#### SRT_REJ_UNSECURE + +Only one connection party has set up a password. See also the +[`SRTO_ENFORCEDENCRYPTION`](API-socket-options.md#SRTO_ENFORCEDENCRYPTION) flag. + + +#### SRT_REJ_MESSAGEAPI + +The value of the [`SRTO_MESSAGEAPI`](API-socket-options.md#SRTO_MESSAGEAPI) +flag is different on both connection parties. + + +#### SRT_REJ_CONGESTION + +The [`SRTO_CONGESTION`](API-socket-options.md#SRTO_CONGESTION)option has +been set up differently on both connection parties. + + +#### SRT_REJ_FILTER + +The [`SRTO_PACKETFILTER`](API-socket-options.md#SRTO_PACKETFILTER) option +has been set differently on both connection parties. + + +#### SRT_REJ_GROUP + +The group type or some group settings are incompatible for both connection parties. +While every connection within a bonding group may have different target addresses, +they should all designate the same endpoint and the same SRT application. If this +condition isn't satisfied, then the peer will respond with a different peer group +ID for the connection that is trying to contact a machine/application that is +completely different from the existing connections in the bonding group. + + +#### SRT_REJ_TIMEOUT + +The connection wasn't rejected, but it timed out. This code is always set on +connection timeout, but this is the only way to get this state in non-blocking +mode (see [`SRTO_RCVSYN`](API-socket-options.md#SRTO_RCVSYN)). + +There may also be server and user rejection codes, as defined by the +`SRT_REJC_INTERNAL`, `SRT_REJC_PREDEFINED` and `SRT_REJC_USERDEFINED` +constants. Note that the number space from the value of `SRT_REJC_PREDEFINED` +and above is reserved for "predefined codes" (`SRT_REJC_PREDEFINED` value plus +adopted HTTP codes). Values above `SRT_REJC_USERDEFINED` are freely defined by +the application. + + +[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions) + +--- + +### Error Codes + +All functions that return the status via `int` value return -1 (designated as +`SRT_ERROR`) always when the call has failed (in case of resource creation +functions an appropriate symbol is defined, like `SRT_INVALID_SOCK` for +`SRTSOCKET`). When this happens, the error code can be obtained from the +`srt_getlasterror` function. The values for the error are collected in an +`SRT_ERRNO` enum: + + +#### SRT_EUNKNOWN + +Internal error when setting the right error code. + + +#### SRT_SUCCESS + +The value set when the last error was cleared and no error has occurred since then. + + +#### SRT_ECONNSETUP + +General setup error resulting from internal system state. + + +#### SRT_ENOSERVER + +Connection timed out while attempting to connect to the remote address. Note +that when this happens, [`srt_getrejectreason`](#srt_getrejectreason) also reports +the timeout reason. + + +#### SRT_ECONNREJ + +Connection has been rejected. Additional reject reason can be obtained through +[`srt_getrejectreason`](#srt_getrejectreason) (see above). + + +#### SRT_ESOCKFAIL + +An error occurred when trying to call a system function on an internally used +UDP socket. Note that the detailed system error is available in the extra variable +passed by pointer to `srt_getlasterror`. + + +#### SRT_ESECFAIL + +A possible tampering with the handshake packets was detected, or an encryption +request wasn't properly fulfilled. + + +#### SRT_ESCLOSED + +A socket that was vital for an operation called in blocking mode +has been closed during the operation. Please note that this situation is +handled differently than the system calls for `connect` and `accept` +functions for TCP, which simply block indefinitely (or until the standard +timeout) when the key socket was closed during an operation. When this +error is reported, it usually means that the socket passed as the first +parameter to [`srt_connect*`](#srt_connect) or [`srt_accept`](#srt_accept) +is no longer usable. + + +#### SRT_ECONNFAIL + +General connection failure of unknown details. + + +#### SRT_ECONNLOST + +The socket was properly connected, but the connection has been broken. +This specialization is reported from the transmission functions. + + +#### SRT_ENOCONN + +The socket is not connected. This can be reported also when the connection was +broken for a function that checks some characteristic socket data. + + +#### SRT_ERESOURCE + +System or standard library error reported unexpectedly for unknown purpose. +Usually it means some internal error. + + +#### SRT_ETHREAD + +System was unable to spawn a new thread when required. + + +#### SRT_ENOBUF + +System was unable to allocate memory for buffers. + + +#### SRT_ESYSOBJ + +System was unable to allocate system specific objects (such as +sockets, mutexes or condition variables). + + +#### SRT_EFILE + +General filesystem error (for functions operating with file transmission). + + +#### SRT_EINVRDOFF + +Failure when trying to read from a given position in the file (file could +be modified while it was read from). + + +#### SRT_ERDPERM + +Read permission was denied when trying to read from file. + + +#### SRT_EINVWROFF + +Failed to set position in the written file. + + +#### SRT_EWRPERM + +Write permission was denied when trying to write to a file. + + +#### SRT_EINVOP + +Invalid operation performed for the current state of a socket. This mainly +concerns performing `srt_bind*` operations on a socket that is already bound. +Once a socket has been been bound, it cannot be bound again. + + +#### SRT_EBOUNDSOCK + +The socket is currently bound and the required operation cannot be +performed in this state. Usually it's about an option that can only +be set on the socket before binding (`srt_bind*`). Note that a socket +that is currently connected is also considered bound. + + +#### SRT_ECONNSOCK + +The socket is currently connected and therefore performing the required operation +is not possible. Usually concerns setting an option that must be set before +connecting (although it is allowed to be altered after binding), or when trying +to start a connecting operation ([`srt_connect*`](#srt_connect)) while the socket +isn't in a state that allows it (only [`SRTS_INIT`](#SRTS_INIT) or +[`SRTS_OPENED`](#SRTS_OPENED) are allowed). + + +#### SRT_EINVPARAM + +This error is reported in a variety of situations when call parameters +for API functions have some requirements defined and these were not +satisfied. This error should be reported after an initial check of the +parameters of the call before even performing any operation. This error +can be easily avoided if you set the values correctly. + + +#### SRT_EINVSOCK + +The API function required an ID of an entity (socket or group) and +it was invalid. Note that some API functions work only with socket or +only with group, so they would also return this error if inappropriate +type of entity was passed, even if it was valid. + + +#### SRT_EUNBOUNDSOCK + +The operation to be performed on a socket requires that it first be explicitly +bound (using [`srt_bind*`](#srt_bind) functions). Currently it applies when +calling [`srt_listen`](#srt_listen), which cannot work with an implicitly +bound socket. + + +#### SRT_ENOLISTEN + +The socket passed for the operation is required to be in the listen +state ([`srt_listen`](#srt_listen) must be called first). + + +#### SRT_ERDVNOSERV + +The required operation cannot be performed when the socket is set to rendezvous +mode ([`SRTO_RENDEZVOUS`](API-socket-options.md#SRTO_RENDEZVOUS) set to true). +Usually applies when trying to call [`srt_listen`](#srt_listen) on such a socket. + + +#### SRT_ERDVUNBOUND + +An attempt was made to connect to a socket set to rendezvous mode +([`SRTO_RENDEZVOUS`](API-socket-options.md#SRTO_RENDEZVOUS) set to true) +that was not first bound. A rendezvous connection requires setting up two addresses +and ports on both sides of the connection, then setting the local one with +[`srt_bind`](#srt_bind) and using the remote one with [`srt_connect`](#srt_connect) +(or you can simply use [`srt_rendezvous`](#srt_rendezvous)). Calling +[`srt_connect*`](#srt_connect) on an unbound socket (in [`SRTS_INIT`](#SRTS_INIT) +state) that is to be bound implicitly is only allowed for regular caller sockets +(not rendezvous). + + +#### SRT_EINVALMSGAPI + +The function was used incorrectly in the message API. This can happen if: + +* The parameters specific for the message API in [`SRT_MSGCTRL`](#SRT_MSGCTRL) +type parameter were incorrectly specified. + +* The extra parameter check performed by the congestion controller has failed. + +* The socket is a member of a self-managing group, therefore you should +perform the operation on the group, not on this socket. + + +#### SRT_EINVALBUFFERAPI + +The function was used incorrectly in the stream (buffer) API, that is, either the +stream-only functions were used with set message API ([`srt_sendfile`](#srt_sendfile)/[`srt_recvfile`](#srt_recvfile)) +or TSBPD mode was used with buffer API ([`SRTO_TSBPDMODE`](API-socket-options.md#SRTO_TSBPDMODE) set to true) +or the congestion controller has failed to check call parameters. + + +#### SRT_EDUPLISTEN + +The port tried to be bound for listening is already busy. Note that binding to the same port +is allowed in general (when [`SRTO_REUSEADDR`](API-socket-options.md#SRTO_REUSEADDRS) +is true on every socket that has bound it), but only one such socket can be a listener. + + +#### SRT_ELARGEMSG + +Size exceeded. This is reported in the following situations: + +* Trying to receive a message, but the read-ready message is larger than +the buffer passed to the receiving function. + +* Trying to send a message, but the size of this message exceeds the +size of the preset sender buffer, so it cannot be stored in the sender buffer. + +* When getting group data, the array to be filled is too small. + + +#### SRT_EINVPOLLID + +The epoll ID passed to an epoll function is invalid. + + +#### SRT_EPOLLEMPTY + +The epoll container currently has no subscribed sockets. This is reported by an +epoll waiting function that would in this case block forever. This problem +might be reported both in a situation where you have created a new epoll +container and didn't subscribe any sockets to it, or you did, but these +sockets have been closed (including when closed in a separate thread while the +waiting function was blocking). Note that this situation can be prevented +by setting the `SRT_EPOLL_ENABLE_EMPTY` flag, which may be useful when +you use multiple threads and start waiting without subscribed sockets, so that +you can subscribe them later from another thread. + + +#### `SRT_EBINDCONFLICT` + +The binding you are attempting to set up a socket with cannot be completed because +it conflicts with another existing binding. This is because an intersecting binding +was found that cannot be reused according to the specification in `srt_bind` call. + +A binding is considered intersecting if the existing binding has the same port +and covers at least partially the range as that of the attempted binding. These +ranges can be split in three groups: + +1. An explicitly specified IP address (both IPv4 and IPv6) covers this address only. +2. An IPv4 wildcard 0.0.0.0 covers all IPv4 addresses (but not IPv6). +3. An IPv6 wildcard :: covers: + * if `SRTO_IPV6ONLY` is true - all IPv6 addresses (but not IPv4) + * if `SRTO_IPV6ONLY` is false - all IP addresses. + +Example 1: + +* Socket 1: bind to IPv4 0.0.0.0 +* Socket 2: bind to IPv6 :: with `SRTO_IPV6ONLY` = true +* Result: NOT intersecting + +Example 2: + +* Socket 1: bind to IPv4 1.2.3.4 +* Socket 2: bind to IPv4 0.0.0.0 +* Result: intersecting (and conflicting) + +Example 3: + +* Socket 1: bind to IPv4 1.2.3.4 +* Socket 2: bind to IPv6 :: with `SRTO_IPV6ONLY` = false +* Result: intersecting (and conflicting) + +If any common range coverage is found between the attempted binding specification +(in `srt_bind` call) and the found existing binding with the same port number, +then all of the following conditions must be satisfied between them: + +1. The `SRTO_REUSEADDR` must be true (default) in both. + +2. The IP address specification (in case of IPv6, also including the value of +`SRTO_IPV6ONLY` flag) must be exactly identical. + +3. The UDP-specific settings must be identical. + +If any of these conditions isn't satisfied, the `srt_bind` function results +in conflict and report this error. + +#### SRT_EASYNCFAIL + +General asynchronous failure (not in use currently). + + +#### SRT_EASYNCSND + +Sending operation is not ready to perform. This error is reported when trying to +perform a sending operation on a socket that is not ready for sending, but +[`SRTO_SNDSYN`](API-socket-options.md#SRTO_SNDSYN) was set to false (when +true, the function would block the call otherwise). + + +#### SRT_EASYNCRCV + +Receiving operation is not ready to perform. This error is reported when trying to +perform a receiving operation or accept a new socket from the listener socket, when +the socket is not ready for that operation, but [`SRTO_RCVSYN`](API-socket-options.md#SRTO_RCVSYN) +was set to false (when true, the function would block the call otherwise). + + +#### SRT_ETIMEOUT + +The operation timed out. This can happen if you have a timeout set by an option +([`SRTO_RCVTIMEO`](API-socket-options.md#SRTO_RCVTIMEO) or +[`SRTO_SNDTIMEO`](API-socket-options.md#SRTO_SNDTIMEO)), or passed as an +extra argument ([`srt_epoll_wait`](#srt_epoll_wait) or [`srt_accept_bond`](#srt_accept_bond)) +and the function call was blocking, but the required timeout time has passed. + + +#### SRT_ECONGEST + +**NOTE**: This error is used only in an experimental version that requires +setting the `SRT_ENABLE_ECN` macro at compile time. Otherwise the situation +described below results in the usual successful report. + +This error should be reported by the sending function when, with +[`SRTO_TSBPDMODE`](API-socket-options.md#SRTO_TSBPDMODE) and +[`SRTO_TLPKTDROP`](API-socket-options.md#SRTO_TLPKTDROP) set to true, some +packets were dropped at the sender side (see the description of +[`SRTO_TLPKTDROP`](API-socket-options.md#SRTO_TLPKTDROP) for details). This +doesn't concern the data that were passed for sending by the sending function +(these data are placed at the back of the sender buffer, while the dropped +packets are at the front). In other words, the operation done by the sending +function is successful, but the application might want to slow down the sending +rate to avoid congestion. + + +#### SRT_EPEERERR + +This error is reported when a receiver peer is writing to a file that an agent +is sending. When the peer encounters an error when writing the received data to +a file, it sends the `UMSG_PEERERROR` message back to the sender, and the sender +reports this error from the API sending function. + + +[Return to Top of Page](#SRT-API-Functions) diff --git a/docs/API/API-socket-options.md b/docs/API/API-socket-options.md new file mode 100644 index 0000000..1289a5c --- /dev/null +++ b/docs/API/API-socket-options.md @@ -0,0 +1,1577 @@ +# SRT API Socket Options + +There is a general method of setting options on a socket in the SRT C API, similar +to the system `setsockopt/getsockopt` functions. + +- [Types Used in Socket Options](#types-used-in-socket-options) +- [Getting and Setting Options](#getting-and-setting-options) +- [List of Options](#list-of-options) + +## Types Used in Socket Options + +Possible types of socket options are: + +- `int32_t` - a 32-bit integer. On most systems similar to `int`. +In some cases the value is expressed using an enumeration type +(see [Enumeration types...](#enumeration_types) section below). + +- `int64_t` - a 64-bit integer. + +- `bool` - a Boolean type (`` for C, or built-in +for C++). When *setting* an option, passing the value through an `int` type is +also properly recognized. When *getting* an option, however, the`bool` type +should be used. It is also possible to pass a variable of `int` type initialized +with 0 and then comparing the resulting value with 0 (just don't compare +the result with 1 or `true`). + +- `string` - a C string. When *setting* an option, a `const char*` character array pointer +is expected to be passed in `optval` and the array length in `optlen` **without the terminating NULL character**. +When *getting*, an array is expected to be passed in `optval` with a +sufficient size **with an extra space for the terminating NULL character** provided in `optlen`. +The return value of `optlen` does not count the terminating NULL character. + +- `linger` - Linger structure. Used exclusively with `SRTO_LINGER`. + +### Enumeration Types Used in Options + +#### `SRT_TRANSTYPE` + +Used by `SRTO_TRANSTYPE` option: + +- `SRTT_LIVE`: Live mode. +- `SRTT_FILE`: File mode. + +See [Transmission Types](API.md#transmission-types) for details. + +#### `SRT_KM_STATE` + +The defined encryption state as performed by the Key Material Exchange, used +by `SRTO_RCVKMSTATE`, `SRTO_SNDKMSTATE` and `SRTO_KMSTATE` options: + +- `SRT_KM_S_UNSECURED`: no encryption/decryption. If this state is only on +the receiver, received encrypted packets will be dropped. + +- `SRT_KM_S_SECURING`: pending security (HSv4 only). This is a temporary state +used only if the connection uses HSv4 and the Key Material Exchange is +not finished yet. On HSv5 this is not possible because the Key Material +Exchange for the initial key is done in the handshake. + +- `SRT_KM_S_SECURED`: KM exchange was successful and the data will be sent +encrypted and will be decrypted by the receiver. This state is only possible on +both sides in both directions simultaneously. + +- `SRT_KM_S_NOSECRET`: If this state is in the sending direction (`SRTO_SNDKMSTATE`), +then it means that the sending party has set a passphrase, but the peer did not. +In this case the sending party can receive unencrypted packets from the peer, but +packets it sends to the peer will be encrypted and the peer will not be able to +decrypt them. This state is only possible in HSv5. + +- `SRT_KM_S_BADSECRET`: The password is wrong (set differently on each party); +encrypted payloads won't be decrypted in either direction. + +Note that with the default value of `SRTO_ENFORCEDENCRYPTION` option (true), +the state is equal on both sides in both directions, and it can be only +`SRT_KM_S_UNSECURED` or `SRT_KM_S_SECURED` (in other cases the connection +is rejected). Otherwise it may happen that either both sides have different +passwords and the state is `SRT_KM_S_BADSECRET` in both directions, or only +one party has set a password, in which case the KM state is as follows: + +| | `SRTO_RCVKMSTATE` | `SRTO_SNDKMSTATE` | +|--------------------------|----------------------|----------------------| +| Party with no password: | `SRT_KM_S_NOSECRET` | `SRT_KM_S_UNSECURED` | +| Party with password: | `SRT_KM_S_UNSECURED` | `SRT_KM_S_NOSECRET` | + +## Getting and Setting Options + +Legacy version: + + int srt_getsockopt(SRTSOCKET socket, int level, SRT_SOCKOPT optName, void* optval, int& optlen); + int srt_setsockopt(SRTSOCKET socket, int level, SRT_SOCKOPT optName, const void* optval, int optlen); + +New version: + + int srt_getsockflag(SRTSOCKET socket, SRT_SOCKOPT optName, void* optval, int& optlen); + int srt_setsockflag(SRTSOCKET socket, SRT_SOCKOPT optName, const void* optval, int optlen); + +In the legacy version, there's an additional unused `level` parameter. It was +there in the original UDT API just to mimic the system `setsockopt` function, +but it's ignored. + +Some options require a value of type `bool` while others require type `integer`, +which is not the same -- they differ in size, and mistaking them may end up +causing a crash. This must be kept in mind especially in any C wrapper. For +convenience, the *setting* option function may accept both `int32_t` and `bool` +types, but this is not so in the case of *getting* an option value. + +**UDT project legacy note**: Almost all options from the UDT library are +derived (there are a few deleted, including some deprecated already in UDT). +Many new SRT options have been added. All options are available exclusively +with the `SRTO_` prefix. Old names are provided as alias names in the `udt.h` +legacy/C++ API file. Note the translation rules: + +* `UDT_` prefix from UDT options was changed to the prefix `SRTO_` +* `UDP_` prefix from UDT options was changed to the prefix `SRTO_UDP_` +* `SRT_` prefix in older SRT versions was changed to `SRTO_` + +The [table below](#list-of-options) provides a complete list of SRT options and +their characteristics according to the following legend: + +1. **Since**: Defines the SRT version when this option was first introduced. If this field +is empty, it's an option derived from UDT. "Version 0.0.0" is the oldest version +of SRT ever created and put into use. + +2. **Restrict**: Defines restrictions on setting the option. The field is empty if the option +is not settable (see **Dir** column): + + - `pre-bind`: The option cannot be altered on a socket that is already bound (by calling +`srt_bind()` or any other function doing this, including automatic binding when trying to +connect, as well as accepted sockets). In other words, once an SRT socket has transitioned from +`SRTS_INIT` to `SRTS_OPENED` socket state. + + - `pre`: The option cannot be altered on a socket that is in `SRTS_LISTENING`, `SRTS_CONNECTING` +or `SRTS_CONNECTED` state. If an option was set on a listener socket, it will be inherited +by a socket returned by `srt_accept()` (except for `SRTO_STREAMID`). + + - `post`: The option is unrestricted and can be altered at any time, including when the +socket is connected, as well as on an accepted socket. The setting of this flag on a listening +socket is usually derived by the accepted socket, but this isn't a rule for all options. +Note though that there are some unrestricted options that have an important meaning when +set prior to connecting (different one than for a connected socket). + + **NOTE**: The `pre-bind` characteristic applies exclusively to options that: + + - Change the behavior and functionality of the `srt_bind` call + - Concern or set an option on the internally used UDP socket + - Concern any kind of resource used by the multiplexer + +3. **Type**: The data type of the option (see above). + +4. **Units**: Roughly specified unit, if the value defines things like length or time. +It can also define more precisely what kind of specialization can be used +when the type is integer: + + - `enum`: the possible values are defined in an enumeration type + - `flags`: the integer value is a collection of bit flags + - `B/s` - bytes per second. + +5. **Default**: The exact default value, if it can be easily specified. A more complicated +default state of a particular option will be explained in the [description](#option-descriptions) +(when marked by asterisk). For non-settable options this field is empty. + +6. **Range**: If a value of an integer type has a limited range, or only a certain value +allowed, it will be specified here (otherwise empty). A range value can be +specified as: + + - `X-... `: specifies only a minimum value + - `X-Y,Z `: values between X and Y are allowed, and additionally Z + + - If the value is of `string` type, this field will contain its maximum size +in square brackets. + + - If the range contains additionally an asterisk, it means that more elaborate +restrictions on the value apply, as explained in the [description](#option-descriptions). + +7. **Dir**: Option direction: W if can be set, R if can be retrieved, RW if both. + +8. **Entity**: This describes whether the option can be set on the socket or the group. +The G and S options may appear together, in which case both possibilities apply. +The D and I options, mutually exclusive, appear always with G. +The + marker can only coexist with GS. Possible specifications are: + + - S: This option can be set on a single socket (exclusively, if not GS) + + - G: This option can be set on a group (exclusively, if not GS) + + - D: If set on a group, it will be derived by the member socket + + - I: If set on a group, it will be taken and managed exclusively by the group + + - +: This option is also allowed to be set individually on a group member + socket through a configuration object in `SRT_SOCKGROUPCONFIG` prepared by + `srt_create_config`. Note that this setting may override the setting derived + from the group. + +## List of Options + +The following table lists SRT API socket options in alphabetical order. Option details are given further below. + +| Option Name | Since | Restrict | Type | Units | Default | Range | Dir |Entity | +| :------------------------------------------------------ | :---: | :------: | :-------: | :-----: | :---------------: | :------: |:---:|:-----:| +| [`SRTO_BINDTODEVICE`](#SRTO_BINDTODEVICE) | 1.4.2 | pre-bind | `string` | | | | RW | GSD+ | +| [`SRTO_CONGESTION`](#SRTO_CONGESTION) | 1.3.0 | pre | `string` | | "live" | \* | W | S | +| [`SRTO_CONNTIMEO`](#SRTO_CONNTIMEO) | 1.1.2 | pre | `int32_t` | ms | 3000 | 0.. | W | GSD+ | +| [`SRTO_DRIFTTRACER`](#SRTO_DRIFTTRACER) | 1.4.2 | post | `bool` | | true | | RW | GSD | +| [`SRTO_ENFORCEDENCRYPTION`](#SRTO_ENFORCEDENCRYPTION) | 1.3.2 | pre | `bool` | | true | | W | GSD | +| [`SRTO_EVENT`](#SRTO_EVENT) | | | `int32_t` | flags | | | R | S | +| [`SRTO_FC`](#SRTO_FC) | | pre | `int32_t` | pkts | 25600 | 32.. | RW | GSD | +| [`SRTO_GROUPCONNECT`](#SRTO_GROUPCONNECT) | 1.5.0 | pre | `int32_t` | | 0 | 0...1 | W | S | +| [`SRTO_GROUPMINSTABLETIMEO`](#SRTO_GROUPMINSTABLETIMEO) | 1.5.0 | pre | `int32_t` | ms | 60 | 60-... | W | GDI+ | +| [`SRTO_GROUPTYPE`](#SRTO_GROUPTYPE) | 1.5.0 | | `int32_t` | enum | | | R | S | +| [`SRTO_INPUTBW`](#SRTO_INPUTBW) | 1.0.5 | post | `int64_t` | B/s | 0 | 0.. | RW | GSD | +| [`SRTO_IPTOS`](#SRTO_IPTOS) | 1.0.5 | pre-bind | `int32_t` | | (system) | 0..255 | RW | GSD | +| [`SRTO_IPTTL`](#SRTO_IPTTL) | 1.0.5 | pre-bind | `int32_t` | hops | (system) | 1..255 | RW | GSD | +| [`SRTO_IPV6ONLY`](#SRTO_IPV6ONLY) | 1.4.0 | pre-bind | `int32_t` | | (system) | -1..1 | RW | GSD | +| [`SRTO_ISN`](#SRTO_ISN) | 1.3.0 | | `int32_t` | | | | R | S | +| [`SRTO_KMPREANNOUNCE`](#SRTO_KMPREANNOUNCE) | 1.3.2 | pre | `int32_t` | pkts | 0: 212 | 0.. \* | RW | GSD | +| [`SRTO_KMREFRESHRATE`](#SRTO_KMREFRESHRATE) | 1.3.2 | pre | `int32_t` | pkts | 0: 224 | 0.. | RW | GSD | +| [`SRTO_KMSTATE`](#SRTO_KMSTATE) | 1.0.2 | | `int32_t` | enum | | | R | S | +| [`SRTO_LATENCY`](#SRTO_LATENCY) | 1.0.2 | pre | `int32_t` | ms | 120 \* | 0.. | RW | GSD | +| [`SRTO_LINGER`](#SRTO_LINGER) | | post | `linger` | s | off \* | 0.. | RW | GSD | +| [`SRTO_LOSSMAXTTL`](#SRTO_LOSSMAXTTL) | 1.2.0 | post | `int32_t` | packets | 0 | 0.. | RW | GSD+ | +| [`SRTO_MAXBW`](#SRTO_MAXBW) | | post | `int64_t` | B/s | -1 | -1.. | RW | GSD | +| [`SRTO_MESSAGEAPI`](#SRTO_MESSAGEAPI) | 1.3.0 | pre | `bool` | | true | | W | GSD | +| [`SRTO_MININPUTBW`](#SRTO_MININPUTBW) | 1.4.3 | post | `int64_t` | B/s | 0 | 0.. | RW | GSD | +| [`SRTO_MINVERSION`](#SRTO_MINVERSION) | 1.3.0 | pre | `int32_t` | version | 0x010000 | \* | RW | GSD | +| [`SRTO_MSS`](#SRTO_MSS) | | pre-bind | `int32_t` | bytes | 1500 | 76.. | RW | GSD | +| [`SRTO_NAKREPORT`](#SRTO_NAKREPORT) | 1.1.0 | pre | `bool` | | \* | | RW | GSD+ | +| [`SRTO_OHEADBW`](#SRTO_OHEADBW) | 1.0.5 | post | `int32_t` | % | 25 | 5..100 | RW | GSD | +| [`SRTO_PACKETFILTER`](#SRTO_PACKETFILTER) | 1.4.0 | pre | `string` | | "" | [512] | RW | GSD | +| [`SRTO_PASSPHRASE`](#SRTO_PASSPHRASE) | 0.0.0 | pre | `string` | | "" | [10..79] | W | GSD | +| [`SRTO_PAYLOADSIZE`](#SRTO_PAYLOADSIZE) | 1.3.0 | pre | `int32_t` | bytes | \* | 0.. \* | W | GSD | +| [`SRTO_PBKEYLEN`](#SRTO_PBKEYLEN) | 0.0.0 | pre | `int32_t` | bytes | 0 | \* | RW | GSD | +| [`SRTO_PEERIDLETIMEO`](#SRTO_PEERIDLETIMEO) | 1.3.3 | pre | `int32_t` | ms | 5000 | 0.. | RW | GSD+ | +| [`SRTO_PEERLATENCY`](#SRTO_PEERLATENCY) | 1.3.0 | pre | `int32_t` | ms | 0 | 0.. | RW | GSD | +| [`SRTO_PEERVERSION`](#SRTO_PEERVERSION) | 1.1.0 | | `int32_t` | * | | | R | GS | +| [`SRTO_RCVBUF`](#SRTO_RCVBUF) | | pre-bind | `int32_t` | bytes | 8192 payloads | \* | RW | GSD+ | +| [`SRTO_RCVDATA`](#SRTO_RCVDATA) | | | `int32_t` | pkts | | | R | S | +| [`SRTO_RCVKMSTATE`](#SRTO_RCVKMSTATE) | 1.2.0 | | `int32_t` | enum | | | R | S | +| [`SRTO_RCVLATENCY`](#SRTO_RCVLATENCY) | 1.3.0 | pre | `int32_t` | msec | \* | 0.. | RW | GSD | +| [`SRTO_RCVSYN`](#SRTO_RCVSYN) | | post | `bool` | | true | | RW | GSI | +| [`SRTO_RCVTIMEO`](#SRTO_RCVTIMEO) | | post | `int32_t` | ms | -1 | -1, 0.. | RW | GSI | +| [`SRTO_RENDEZVOUS`](#SRTO_RENDEZVOUS) | | pre | `bool` | | false | | RW | S | +| [`SRTO_RETRANSMITALGO`](#SRTO_RETRANSMITALGO) | 1.4.2 | pre | `int32_t` | | 1 | [0, 1] | RW | GSD | +| [`SRTO_REUSEADDR`](#SRTO_REUSEADDR) | | pre-bind | `bool` | | true | | RW | GSD | +| [`SRTO_SENDER`](#SRTO_SENDER) | 1.0.4 | pre | `bool` | | false | | W | S | +| [`SRTO_SNDBUF`](#SRTO_SNDBUF) | | pre-bind | `int32_t` | bytes | 8192 payloads | \* | RW | GSD+ | +| [`SRTO_SNDDATA`](#SRTO_SNDDATA) | | | `int32_t` | pkts | | | R | S | +| [`SRTO_SNDDROPDELAY`](#SRTO_SNDDROPDELAY) | 1.3.2 | post | `int32_t` | ms | \* | -1.. | W | GSD+ | +| [`SRTO_SNDKMSTATE`](#SRTO_SNDKMSTATE) | 1.2.0 | | `int32_t` | enum | | | R | S | +| [`SRTO_SNDSYN`](#SRTO_SNDSYN) | | post | `bool` | | true | | RW | GSI | +| [`SRTO_SNDTIMEO`](#SRTO_SNDTIMEO) | | post | `int32_t` | ms | -1 | -1.. | RW | GSI | +| [`SRTO_STATE`](#SRTO_STATE) | | | `int32_t` | enum | | | R | S | +| [`SRTO_STREAMID`](#SRTO_STREAMID) | 1.3.0 | pre | `string` | | "" | [512] | RW | GSD | +| [`SRTO_TLPKTDROP`](#SRTO_TLPKTDROP) | 1.0.6 | pre | `bool` | | \* | | RW | GSD | +| [`SRTO_TRANSTYPE`](#SRTO_TRANSTYPE) | 1.3.0 | pre | `int32_t` | enum |`SRTT_LIVE` | \* | W | S | +| [`SRTO_TSBPDMODE`](#SRTO_TSBPDMODE) | 0.0.0 | pre | `bool` | | \* | | W | S | +| [`SRTO_UDP_RCVBUF`](#SRTO_UDP_RCVBUF) | | pre-bind | `int32_t` | bytes | 8192 payloads | \* | RW | GSD+ | +| [`SRTO_UDP_SNDBUF`](#SRTO_UDP_SNDBUF) | | pre-bind | `int32_t` | bytes | 65536 | \* | RW | GSD+ | +| [`SRTO_VERSION`](#SRTO_VERSION) | 1.1.0 | | `int32_t` | | | | R | S | + +### Option Descriptions + +#### SRTO_BINDTODEVICE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir |Entity| +| --------------------- | ----- | -------- | -------- | ------ | -------- | ------ |-----|------| +| `SRTO_BINDTODEVICE` | 1.4.2 | pre-bind | `string` | | | | RW | GSD+ | + +Refers to the `SO_BINDTODEVICE` system socket option for `SOL_SOCKET` level. +This effectively limits the packets received by this socket to only those +that are targeted to that device. The device is specified by name passed as +string. The setting becomes effective after binding the socket (including +default-binding when connecting). + +NOTE: This option is only available on Linux and available there by default. +On all other platforms setting this option will always fail. + +NOTE: With the default system configuration, this option is only available +for a process that runs as root. Otherwise the function that applies the setting +(`srt_bind`, `srt_connect` etc.) will fail. + +[Return to list](#list-of-options) + +--- + +#### SRTO_CONGESTION + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_CONGESTION` | 1.3.0 | pre | `string` | | "live" | * | W | S | + +The type of congestion controller used for the transmission for that socket. + +Its type must be exactly the same on both connecting parties, otherwise the +connection is rejected - **however** you may also change the value of this +option for the accepted socket in the listener callback (see `srt_listen_callback`) +if an appropriate instruction was given in the Stream ID. + +Currently supported congestion controllers are designated as "live" and "file" + +Note that it is not recommended to change this option manually, but you should +rather change the whole set of options using the [`SRTO_TRANSTYPE`](#SRTO_TRANSTYPE) option. + +[Return to list](#list-of-options) + +--- + +#### SRTO_CONNTIMEO + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ------------------ | ----- | -------- | --------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_CONNTIMEO` | 1.1.2 | pre | `int32_t` | msec | 3000 | 0.. | W | GSD+ | + +Connect timeout. This option applies to the caller and rendezvous connection +modes. For the rendezvous mode (see `SRTO_RENDEZVOUS`) the effective connection timeout +will be 10 times the value set with `SRTO_CONNTIMEO`. + +[Return to list](#list-of-options) + +--- + +#### SRTO_DRIFTTRACER + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | --------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_DRIFTTRACER`| 1.4.2 | post | `bool` | | true | | RW | GSD | + +Enables or disables time drift tracer (receiver). + +[Return to list](#list-of-options) + +--- + +#### SRTO_ENFORCEDENCRYPTION + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_ENFORCEDENCRYPTION` | 1.3.2 | pre | `bool` | | true | | W | GSD | + +This option enforces that both connection parties have the same passphrase +set, or both do not set the passphrase, otherwise the connection is rejected. + +When this option is set to FALSE **on both connection parties**, the +connection is allowed even if the passphrase differs on both parties, +or it was set only on one party. Note that the party that has set a passphrase +is still allowed to send data over the network. However, the receiver will not +be able to decrypt that data and will not deliver it to the application. The +party that has set no passphrase can send (unencrypted) data that will be +successfully received by its peer. + +This option can be used in some specific situations when the user knows +both parties of the connection, so there's no possible situation of a rogue +sender and can be useful in situations where it is important to know whether a +connection is possible. The inability to decrypt an incoming transmission can +be then reported as a different kind of problem. + +**IMPORTANT**: There is unusual and unobvious behavior when this flag is TRUE +on the caller and FALSE on the listener, and the passphrase was mismatched. On +the listener side the connection will be established and broken right after, +resulting in a short-lived "spurious" connection report on the listener socket. +This way, a socket will be available for retrieval from an `srt_accept` call +for a very short time, after which it will be removed from the listener backlog +just as if no connection attempt was made at all. If the application is fast +enough to react on an incoming connection, it will retrieve it, only to learn +that it is already broken. This also makes possible a scenario where +`SRT_EPOLL_IN` is reported on a listener socket, but then an `srt_accept` call +reports an `SRT_EASYNCRCV` error. How fast the connection gets broken depends +on the network parameters -- in particular, whether the `UMSG_SHUTDOWN` message +sent by the caller is delivered (which takes one RTT in this case) or missed +during the interval from its creation up to the connection timeout (default = 5 +seconds). It is therefore strongly recommended that you only set this flag to +FALSE on the listener when you are able to ensure that it is also set to FALSE +on the caller side. + +[Return to list](#list-of-options) + +--- + +#### SRTO_EVENT + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | --------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_EVENT` | | | `int32_t` | flags | | | R | S | + +Returns bit flags set according to the current active events on the socket. + +Possible values are those defined in `SRT_EPOLL_OPT` enum (a combination of +`SRT_EPOLL_IN`, `SRT_EPOLL_OUT` and `SRT_EPOLL_ERR`). + +[Return to list](#list-of-options) + +--- + +#### SRTO_FC + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | --------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_FC` | | pre | `int32_t` | pkts | 25600 | 32.. | RW | GSD | + +Flow Control limits the maximum number of packets "in flight" - payload (data) packets that were sent +but reception is not yet acknowledged with an ACK control packet. +It also includes data packets already received, but that can't be acknowledged due to loss of preceding data packet(s). +In other words, if a data packet with sequence number `A` was lost, then acknowledgement of the following `SRTO_FC` packets +is blocked until packet `A` is either successfully retransmitted or dropped by the +[Too-Late Packet Drop mechanism](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-00#section-4.6). +Thus the sender will have `SRTO_FC` packets in flight, and will not be allowed to send further data packets. +Therefore, when establishing the value of `SRTO_FC`, it is recommend taking into consideration possible delays due to packet loss and retransmission. + +There is a restriction that the receiver buffer size ([SRTO_RCVBUF](#SRTO_RCVBUF)) must not be greater than `SRTO_FC` +([#700](https://github.com/Haivision/srt/issues/700)). +Therefore, it is recommended to set the value of `SRTO_FC` first, and then the value of `SRTO_RCVBUF`. + +The default flow control window size is 25600 packets. It is approximately: +- 270 Mbits of payload in the default live streaming configuration with an SRT payload size of 1316 bytes; +- 300 Mbits of payload with an SRT payload size of 1456 bytes. + +The minimum number of packets in flight should be (assuming max payload size): +`FCmin = bps / 8 × RTTsec / (MSS - 44)`, +where +- `bps` - is the payload bitrate of the stream in bits per second; +- `RTTsec` - RTT of the network connection in seconds; +- `MSS` - Maximum segment size (aka MTU), see [SRTO_MSS](#SRTO_MSS); +- 44 - size of headers (20 bytes IPv4 + 8 bytes of UDP + 16 bytes of SRT packet header). + +To avoid blocking the sending of further packets in case of packet loss, the recommended flow control window is +`FC = bps / 8 × (RTTsec + latency_sec) / (MSS - 44)`, +where `latency_sec` is the receiver buffering delay ([SRTO_RCVLATENCY](#SRTO_RCVLATENCY)) **in seconds**. + +[Return to list](#list-of-options) + +--- + +#### SRTO_GROUPCONNECT + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | --------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_GROUPCONNECT` | 1.5.0 | pre | `int32_t` | | 0 | 0...1 | W | S | + +When this flag is set to 1 on a listener socket, it allows this socket to +accept group connections. When set to the default 0, group connections will be +rejected. Keep in mind that if the `SRTO_GROUPCONNECT` flag is set to 1 (i.e. +group connections are allowed) `srt_accept` may return a socket **or** a group +ID. A call to `srt_accept` on a listener socket that has group connections +allowed must take this into consideration. It's up to the caller of this +function to make this distinction and to take appropriate action depending on +the type of entity returned. + +When this flag is set to 1 on an accepted socket that is passed to the +listener callback handler, it means that this socket is created for a group +connection and it will become a member of a group. Note that in this case +only the first connection within the group will result in reporting from +`srt_accept` (further connections are handled in the background), and this +function will return the group, not this socket ID. + +[Return to list](#list-of-options) + +--- + +#### SRTO_GROUPMINSTABLETIMEO + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_GROUPMINSTABLETIMEO` | 1.5.0 | pre | `int32_t` | ms | 60 | 60-... | W | GDI+ | + +The option is used for groups of type `SRT_GTYPE_BACKUP`. It defines the **minimum** value of the stability +timeout for all active member sockets in a group. +The actual timeout value is determined in runtime based on the RTT estimate of an individual member socket. +If there is no response from the peer for the calculated timeout, +the member is considered unstable, triggering activation of an idle backup member. + +The smaller the value is, the earlier a backup member might be activated to prepare transition to that path. +However, it may also lead to spurious activations of backup paths. +The higher the value is, the later the backup link would be activated. All unacknowledged payload packets +have to be retransmitted through the backup path. If they don't reach the receiver in time, they would be dropped. +Therefore, an appropriate adjustment of the SRT buffering delay +(`SRTO_PEERLATENCY` on sender, `SRTO_RCVLATENCY` on receiver) should also be considered. + +Normally the receiver should send an ACK back to the sender every 10 ms. In the case of congestion, +in the live streaming configuration of SRT a loss report is expected to be sent every RTT/2. +The network jitter and increase of RTT on the public internet causes +these intervals to be stretched. +The default minimum value of 60 ms is selected as a general fit for most of the use cases. + +Please refer to the [SRT Connection Bonding: Main/Backup](../features/bonding-main-backup.md) document for more details. + +Note that the value of this option is not allowed to exceed the value of +`SRTO_PEERIDLETIMEO`, which determines the timeout to actually break an idle (irresponsive) connection. + +[Return to list](#list-of-options) + +--- + +#### SRTO_GROUPTYPE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_GROUPTYPE` | 1.5.0 | | `int32_t` | enum | | | R | S | + +This option is read-only and it is intended to be called inside the listener +callback handler (see `srt_listen_callback`). Possible values are defined in +the `SRT_GROUP_TYPE` enumeration type. + +This option returns the group type that is declared in the incoming connection. +If the incoming connection is not going to make a group-member connection, then +the value returned is `SRT_GTYPE_UNDEFINED`. If this option is read in any other +context than inside the listener callback handler, the value is undefined. + +[Return to list](#list-of-options) + +--- + +#### SRTO_INPUTBW + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ---------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_INPUTBW` | 1.0.5 | post | `int64_t` | B/s | 0 | 0.. | RW | GSD | + +This option is effective only if [`SRTO_MAXBW`](#SRTO_MAXBW) is set to 0 (relative). It +controls the maximum bandwidth together with [`SRTO_OHEADBW`](#SRTO_OHEADBW) option according +to the formula: `MAXBW = INPUTBW * (100 + OHEADBW) / 100`. When this option +is set to 0 (automatic) then the real INPUTBW value will be estimated from +the rate of the input (cases when the application calls the `srt_send*` +function) during transmission. The minimum allowed estimate value is restricted +by [`SRTO_MININPUTBW`](#SRTO_MININPUTBW), meaning `INPUTBW = MAX(INPUTBW_ESTIMATE; MININPUTBW)`. + +*Recommended: set this option to the anticipated bitrate of your live stream +and keep the default 25% value for `SRTO_OHEADBW`*. + +[Return to list](#list-of-options) + +--- + +#### SRTO_MININPUTBW + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_MININPUTBW` | 1.4.3 | post | `int64_t` | B/s | 0 | 0.. | RW | GSD | + +This option is effective only if both `SRTO_MAXBW` and `SRTO_INPUTBW` are set to 0. +It controls the minimum allowed value of the input bitrate estimate. + +See [`SRTO_INPUTBW`](#SRTO_INPUTBW). + +[Return to list](#list-of-options) + +--- + +#### SRTO_IPTOS + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ---------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_IPTOS` | 1.0.5 | pre-bind | `int32_t` | | (system) | 0..255 | RW | GSD | + +IPv4 Type of Service (see `IP_TOS` option for IP) or IPv6 Traffic Class (see `IPV6_TCLASS` +of IPv6) depending on socket address family. Applies to sender only. + +When *getting*, the returned value is the user preset for non-connected sockets +and the actual value for connected sockets. + +*Sender*: user configurable, default: `0xB8`. + +[Return to list](#list-of-options) + +--- + +#### SRTO_IPTTL + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ---------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_IPTTL` | 1.0.5 | pre-bind | `int32_t` | hops | (system) | 1..255 | RW | GSD | + +IPv4 Time To Live (see `IP_TTL` option for IP) or IPv6 unicast hops (see +`IPV6_UNICAST_HOPS` for IPv6) depending on socket address family. Applies to sender only. + +When *getting*, the returned value is the user preset for non-connected sockets +and the actual value for connected sockets. + +*Sender*: user configurable, default: 64 + +[Return to list](#list-of-options) + +--- + +#### SRTO_IPV6ONLY + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ---------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_IPV6ONLY` | 1.4.0 | pre-bind | `int32_t` | | (system) | -1..1 | RW | GSD | + +Set system socket flag `IPV6_V6ONLY`. When set to 0 a listening socket binding an +IPv6 address accepts also IPv4 clients (their addresses will be formatted as +IPv4-mapped IPv6 addresses). By default (-1) this option is not set and the +platform default value is used. + +[Return to list](#list-of-options) + +--- + +#### SRTO_ISN + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ---------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_ISN` | 1.3.0 | | `int32_t` | | | | R | S | + +The value of the ISN (Initial Sequence Number), which is the first sequence +number put on the first UDP packets sent that are carrying an SRT data payload. + +*This value is useful for developers of some more complicated methods of flow +control, possibly with multiple SRT sockets at a time. It is not intended to be +used in any regular development.* + +[Return to list](#list-of-options) + +--- + +#### SRTO_KMPREANNOUNCE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| --------------------- | ----- | -------- | ---------- | ------ | ----------------- | ------ | --- | ------ | +| `SRTO_KMPREANNOUNCE` | 1.3.2 | pre | `int32_t` | pkts | 0: 212 | 0.. * | RW | GSD | + +The interval (defined in packets) between when a new Stream Encrypting Key +(SEK) is sent and when switchover occurs. This value also applies to the +subsequent interval between when switchover occurs and when the old SEK is +decommissioned. + +At `SRTO_KMPREANNOUNCE` packets before switchover the new key is sent +(repeatedly, if necessary, until it is confirmed by the receiver). + +At the switchover point (see `SRTO_KMREFRESHRATE`), the sender starts +encrypting and sending packets using the new key. The old key persists in case +it is needed to decrypt packets that were in the flight window, or +retransmitted packets. + +The old key is decommissioned at `SRTO_KMPREANNOUNCE` packets after switchover. + +**The allowed range** for this value is between 1 and half of the current value of +`SRTO_KMREFRESHRATE`. The minimum value should never be less than the flight +window [`SRTO_FC`](#SRTO_FC) (i.e. the number of packets that have already left the sender but have +not yet arrived at the receiver). + +The value of `SRTO_KMPREANNOUNCE must not exceed `(SRTO_KMREFRESHRATE - 1) / 2`. + +**Default value:** `0` - corresponds to 4096 packets (212 or 0x1000). + +[Return to list](#list-of-options) + +--- + +#### SRTO_KMREFRESHRATE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| --------------------- | ----- | -------- | ---------- | ------ | ---------------- | ------ | --- | ------ | +| `SRTO_KMREFRESHRATE` | 1.3.2 | pre | `int32_t` | pkts | 0: 224| 0.. | RW | GSD | + +The number of packets to be transmitted after which the Stream Encryption Key +(SEK), used to encrypt packets, will be switched to the new one. Note that +the old and new keys live in parallel for a certain period of time (see +`SRTO_KMPREANNOUNCE`) before and after the switchover. + +Having a preannounce period before switchover ensures the new SEK is installed +at the receiver before the first packet encrypted with the new SEK is received. +The old key remains active after switchover in order to decrypt packets that +might still be in flight, or packets that have to be retransmitted. + +**Default value:** `0` - corresponds to 16777216 packets (224 or 0x1000000). + +[Return to list](#list-of-options) + +--- + +#### SRTO_KMSTATE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| --------------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_KMSTATE` | 1.0.2 | | `int32_t` | enum | | | R | S | + +Keying Material state. This is a legacy option that is equivalent to +`SRTO_SNDKMSTATE`, if the socket has set `SRTO_SENDER` to true, and +`SRTO_RCVKMSTATE` otherwise. This option is then equal to `SRTO_RCVKMSTATE` +always if your application disregards possible cooperation with a peer older +than 1.3.0, but then with the default value of `SRTO_ENFORCEDENCRYPTION` the +value returned by both options is always the same. See [`SRT_KM_STATE`](#2-srt_km_state) +for more details. + +[Return to list](#list-of-options) + +--- + +#### SRTO_LATENCY + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| --------------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_LATENCY` | 1.0.2 | pre | `int32_t` | ms | 120 * | 0.. | RW | GSD | + +This option sets both [`SRTO_RCVLATENCY`](#SRTO_RCVLATENCY) and [`SRTO_PEERLATENCY`](#SRTO_PEERLATENCY) +to the same value specified. + +Prior to SRT version 1.3.0 `SRTO_LATENCY` was the only option to set the latency. +However it is effectively equivalent to setting `SRTO_PEERLATENCY` in the sending direction +(see [`SRTO_SENDER`](#SRTO_SENDER)), and `SRTO_RCVLATENCY` in the receiving direction. +SRT version 1.3.0 and higher support bidirectional transmission, so that each side can +be sender and receiver at the same time, and `SRTO_SENDER` became redundant. + +[Return to list](#list-of-options) + +--- + +#### SRTO_LINGER + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ | +| `SRTO_LINGER` | | pre | `linger` | s | off \* | 0.. | RW | GSD | + +SRT socket linger time on close (similar to [SO\_LINGER](http://man7.org/linux/man-pages/man7/socket.7.html)). +The defulat value in [the live streaming configuration](./API.md#transmission-types) is OFF. In this type of workflow there is no point for wait for all the data +to be delivered after a connection is closed. +The default value in [the file transfer configuration](./API.md#transmission-types) is 180 s. + + +*SRT recommended value*: off (0). + +[Return to list](#list-of-options) + +--- + +#### SRTO_LOSSMAXTTL + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_LOSSMAXTTL` | 1.2.0 | post | `int32_t` | packets | 0 | 0.. | RW | GSD+ | + +The value up to which the *Reorder Tolerance* may grow. The *Reorder Tolerance* +is the number of packets that must follow the experienced "gap" in sequence numbers +of incoming packets so that the loss report is sent (in the hope that the gap is due +to packet reordering rather than because of loss). The value of *Reorder Tolerance* +starts from 0 and is set to a greater value when packet reordering is detected +This happens when a "belated" packet, with sequence number older than the latest +received, has been received, but without retransmission flag. When this is detected +the *Reorder Tolerance* is set to the value of the interval between latest sequence +and this packet's sequence, but not more than the value set by `SRTO_LOSSMAXTTL`. +By default this value is set to 0, which means that this mechanism is off. + +[Return to list](#list-of-options) + +--- + +#### SRTO_MAXBW + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_MAXBW` | 1.0.5 | post | `int64_t` | B/s | -1 | -1.. | RW | GSD | + +Maximum send bandwidth: + +- `-1`: infinite (the limit in Live Mode is 1 Gbps); +- `0`: relative to input rate (see [`SRTO_INPUTBW`](#SRTO_INPUTBW)); +- `>0`: absolute limit in B/s. + +**NOTE**: This option has a default value of -1, regardless of the mode. +For live streams it is typically recommended to set the value 0 here and rely +on `SRTO_INPUTBW` and `SRTO_OHEADBW` options. However, if you want to do so, +you should make sure that your stream has a fairly constant bitrate, or that +changes are not abrupt, as high bitrate changes may work against the +measurement. SRT cannot ensure that this is always the case for a live stream, +therefore the default -1 remains even in live mode. + +[Return to list](#list-of-options) + +--- + +#### SRTO_MESSAGEAPI + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_MESSAGEAPI` | 1.3.0 | pre | `bool` | | true | | W | GSD | + +When set, this socket uses the Message API[\*], otherwise it uses the +Stream API. Note that in live mode (see [`SRTO_TRANSTYPE`](#SRTO_TRANSTYPE) option) only the +Message API is available. In File mode you can chose to use one of two modes +(note that the default for this option is changed with `SRTO_TRANSTYPE` +option): + +- **Stream API** (default for file mode): In this mode you may send +as many data as you wish with one sending instruction, or even use dedicated +functions that operate directly on a file. The internal facility will take care +of any speed and congestion control. When receiving, you can also receive as +many data as desired. The data not extracted will be waiting for the next call. +There is no boundary between data portions in Stream mode. + +- **Message API**: In this mode your single sending instruction passes exactly +one piece of data that has boundaries (a message). Contrary to Live mode, +this message may span multiple UDP packets, and the only size limitation +is that it shall fit as a whole in the sending buffer. The receiver shall use +as large a buffer as necessary to receive the message, otherwise reassembling +and delivering the message might not be possible. When the message is not +complete (not all packets received or there was a packet loss) it will not be +copied to the application's buffer. Messages that are sent later, but were +earlier reassembled by the receiver, will be delivered once ready, if the +`inorder` flag was set to false. +See [`srt_sendmsg`](API.md#sending-and-receiving). + +As a comparison to the standard system protocols, the Stream API does +transmission similar to TCP, whereas the Message API functions like the +SCTP protocol. + +[Return to list](#list-of-options) + +--- + +#### SRTO_MINVERSION + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_MINVERSION` | 1.3.0 | pre | `int32_t` | version | 0x010000 | * | RW | GSD | + +The minimum SRT version that is required from the peer. A connection to a +peer that does not satisfy the minimum version requirement will be rejected. +See [`SRTO_VERSION`](#SRTO_VERSION) for the version format. + +The default value is 0x010000 (SRT v1.0.0). + +[Return to list](#list-of-options) + +--- + +#### SRTO_MSS + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_MSS` | | pre-bind | `int32_t` | bytes | 1500 | 76.. | RW | GSD | + +Maximum Segment Size. Used for buffer allocation and rate calculation using +packet counter assuming fully filled packets. Each party can set its own MSS +value independently. During a handshake the parties exchange MSS values, and +the lowest is used. + +*Generally on the internet MSS is 1500 by default. This is the maximum +size of a UDP packet and can be only decreased, unless you have some unusual +dedicated network settings. MSS is not to be confused with the size of the UDP +payload or SRT payload - this size is the size of the IP packet, including the +UDP and SRT headers* + +THe value of `SRTO_MSS` must not exceed `SRTO_UDP_SNDBUF` or `SRTO_UDP_RCVBUF`. + +[Return to list](#list-of-options) + +--- + +#### SRTO_NAKREPORT + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_NAKREPORT` | 1.1.0 | pre | `bool` | | * | | RW | GSD+ | + +When set to true, every report for a detected loss will be repeated when the +timeout for the expected retransmission of this loss has expired and the +missing packet still wasn't recovered, or wasn't conditionally dropped (see +[`SRTO_TLPKTDROP`](#SRTO_TLPKTDROP)). + +The default is true for Live mode, and false for File mode (see [`SRTO_TRANSTYPE`](#SRTO_TRANSTYPE)). + +[Return to list](#list-of-options) + +--- + +#### SRTO_OHEADBW + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_OHEADBW` | 1.0.5 | post | `int32_t` | % | 25 | 5..100 | RW | GSD | + +Recovery bandwidth overhead above input rate (see [`SRTO_INPUTBW`](#SRTO_INPUTBW)), +in percentage of the input rate. It is effective only if `SRTO_MAXBW` is set to 0. + +*Sender*: user configurable, default: 25%. + +Recommendations: + +- Overhead is intended to give you extra bandwidth for the case when a packet +has taken part of the bandwidth, but then was lost and has to be retransmitted. +Therefore the effective maximum bandwidth should be appropriately higher than +your stream's bitrate so that there's some room for retransmission, but still +limited so that the retransmitted packets don't cause the bandwidth usage to +skyrocket when larger groups of packets are lost + +- Don't configure it too low and avoid 0 in the case when you have the +`SRTO_INPUTBW` option set to 0 (automatic). Otherwise your stream will choke +and break quickly at any rise in packet loss. + +- ***To do: set-only; get should be supported.*** + +[Return to list](#list-of-options) + +--- + +#### SRTO_PACKETFILTER + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_PACKETFILTER` | 1.4.0 | pre | `string` | | "" | [512] | RW | GSD | + +Set up the packet filter. The string must match appropriate syntax for packet +filter setup. Note also that: + +* The configuration is case-sentitive (e.g. "FEC,Cols:20" is not valid). +* Setting this option will fail if you use an unknown filter type. + +An empty value for this option means that for this connection the filter isn't +required, but it will accept any filter settings if provided by the peer. If +this option is changed by both parties simultaneously, the result will be a +configuration integrating parameters from both parties, that is: + +* parameters provided by both parties are accepted, if they are identical +* parameters that are set only on one side will have the value defined by that side +* parameters not set in either side will be set as default + +The connection will be rejected with `SRT_REJ_FILTER` code in the following cases: + +* both sides define a different packet filter type +* for the same key two different values were provided by both sides +* mandatory parameters weren't provided by either side + +In case of the built-in `fec` filter, the mandatory parameter is `cols`, all +others have their default values. For example, the configuration specified +as `fec,cols:10` is `fec,cols:10,rows:1,arq:onreq,layout:even`. See how to +configure the FEC filter in [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md#configuring-the-fec-filter). + +Below in the table are examples for the built-in `fec` filter. Note that the +negotiated config need not have parameters in the given order. + +Cases when negotiation succeeds: + +| Peer A | Peer B | Negotiated Config +|----------------------|---------------------|------------------------------------------------------ +| (no filter) | (no filter) | +| fec,cols:10 | fec | fec,cols:10,rows:1,arq:onreq,layout:even +| fec,cols:10 | fec,cols:10,rows:20 | fec,cols:10,rows:20,arq:onreq,layout:even +| fec,layout:staircase | fec,cols:10 | fec,cols:10,rows:1,arq:onreq,layout:staircase + +In these cases the configuration is rejected with SRT_REJ_FILTER code: + +| Peer A | Peer B | Error reason +|-----------------------|---------------------|-------------------------- +| fec | (no filter) | missing `cols` parameter +| fec,rows:20,arq:never | fec,layout:even | missing `cols` parameter +| fec,cols:20 | fec,cols:10 | `cols` parameter value conflict +| fec,cols:20,rows:20 | fec,cols:20,rows:10 | `rows` parameter value conflict + +In general it is recommended that one party defines the full configuration, +while the other keeps this value empty. + +Reading this option after the connection is established will return the full +configuration that has been agreed upon by both parties (including default +values). + +For details, see [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md). + +[Return to list](#list-of-options) + +--- + +#### SRTO_PASSPHRASE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_PASSPHRASE` | 0.0.0 | pre | `string` | | "" |[10..79]| W | GSD | + +Sets the passphrase for encryption. This enables encryption on this party (or +disables it, if an empty passphrase is passed). The password must be minimum +10 and maximum 79 characters long. + +The passphrase is the shared secret between the sender and the receiver. It is +used to generate the Key Encrypting Key using [PBKDF2](http://en.wikipedia.org/wiki/PBKDF2) +(Password-Based Key Derivation Function 2). + +When a socket with configured passphrase is being connected, the peer must +have the same password set, or the connection is rejected. This behavior can be +changed by [`SRTO_ENFORCEDENCRYPTION`](#SRTO_ENFORCEDENCRYPTION). + +Note that since the introduction of bidirectional support, there's only one +initial encryption key to encrypt the stream (new keys after refreshing will be +updated independently), and there's no distinction between "service party that +defines the password" and "client party that is required to set matching +password" - both parties are equivalent, and in order to have a working +encrypted connection, they have to simply set the same passphrase. + +[Return to list](#list-of-options) + +--- + +#### SRTO_PAYLOADSIZE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_PAYLOADSIZE` | 1.3.0 | pre | `int32_t` | bytes | \* | 0.. \* | W | GSD | + +Sets the maximum declared size of a single call to sending function in Live +mode. When set to 0, there's no limit for a single sending call. + +For Live mode: Default value is 1316, but can be increased up to 1456. Note that +with the `SRTO_PACKETFILTER` option additional header space is usually required, +which decreases the maximum possible value for `SRTO_PAYLOADSIZE`. + +For File mode: Default value is 0 and it's recommended not to be changed. + +[Return to list](#list-of-options) + +--- + +#### SRTO_PBKEYLEN + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_PBKEYLEN` | 0.0.0 | pre | `int32_t` | bytes | 0 | * | RW | GSD | + +Encryption key length. + +Possible values: + +- 0 =`PBKEYLEN` (default value) +- 16 = AES-128 (effective value) +- 24 = AES-192 +- 32 = AES-256 + +The use is slightly different in 1.2.0 (HSv4), and since 1.3.0 (HSv5): + +- **HSv4**: This is set on the sender and enables encryption, if not 0. The receiver +shall not set it and will agree on the length as defined by the sender. + +- **HSv5**: The "default value" for `PBKEYLEN` is 0, which means that the +`PBKEYLEN` won't be advertised. The "effective value" for `PBKEYLEN` is 16, but +this applies only when neither party has set the value explicitly (i.e. when +both are initially at the default value of 0). If any party *has* set an +explicit value (16, 24, 32) it will be advertised in the handshake. If the other +party remains at the default 0, it will accept the peer's value. The situation +where both parties set a value should be treated carefully. Actually there are +three intended methods of defining it, and all other uses are considered +undefined behavior: + + - **Unidirectional**: the sender shall set `PBKEYLEN` and the receiver shall + not alter the default value 0. The effective `PBKEYLEN` will be the one set + on the sender. The receiver need not know the sender's `PBKEYLEN`, just the + passphrase, `PBKEYLEN` will be correctly passed. + + - **Bidirectional in Caller-Listener arrangement**: it is recommended to use + a rule whereby you will be setting the `PBKEYLEN` exclusively either on the + Listener or on the Caller. The value set on the Listener will win, if set on + both parties. + + - **Bidirectional in Rendezvous arrangement**: you have to know the passphrases + for both parties, as well as `PBKEYLEN`. Set `PBKEYLEN` to the same value on + both parties (or leave the default value on both parties, which will + result in 16) + + - **Unwanted behavior cases**: if both parties set `PBKEYLEN` and the value + on both sides is different, the effective `PBKEYLEN` will be the one that is + set on the Responder party, which may also override the `PBKEYLEN` 32 set by + the sender to value 16 if such value was used by the receiver. The Responder + party is the Listener in a Caller-Listener arrangement. In Rendezvous it's a + matter of luck which party becomes the Responder. + +[Return to list](#list-of-options) + +--- + +#### SRTO_PEERIDLETIMEO + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_PEERIDLETIMEO` | 1.3.3 | pre | `int32_t` | ms | 5000 | 0.. | RW | GSD+ | + +The maximum time in `[ms]` to wait until another packet is received from a peer +since the last such packet reception. If this time is passed, the connection is +considered broken on timeout. + +[Return to list](#list-of-options) + +--- + +#### SRTO_PEERLATENCY + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_PEERLATENCY` | 1.3.0 | pre | `int32_t` | ms | 0 | 0.. | RW | GSD | + +The latency value (as described in [`SRTO_RCVLATENCY`](#SRTO_RCVLATENCY)) provided by the sender +side as a minimum value for the receiver. + +Reading the value of the option on an unconnected socket reports the configured value. +Reading the value on a connected socket reports the effective receiver buffering latency of the peer. + +**The `SRTO_PEERLATENCY` option in versions prior to 1.3.0 is only available as** +[`SRTO_LATENCY`](#SRTO_LATENCY). + +See also [`SRTO_LATENCY`](#SRTO_LATENCY). + +[Return to list](#list-of-options) + +--- + +#### SRTO_PEERVERSION + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | -------- | ------ | --- | ------ | +| `SRTO_PEERVERSION` | 1.1.0 | | `int32_t` | * | | | R | GS | + +SRT version used by the peer. The value 0 is returned if not connected, SRT +handshake not yet performed (HSv4 only), or if peer is not SRT. +See [`SRTO_VERSION`](#SRTO_VERSION) for the version format. + +[Return to list](#list-of-options) + +--- + +#### SRTO_RCVBUF + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | ---------- | ------ | --- | ------ | +| `SRTO_RCVBUF` | | pre-bind | `int32_t` | bytes | 8192 bufs | * | RW | GSD+ | + +Receive Buffer Size, in bytes. Note, however, that the internal setting of this +value is in the number of buffers, each one of size equal to SRT payload size, +which is the value of `SRTO_MSS` decreased by UDP and SRT header sizes (28 and 16). +The value set here will be effectively aligned to the multiple of payload size. + +- **Minimum value**: 32 buffers (46592 with default value of `SRTO_MSS`). + +- **Maximum value**: [`SRTO_FC`](#SRTO_FC) number of buffers (receiver buffer must not be greater +than the Flight Flag size). + +[Return to list](#list-of-options) + +--- + +#### SRTO_RCVDATA + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | ---------- | ------ | --- | ------ | +| `SRTO_RCVDATA` | | | `int32_t` | pkts | | | R | S | + +Size of the available data in the receive buffer. + +[Return to list](#list-of-options) + +--- + +#### SRTO_RCVKMSTATE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | ---------- | ------ | --- | ------ | +| `SRTO_RCVKMSTATE` | 1.2.0 | | `int32_t` | enum | | | R | S | + +KM state on the agent side when it's a receiver. + +Values defined in enum [`SRT_KM_STATE`](#srt_km_state). + +[Return to list](#list-of-options) + +--- + +#### SRTO_RCVLATENCY + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | ---------- | ------ | --- | ------ | +| `SRTO_RCVLATENCY` | 1.3.0 | pre | `int32_t` | ms | * | 0.. | RW | GSD | + +The latency value in the receiving direction of the socket. +This value is only significant when [`SRTO_TSBPDMODE`](#SRTO_TSBPDMODE) is enabled. + +**Default value**: 120 ms in Live mode, 0 in File mode (see [`SRTO_TRANSTYPE`](#SRTO_TRANSTYPE)). + +The latency value defines the **minimum** receiver buffering delay before delivering an SRT data packet +from a receiving SRT socket to a receiving application. The provided value is used in the connection establishment (handshake exchange) stage +to fix the end-to-end latency of the transmission. The effective end-to-end latency `L` will be fixed +as the network transmission time of the final handshake packet (~1/2 RTT) plus the **negotiated** latency value `Ln`. +Data packets will stay in the receiver buffer for at least `L` microseconds since the timestamp of the +packet, independent of the actual network transmission times (RTT variations) of these packets. + +The actual value of the receiver buffering delay `Ln` (the negotiated latency) used on a connection +is determined by the negotiation in the connection establishment (handshake exchange) phase as the maximum of the +`SRTO_RCVLATENCY` value and the value of [`SRTO_PEERLATENCY`](#SRTO_PEERLATENCY) set by the peer. + +Reading the `SRTO_RCVLATENCY` value on a socket after the connection is established provides the actual (negotiated) +latency value `Ln`. + +The receiver's buffer must be large enough to store the `L` segment of the stream, +i.e. `L × Bitrate` bytes. Refer to [`SRTO_RCVBUF`](#SRTO_RCVBUF). + +The sender's buffer must be large enough to store a packet up until it is either delivered (and acknowledged) +or dropped by the sender due to it becoming too late to be delivered. +In other words, `D × Bitrate` bytes, where `D` is the sender's drop delay value configured with [`SRTO_SNDDROPDELAY`](#SRTO_SNDDROPDELAY). + +Buffering of data packets on the receiving side makes it possible to recover from packet losses using the ARQ +(Automatic Repeat Request) technique, and to deal with varying RTT times (network jitter) in the network, providing +a (close to) **constant end-to-end latency of the transmission**. + +See also [`SRTO_LATENCY`](#SRTO_LATENCY). + +[Return to list](#list-of-options) + +--- + +#### SRTO_RCVSYN + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | ---------- | ------ | --- | ------ | +| `SRTO_RCVSYN` | | post | `bool` | | true | | RW | GSI | + +When true, sets blocking mode on reading function when it's not ready to +perform the operation. When false ("non-blocking mode"), the reading function +will in this case report error `SRT_EASYNCRCV` and return immediately. Details +depend on the tested entity: + +On a connected socket or group this applies to a receiving function +(`srt_recv` and others) and a situation when there are no data available for +reading. The readiness state for this operation can be tested by checking the +`SRT_EPOLL_IN` flag on the aforementioned socket or group. + +On a freshly created socket or group that is about to be connected to a peer +listener this applies to any `srt_connect` call (and derived), which in +"non-blocking mode" always returns immediately. The connected state for that +socket or group can be tested by checking the `SRT_EPOLL_OUT` flag. Note +that a socket that failed to connect doesn't change the `SRTS_CONNECTING` +state and can be found out only by testing the `SRT_EPOLL_ERR` flag. + +On a listener socket this applies to `srt_accept` call. The readiness state +for this operation can be tested by checking the `SRT_EPOLL_IN` flag on +this listener socket. This flag is also derived from the listener socket +by the accepted socket or group, although the meaning of this flag is +effectively different. + +Note that when this flag is set only on a group, it applies to a +specific receiving operation being done on that group (i.e. it is not +derived from the socket of which the group is a member). + +[Return to list](#list-of-options) + +--- + +#### SRTO_RCVTIMEO + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | ---------- | ------ | --- | ------ | +| `SRTO_RCVTIMEO` | | post | `int32_t` | ms | -1 | -1, 0..| RW | GSI | + +Limits the time up to which the receiving operation will block (see +[`SRTO_RCVSYN`](#SRTO_RCVSYN) for details), such that when this time is exceeded, +it will behave as if in "non-blocking mode". The -1 value means no time limit. + +[Return to list](#list-of-options) + +--- + +#### SRTO_RENDEZVOUS + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | ---------- | ------ | --- | ------ | +| `SRTO_RENDEZVOUS` | | pre | `bool` | | false | | RW | S | + +Use Rendezvous connection mode (both sides must set this and both must use the +procedure of `srt_bind` and then `srt_connect` (or `srt_rendezvous`) to one another. + +[Return to list](#list-of-options) + +--- + +#### SRTO_RETRANSMITALGO + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| --------------------- | ----- | -------- | --------- | ------ | ------- | ------ | --- | ------ | +| `SRTO_RETRANSMITALGO` | 1.4.2 | pre | `int32_t` | | 1 | [0, 1] | RW | GSD | + +An SRT sender option to choose between two retransmission algorithms: + +- 0 - aggressive retransmission algorithm (default until SRT v1.4.4), and +- 1 - efficient retransmission algorithm (introduced in SRT v1.4.2; default since SRT v1.4.4). + +The aggressive retransmission algorithm causes the SRT sender to schedule a packet for retransmission each time it receives a negative acknowledgement (NAK). On a network characterized by low packet loss levels and link capacity high enough to accommodate extra retransmission overhead, this algorithm increases the chances of recovering from packet loss with a minimum delay, and may better suit end-to-end latency constraints. + +The new efficient algorithm optimizes the bandwidth usage by producing fewer retransmissions per lost packet. It takes SRT statistics into account to determine if a retransmitted packet is still in flight and could reach the receiver in time, so that some of the NAK reports are ignored by the sender. This algorithm better fits general use cases, as well as cases where channel bandwidth is limited. + +To learn more about the algorithms, read ["Improving SRT Retransmissions — Experiments with Simulated Live Streaming (Part 1)"](https://medium.com/innovation-labs-blog/improving-srt-retransmissions-experiments-with-simulated-live-streaming-part-1-7d192483bba4) article. + +NOTE: This option is effective only on the sending side. It influences the decision +as to whether a particular reported lost packet should be retransmitted at a +certain time or not. + +NOTE: The efficient retransmission algorithm can only be used when a receiver sends +Periodic NAK reports. See [SRTO_NAKREPORT](#SRTO_NAKREPORT). + +[Return to list](#list-of-options) + +--- + +#### SRTO_REUSEADDR + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | ---------- | ------ | --- | ------ | +| `SRTO_REUSEADDR` | | pre-bind | `bool` | | true | | RW | GSD | + +When true, allows the SRT socket to use the binding address used already by +another SRT socket in the same application. Note that SRT socket uses an +intermediate object called Multiplexer to access the underlying UDP sockets, +so multiple SRT sockets may share one UDP socket, and the packets received by this +UDP socket will be correctly dispatched to the SRT socket to which they are +currently destined. This has some similarities to the `SO_REUSEADDR` system socket +option, although it's only used inside SRT. + +*TODO: This option weirdly only allows the socket used in **bind()** to use the +local address that another socket is already using, but not to disallow another +socket in the same application to use the binding address that the current +socket is already using. What it actually changes is that when given an address in +**bind()** is already used by another socket, this option will make the binding +fail instead of adding the socket to the shared group of that socket that +already has bound this address - but it will not disallow another socket to reuse +its address.* + +[Return to list](#list-of-options) + +--- + +#### SRTO_SENDER + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | ---------- | ------ | --- | ------ | +| `SRTO_SENDER` | 1.0.4 | pre | `bool` | | false | | W | S | + +Set sender side. The side that sets this flag is expected to be a sender. This +flag is only required when communicating with a receiver that uses SRT version +less than 1.3.0 (and hence *HSv4* handshake), in which case if not set properly, +the TSBPD mode (see [`SRTO_TSBPDMODE`](#SRTO_TSBPDMODE)) or encryption will not +work. Setting `SRTO_MINVERSION` to 1.3.0 is therefore recommended. + +[Return to list](#list-of-options) + +--- + +#### SRTO_SNDBUF + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_SNDBUF` | | pre-bind | `int32_t` | bytes |8192 bufs | * | RW | GSD+ | + +Sender Buffer Size. See [`SRTO_RCVBUF`](#SRTO_RCVBUF) for more information. + +[Return to list](#list-of-options) + +--- + +#### SRTO_SNDDATA + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_SNDDATA` | | | `int32_t` | pkts | | | R | S | + +Size of the unacknowledged data in send buffer. + +[Return to list](#list-of-options) + +--- + +#### SRTO_SNDDROPDELAY + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_SNDDROPDELAY` | 1.3.2 | post | `int32_t` | ms | * | -1.. | W | GSD+ | + +Sets an extra delay before `TLPKTDROP` is triggered on the data sender. +This delay is added to the default drop delay time interval value. Keep in mind +that the longer the delay, the more probable it becomes that packets would be +retransmitted uselessly because they will be dropped by the receiver anyway. + +`TLPKTDROP` discards packets reported as lost if it is already too late to send +them (the receiver would discard them even if received). The delay before the +`TLPKTDROP` mechanism is triggered consists of the SRT latency (`SRTO_PEERLATENCY`), +plus `SRTO_SNDDROPDELAY`, plus `2 * interval between sending ACKs` (where the +default `interval between sending ACKs` is 10 milliseconds). +The minimum delay is `1000 + 2 * interval between sending ACKs` milliseconds. + +**Special value -1**: Do not drop packets on the sender at all (retransmit them +always when requested). + +**Default:** 0 in Live mode, -1 in File mode. + +[Return to list](#list-of-options) + +--- + +#### SRTO_SNDKMSTATE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_SNDKMSTATE` | 1.2.0 | | `int32_t` | enum | | | R | S | + +Peer KM state on receiver side for `SRTO_KMSTATE` + +Values defined in enum [`SRT_KM_STATE`](#srt_km_state). + +[Return to list](#list-of-options) + +--- + +#### SRTO_SNDSYN + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_SNDSYN` | | post | `bool` | | true | | RW | GSI | + +When true, sets blocking mode on writing function when it's not ready to +perform the operation. When false ("non-blocking mode"), the writing function +will in this case report error `SRT_EASYNCSND` and return immediately. + +On a connected socket or group this applies to a sending function +(`srt_send` and others) and a situation when there's no free space in +the sender buffer, caused by inability to send all the scheduled data over +the network. Readiness for this operation can be tested by checking the +`SRT_EPOLL_OUT` flag. + +On a freshly created socket or group it will have no effect until the socket +enters a connected state. + +On a listener socket it will be derived by the accepted socket or group, +but will have no effect on the listener socket itself. + +[Return to list](#list-of-options) + +--- + +#### SRTO_SNDTIMEO + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_SNDTIMEO` | | post | `int32_t` | ms | -1 | -1.. | RW | GSI | + +limit the time up to which the sending operation will block (see +`SRTO_SNDSYN` for details), so when this time is exceeded, it will behave as +if in "non-blocking mode". The -1 value means no time limit. + +[Return to list](#list-of-options) + +--- + +#### SRTO_STATE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_STATE` | | | `int32_t` | enum | | | R | S | + +Returns the current socket state, same as `srt_getsockstate`. + +[Return to list](#list-of-options) + +--- + +#### SRTO_STREAMID + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| -------------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_STREAMID` | 1.3.0 | pre | `string` | | "" | [512] | RW | GSD | + +- A string that can be set on the socket prior to connecting. The listener side +will be able to retrieve this stream ID from the socket that is returned from +`srt_accept` (for a connected socket with that stream ID). You usually use SET +on the socket used for `srt_connect`, and GET on the socket retrieved from +`srt_accept`. This string can be used completely free-form. However, it's highly +recommended to follow the [SRT Access Control (Stream ID) Guidlines](../features/access-control.md). + +- As this uses internally the `std::string` type, there are additional functions +for it in the legacy/C++ API (udt.h): `srt::setstreamid` and `srt::getstreamid`. + +- This option is not useful for a Rendezvous connection, since one side would +override the value from the other side resulting in an arbitrary winner. Also +in this connection both peers are known to one another and both have equivalent +roles in the connection. + +- **IMPORTANT**: This option is not derived by the accepted socket from the listener +socket, and setting it on a listener socket (see `srt_listen` function) doesn't +influence anything. + +[Return to list](#list-of-options) + +--- + +#### SRTO_TLPKTDROP + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_TLPKTDROP` | 1.0.6 | pre | `bool` | | * | | RW | GSD | + +Too-late Packet Drop. When enabled on receiver, it skips missing packets that +have not been delivered in time and delivers the subsequent packets to the +application when their time-to-play has come. It also sends a fake ACK to the +sender. When enabled on sender and enabled on the receiving peer, sender drops +the older packets that have no chance to be delivered in time. It is automatically +enabled in sender if receiver supports it. + +**Default:** true in Live mode, false in File mode (see [`SRTO_TRANSTYPE`](#SRTO_TRANSTYPE)) + +[Return to list](#list-of-options) + +--- + +#### SRTO_TRANSTYPE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_TRANSTYPE` | 1.3.0 | pre | `int32_t` | enum |`SRTT_LIVE`| \* | W | S | + +Sets the transmission type for the socket, in particular, setting this option +sets multiple other parameters to their default values as required for a +particular transmission type. + +Values defined by enum `SRT_TRANSTYPE` (see above for possible values) + +[Return to list](#list-of-options) + +--- + +#### SRTO_TSBPDMODE + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_TSBPDMODE` | 0.0.0 | pre | `bool` | | \* | | W | S | + +When true, use Timestamp-based Packet Delivery mode. In this mode the +packet's time is assigned at the sending time (or allowed to be predefined), +transmitted in the packet's header, and then restored on the receiver side so that +the time intervals between consecutive packets are preserved when delivering to +the application. + +**Default:** true in Live mode, false in File mode (see [`SRTO_TRANSTYPE`](#SRTO_TRANSTYPE)). + +[Return to list](#list-of-options) + +--- + +#### SRTO_UDP_RCVBUF + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_UDP_RCVBUF` | | pre-bind | `int32_t` | bytes | 8192 bufs | * | RW | GSD+ | + +UDP Socket Receive Buffer Size. Configured in bytes, maintained in packets +based on MSS value. Receive buffer must not be greater than FC size. + +[Return to list](#list-of-options) + +--- + +#### SRTO_UDP_SNDBUF + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_UDP_SNDBUF` | | pre-bind | `int32_t` | bytes | 65536 | * | RW | GSD+ | + +UDP Socket Send Buffer Size. Configured in bytes, maintained in packets based +on `SRTO_MSS` value. + +[Return to list](#list-of-options) + +--- + +#### SRTO_VERSION + +| OptName | Since | Restrict | Type | Units | Default | Range | Dir | Entity | +| ----------------- | ----- | -------- | ---------- | ------- | --------- | ------ | --- | ------ | +| `SRTO_VERSION` | 1.1.0 | | `int32_t` | | | | R | S | + +Local SRT version. This is the highest local version supported if not +connected, or the highest version supported by the peer if connected. + +The version format in hex is `0x00XXYYZZ` for x.y.z in human readable form. +For example, version 1.4.2 is encoded as `0x010402`. + +[Return to list](#list-of-options) + +--- diff --git a/docs/API/API.md b/docs/API/API.md new file mode 100644 index 0000000..73d458f --- /dev/null +++ b/docs/API/API.md @@ -0,0 +1,711 @@ +# SRT API + +The SRT C API (defined in `srt.h` file) is largely based in design on the legacy +UDT API, with some important changes. The `udt.h` file contains the legacy UDT API +plus some minor optional functions that require the C++ standard library to be used. +There are a few optional C++ API functions stored there, as there is no real C++ API +for SRT. These functions may be useful in certain situations. + +There are some example applications so that you can see how the API is being used, +including `srt-live-transmit` and `srt-file-transmit`. All SRT related material is contained +in `transmitmedia.*` files in the `apps` directory +which is used by all applications. See `SrtSource::Read` and `SrtTarget::Write` +as examples of how data are read and written in SRT. + +- [Setup and Teardown](#setup-and-teardown) +- [Creating and Destroying a Socket](#creating-and-destroying-a-socket) +- [Binding and Connecting](#binding-and-connecting) +- [Sending and Receiving](#sending-and-receiving) +- [Blocking and Non-blocking Modes](#blocking-and-non-blocking-modes) + - [EPoll (Non-blocking Mode Events)](#epoll-non-blocking-mode-events) +- [Transmission Types](#transmission-types) + - [Transmission Method: Live](#transmission-method-live) + - [Transmission Method: Buffer](#transmission-method-buffer) + - [Transmission Method: Message](#transmission-method-message) + +## Setup and Teardown + +Before any part of the SRT C API can be used, the user should call the `srt_startup()` +function. Likewise, before the application exits, the `srt_cleanup()` function +should be called. Note that one of the things the startup function does is to create +a new thread, so choose the point of execution for these functions carefully. + +## Creating and Destroying a Socket + +To do anything with SRT, you first have to create an SRT socket. The term "socket" +in this case is used because of its logical similarity to system-wide sockets. +An SRT socket is not directly related to system sockets, but like a system socket +it is used to define a point of communication. + +### Synopsis + +```c++ +SRTSOCKET srt_create_socket(); +int srt_close(SRTSOCKET s); +``` + +Note that `SRTSOCKET` is just an alias for `int`; this is a legacy naming convention +from UDT, which is here only for clarity. + +### Usage + +```c++ +sock = srt_create_socket(); +``` + +This creates a socket, which can next be configured and then used for communication. + +```c++ +srt_close(sock); +``` + +This closes the socket and frees all its resources. Note that the true life of the +socket does not end exactly after this function exits - some details are being +finished in a separate "SRT GC" thread. Still, at least all shared system resources +(such as listener port) should be released after this function exits. + +### Important Remarks + +1. SRT uses the system UDP protocol as an underlying communication layer, and so +it uses also UDP sockets. The underlying communication layer is used only +instrumentally, and SRT manages UDP sockets as its own system resource as it +pleases - so in some cases it may be reasonable for multiple SRT sockets to share +one UDP socket, or for one SRT socket to use multiple UDP sockets. + +2. The term "port" used in SRT is occasionally identical to the term "UDP +port". However SRT offers more flexibility than UDP (or TCP, the more logical +similarity) because it manages ports as its own resources. For example, one port +may be shared between various services. + +## Binding and Connecting + +Connections are established using the same philosophy as TCP, using functions +with names and signatures similar to the BSD Socket API. What is new here is +the _rendezvous_ mode. + +### Synopsis + +```c++ +int srt_bind(SRTSOCKET u, const struct sockaddr* name, int namelen); +int srt_bind_acquire(SRTSOCKET u, UDPSOCKET udpsock); +``` + +This function sets up the "sockname" for the socket, that is, the local IP address +of the network device (use `INADDR_ANY` for using any device) and port. Note that +this can be done on both listening and connecting sockets; for the latter it will +define the outgoing port. If you don't set up the outgoing port by calling this +function (or use port number 0), a unique port number will be selected automatically. + +The `*_acquire` version simply takes over the given UDP socket and copies the +bound address setting from it. + +```c++ +int srt_listen(SRTSOCKET u, int backlog); +``` + +This sets the backlog (maximum allowed simultaneously pending connections) and +puts the socket into a listening state -- that is, incoming connections will be +accepted in the call `srt_accept`. + +```c++ +SRTSOCKET srt_accept(SRTSOCKET u, struct sockaddr* addr, int* addrlen); +``` + +This function accepts the incoming connection (the peer should do +`srt_connect`) and returns a socket that is exclusively bound to an opposite +socket at the peer. The peer's address is returned in the `addr` +argument. + +```c++ +int srt_connect(SRTSOCKET u, const struct sockaddr* name, int namelen); +int srt_connect_debug(SRTSOCKET u, const struct sockaddr* name, int namelen, int forced_isn); +``` + +This function initiates the connection of a given socket with its peer's counterpart +(the peer gets the new socket for this connection from `srt_accept`). The +address for connection is passed in 'name'. The `connect_debug` version allows +for enforcing the ISN (initial sequence number); this is used only for +debugging or unusual experiments. + +```c++ +int srt_rendezvous(SRTSOCKET u, const struct sockaddr* local_name, int local_namelen, + const struct sockaddr* remote_name, int remote_namelen); +``` + +A convenience function that combines the calls to bind, setting the `SRTO_RENDEZVOUS` flag, +and connecting to the rendezvous counterpart. For simplest usage, the `local_name` should +be set to `INADDR_ANY` (or a specified adapter's IP) and port. Note that both `local_name` +and `remote_name` must use the same port. The peer to which this is going to connect +should call the same function, with appropriate local and remote addresses. A rendezvous +connection means that both parties connect to one another simultaneously. + +**IMPORTANT**: The connection may fail, but the socket that was used for connecting +is not automatically closed and it's also not in broken state (broken state can be +only if a socket was first successfully connected and then broken). When using blocking +mode, the connection failure will result in reporting an error from this function call. +In non-blocking mode the connection failure is designated by the `SRT_EPOLL_ERR` flag +set for this socket in the epoll container. After that failure you can read an extra +information from the socket using `srt_getrejectreason` function, and then you should +close the socket. + +### Listener (Server) Example + +```c++ +sockaddr_in sa = { ... }; // set local listening port and possibly interface's IP +int st = srt_bind(sock, (sockaddr*)&sa, sizeof sa); +srt_listen(sock, 5); +while ( !finish ) { + int sa_len = sizeof sa; + newsocket = srt_accept(sock, (sockaddr*)&sa, &sa_len); + HandleNewClient(newsocket, sa); +} +``` + +### Caller (Client) Example + +```c++ +sockaddr_in sa = { ... }; // set target IP and port + +int st = srt_connect(sock, (sockaddr*)&sa, sizeof sa); +HandleConnection(sock); +``` + +### Rendezvous Example + +```c++ +sockaddr_in lsa = { ... }; // set local listening IP/port +sockaddr_in rsa = { ... }; // set remote IP/port + +srt_setsockopt(m_sock, 0, SRTO_RENDEZVOUS, &yes, sizeof yes); +int stb = srt_bind(sock, (sockaddr*)&lsa, sizeof lsa); +int stc = srt_connect(sock, (sockaddr*)&rsa, sizeof rsa); +HandleConnection(sock); +``` + +or simpler + +```c++ +sockaddr_in lsa = { ... }; // set local listening IP/port +sockaddr_in rsa = { ... }; // set remote IP/port + +int stc = srt_rendezvous(sock, (sockaddr*)&lsa, sizeof lsa, + (sockaddr*)&rsa, sizeof rsa); +HandleConnection(sock); +``` + +## Sending and Receiving + +The SRT API for sending and receiving is split into three categories: *simple*, +*rich*, and *for files only*. + +The **simple API** includes: `srt_send` and `srt_recv` functions. They need only +the socket and the buffer to send from or receive to, just like system `read` +and `write` functions. + +The **rich API** includes the `srt_sendmsg` and `srt_recvmsg` functions. Actually +`srt_recvmsg` is provided for convenience and backward compatibility, as it is +identical to `srt_recv`. The `srt_sendmsg` receives more parameters, specifically +for messages. The `srt_sendmsg2` and `srt_recvmsg2` functions receive the socket, +buffer, and the `SRT_MSGCTRL` object, which is an input-output object specifying +extra data for the operation. + +Functions with the `msg2` suffix use the `SRT_MSGCTRL` object, and have the +following interpretation (except `flags` and `boundary` which are reserved for +future use and should be 0): + +- `srt_sendmsg2`: + - `msgttl`: [IN] maximum time (in ms) to wait for successful delivery (-1: indefinitely) + - `inorder`: [IN] if false, the later sent message is allowed to be delivered earlier + - `srctime`: [IN] timestamp to be used for sending (0 if current time) + - `pktseq`: unused + - `msgno`: [OUT] message number assigned to the currently sent message + +- `srt_recvmsg2` + - `msgttl`: unused + - `inorder`: unused + - `srctime`: [OUT] timestamp set for this dataset when sending + - `pktseq`: [OUT] packet sequence number (first packet from the message, if it spans multiple UDP packets) + - `msgno`: [OUT] message number assigned to the currently received message + +Please note that the `msgttl` and `inorder` arguments and fields in `SRT_MSGCTRL` +are meaningful only when you use the message API in file mode (this will be explained +later). In live mode, which is the SRT default, packets are always delivered when +the time comes (always in order), where you don't want a packet to be dropped +before sending (so -1 should be passed here). + +The `srctime` parameter is an SRT addition for applications (i.e. gateways) +forwarding SRT streams. It permits pulling and pushing of the sender's original +time stamp, converted to local time and drift adjusted. The `srctime` parameter +is the number of usec (since epoch) in local SRT clock time. If the connection +is not between SRT peers or if **Timestamp-Based Packet Delivery mode (TSBPDMODE)** +is not enabled (see [SRT API Socket Options](API-socket-options.md)), +the extracted `srctime` will be 0. Passing `srctime = 0` in `sendmsg` is like using +the API without `srctime` and the local send time will be used (if TSBPDMODE is +enabled and receiver supports it). + +### Synopsis + +```c++ +int srt_send(SRTSOCKET s, const char* buf, int len); +int srt_sendmsg(SRTSOCKET s, const char* buf, int len, int msgttl, bool inorder, uint64_t srctime); +int srt_sendmsg2(SRTSOCKET s, const char* buf, int len, SRT_MSGCTRL* msgctrl); + +int srt_recv(SRTSOCKET s, char* buf, int len); +int srt_recvmsg(SRTSOCKET s, char* buf, int len); +int srt_recvmsg2(SRTSOCKET s, char* buf, int len, SRT_MSGCTRL* msgctrl); +``` + +### Usage + +Sending a payload: + +```c++ +nb = srt_sendmsg(u, buf, nb, -1, true); + +nb = srt_send(u, buf, nb); + +SRT_MSGCTRL mc = srt_msgctrl_default; +nb = srt_sendmsg2(u, buf, nb, &mc); +``` + +Receiving a payload: + +```c++ +nb = srt_recvmsg(u, buf, nb); +nb = srt_recv(u, buf, nb); + +SRT_MSGCTRL mc = srt_msgctrl_default; +nb = srt_recvmsg2(u, buf, nb, &mc); +``` + +### Transmission Types Available in SRT + +Mode settings determine how the sender and receiver functions work. The main +SRT [socket options](API-socket-options.md) that control it are: + +- `SRTO_TRANSTYPE`. Sets several parameters in accordance with the selected +mode: + - `SRTT_LIVE` (default) the Live mode (for live stream transmissions) + - `SRTT_FILE` the File mode (for "no time controlled" fastest data transmission) +- `SRTO_MESSAGEAPI` + - true: (default in Live mode): use Message API + - false: (default in File mode): use Buffer API + +See [Transmission types](#transmission-types) below. + +## Blocking and Non-blocking Modes + +SRT functions can also work in blocking and non-blocking modes, for which +there are two separate options for sending and receiving: `SRTO_SNDSYN` and +`SRTO_RCVSYN`. When blocking mode is used, a function will not exit until +the availability condition is satisfied. In non-blocking mode the function +always exits immediately, and in case of lack of resource availability, it +returns an error with an appropriate code. The use of non-blocking mode usually +requires using some polling mechanism, which in SRT is **EPoll**. + +Note also that the blocking and non-blocking modes apply not only for sending +and receiving. For example, `SNDSYN` defines blocking for `srt_connect` and +`RCVSYN` defines blocking for `srt_accept`. The `SNDSYN` also makes `srt_close` +exit only after the sending buffer is completely empty. + +### EPoll (Non-blocking Mode Events) + +EPoll is a mechanism to track the events happening on the sockets, both "system +sockets" (see `SYSSOCKET` type) and SRT Sockets. Note that `SYSSOCKET` is also +an alias for `int`, used only for clarity. + +#### Synopsis + +```c++ +int srt_epoll_update_usock(int eid, SRTSOCKET u, const int* events = NULL); +int srt_epoll_update_ssock(int eid, SYSSOCKET s, const int* events = NULL); +int srt_epoll_wait(int eid, SRTSOCKET* readfds, int* rnum, SRTSOCKET* writefds, int* wnum, + int64_t msTimeOut, + SYSSOCKET* lrfds, int* lrnum, SYSSOCKET* lwfds, int* lwnum); +int srt_epoll_uwait(int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut); +int srt_epoll_clear_usocks(int eid); +``` + +#### Usage + +SRT socket being a user level concept, the system epoll (or other select) +cannot be used to handle SRT non-blocking mode events. Instead, SRT provides a +user-level epoll that supports both SRT and system sockets. + +The `srt_epoll_update_{u|s}sock()` API functions described here are SRT additions +to the UDT-derived `srt_epoll_add_{u|s}sock()` and `epoll_remove_{u|s}sock()` +functions to atomically change the events of interest. For example, to remove +`SRT_EPOLL_OUT` but keep `SRT_EPOLL_IN` for a given socket with the existing +API, the socket must be removed from epoll and re-added. This cannot be done +atomically, the thread protection (against the epoll thread) being applied +within each function but unprotected between the two calls. It is then possible +to lose an `SRT_EPOLL_IN` event if it fires while the socket is not in the +epoll list. + +Event flags are of various categories: `IN`, `OUT` and `ERR` are events, +which are level-triggered by default and become edge-triggered if combined +with `SRT_EPOLL_ET` flag. The latter is only an edge-triggered flag, not +an event. There's also an `SRT_EPOLL_UPDATE` flag, which is an edge-triggered +only event, and it reports an event on the listener socket that handles socket +group new connections for an already connected group - this is for internal use +only, and it's used in the internal code for socket groups. + +Once the subscriptions are made, you can call an SRT polling function +(`srt_epoll_wait` or `srt_epoll_uwait`) that will block until an event +is raised on any of the subscribed sockets. This function will exit as +soon as at least one event is detected or a timeout occurs. The timeout is +specified in `[ms]`, with two special values: + +- 0: check and report immediately (don't wait) +- -1: wait indefinitely (not interruptible, even by a system signal) + +There are some differences in the synopsis between these two: + +#### `srt_epoll_wait` + +Both system and SRT sockets can be subscribed. This +function reports events on both socket types according to subscriptions, in +these arrays: + +- `readfds` and `lrfds`: subscribed for `IN` and `ERR` +- `writefds` and `lwfds`: subscribed for `OUT` and `ERR` + +where: + +- `readfds` and `writefds` report SRT sockets ("user" socket) +- `lrfds` and `lwfds` report system sockets + +**NOTE**: this function provides no straightforward possibility to report +sockets with an error. If you want to distinguish a report of readiness +for operation from an error report, the only way is to subscribe the +socket in only one direction (either `SRT_EPOLL_IN` or `SRT_EPOLL_OUT`, +but not both) and `SRT_EPOLL_ERR`, and then check the socket's presence +in the array in the direction for which the socket wasn't subscribed. For +example, when an SRT socket is subscribed for `SRT_EPOLL_OUT | SRT_EPOLL_ERR`, +its presence in `readfds` means that an error is reported for it. +This need not be a big problem, because when an error is reported on +a socket, making it appear as if it were ready for an operation, then when that +operation occurs it will simply result in an error. You can use this as an +alternative error check method. + +This function also reports an error of type `SRT_ETIMEOUT` when no socket is +ready as the timeout elapses (including 0). This behavior is different in +`srt_epoll_uwait`. + +Note that in this function there's a loop that checks for socket readiness +every 10ms. Thus, the minimum poll timeout the function can reliably support, +when system sockets are involved, is also 10ms. The return time from a poll +function can only be quicker when there is an event raised on one of the active +SRT sockets. + +#### `srt_epoll_uwait` + +In this function only the SRT sockets can be subscribed +(it reports error if you pass an epoll id that is subscribed to system sockets). +This function waits for the first event on subscribed SRT sockets and reports all +events collected at that moment in an array with the following structure: + +```c++ +typedef struct SRT_EPOLL_EVENT_ +{ + SRTSOCKET fd; + int events; +} SRT_EPOLL_EVENT; + +``` + +Every item reports a single socket with all events as flags. + +When the timeout is not -1, and no sockets are ready until the timeout time +passes, this function returns 0. This behavior is different in `srt_epoll_wait`. + +The extra `srt_epoll_clear_usocks` function removes all subscriptions from +the epoll container. + +The SRT EPoll system does not supports all features of Linux epoll. For +example, it only supports level-triggered events for system sockets. + +## Transmission Types + +**NOTE:** There might be a difference in terminology used in [Internet Draft](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01) and current documentation. +Please consult [Data Transmission Modes](https://tools.ietf.org/html/draft-sharabayko-srt-01#section-4.2) +and [Best Practices and Configuration Tips for Data Transmission via SRT](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-7) +sections of the Internet Draft additionally. The current section is going to be reworked accordingly. + +SRT was originally intended to be used for Live Streaming and therefore its main +and default transmission type is "live". However, SRT supports the modes that +the original UDT library supported, that is, *file* and *message* transmission. + +There are two general modes: **Live** and **File** transmission. Inside File +transmission mode, there are also two possibilities: **Buffer API** and +**Message API**. The Live mode uses Message API. However it doesn't exactly match +the description of the Message API because it uses a maximum single sending buffer +up to the size that fits in one UDP packet. + +There are two options to set a particular type: + +- `SRTO_TRANSTYPE`: uses the enum value with `SRTT_LIVE` for live mode + and `SRTT_FILE` for file mode. This option actually changes several parameters + to their default values for that mode. After this is done, additional parameters, + including those that are set here, can be further changed. + +- `SRTO_MESSAGEAPI`: This sets the Message API (true) or Buffer API (false) + +This makes possible a total of three data transmission methods: + +- [Live](#transmission-method-live) +- [Buffer](#transmission-method-buffer) +- [Message](#transmission-method-message) + +### Terminology + +The following terms are used in the description of transmission types: + +**HANGUP / RESUME**: These terms have different meanings depending on the blocking +state. They describe how a particular function behaves when performing an operation +requires a specific readiness condition to be satisfied. + +In blocking mode HANGUP means that the function blocks until a condition is +satisfied. RESUME means that the condition is satisfied and the function performs +the required operation. + +In non-blocking mode the only difference is that HANGUP, instead of blocking, makes +the function exit immediately with an appropriate error code (such as SRT_EASYNC*, +SRT_ETIMEOUT or SRT_ECONGEST) explaining why the function is not ready to perform +the operation. Refer to the error descriptions in [API-funtions.md](API-funtions.md) +for details. + +The following types of operations are involved: + +1. Reading data: `srt_recv`, `srt_recvmsg`, `srt_recvmsg2`, `srt_recvfile`. + The function HANGS UP if there are no available data to read, and RESUMES when + readable data become available (`SRT_EPOLL_IN` flag set in epoll). Use `SRTO_RCVSYN` + to control blocking mode here. + +2. Writing data: `srt_send`, `srt_sendmsg`, `srt_sendmsg2`, `srt_sendfile`. + The function HANGS UP if the sender buffer becomes full and unable to store + any additional data, and RESUMES if the data scheduled for sending have been + removed from the sender buffer (after being sent and acknowledged) and there + is enough free space in the sender buffer to store data (`SRT_EPOLL_OUT` flag + set in epoll). Use `SRTO_SNDSYN` to control blocking mode here. + +3. Accepting an incoming connection: `srt_accept` + The function HANGS UP if there are no new connections reporting in, and + RESUMES when a new connection has been processed and a new socket or group + has been created to handle it. Note that this function requires the listener + socket to get the connection (the flag `SRTO_RCVSYN` set on + the listener socket controls the blocking mode for this operation). Note also + that the blocking mode for a similar `srt_accept_bond` function is controlled + exclusively by its timeout parameter because it can work with multiple listener + sockets, potentially with different settings. + +4. Connecting: `srt_connect` and its derivatives + The function HANGS UP in the beginning, and RESUMES when the socket used for + connecting is either ready to perform transmission operations or has failed to + connect. It behaves a little differently in non-blocking mode -- the function + should be called only once, and it simply returns a success result as a "HANGUP". + Calling it again with the same socket would be an error. Calling it with a group + would start a completely new connection. It is only possible to determine whether + an operation has finished ("has RESUMED") from epoll flags. The socket, when + successfully connected, would have `SRT_EPOLL_OUT` set, that is, becomes ready + to send data, and `SRT_EPOLL_ERR` when it failed to connect. + +**BLIND / FAST / LATE REXMIT**: BLIND REXMIT is a situation where packets that +were sent are still not acknowledged, either in the expected time frame, or when +another ACK has come for the same number, but no packets have been reported as +lost, or at least not for all still unacknowledged packets. The congestion control +class is responsible for the algorithm for taking care of this situation, which is +either `FASTREXMIT` or `LATEREXMIT`. This will be explained below. + +### Transmission Method: Live + +Setting `SRTO_TRANSTYPE` to `SRTT_LIVE` sets the following [socket options](API-socket-options.md): + +- [`SRTO_TSBPDMODE`](API-socket-options.md#SRTO_TSBPDMODE) = true +- [`SRTO_RCVLATENCY`](API-socket-options.md#SRTO_RCVLATENCY) = 120 +- [`SRTO_PEERLATENCY`](API-socket-options.md#SRTO_PEERLATENCY) = 0 +- [`SRTO_TLPKTDROP`](API-socket-options.md#SRTO_TLPKTDROP) = true +- [`SRTO_LINGER`](API-socket-options.md#SRTO_LINGER) = 0 +- [`SRTO_MESSAGEAPI`](API-socket-options.md#SRTO_MESSAGEAPI) = true +- [`SRTO_NAKREPORT`](API-socket-options.md#SRTO_NAKREPORT) = true +- [`SRTO_RETRANSMITALGO`](API-socket-options.md#SRTO_RETRANSMITALGO) = 1 +- [`SRTO_PAYLOADSIZE`](API-socket-options.md#SRTO_PAYLOADSIZE) = 1316 +- [`SRTO_CONGESTION`](API-socket-options.md#SRTO_CONGESTION) = "live" + +In this mode, every call to a sending function is allowed to send only +so much data, as declared by `SRTO_PAYLOADSIZE`, whose value is still +limited to a maximum of 1456 bytes. The application that does the sending +is by itself responsible for calling the sending function in appropriate +time intervals between subsequent calls. By default, this implies that +the receiver uses 120 ms of latency, which is the declared time interval +between the moment when the packet is scheduled for sending at the +sender side, and when it is received by the receiver application (that +is, the data are kept in the buffer and declared as not received, until +the time comes for the packet to "play"). + +This mode uses the `LiveCC` congestion control class, which puts only a slight +limitation on the bandwidth, if needed (i.e. by adding extra time if the interval +between two consecutive packets would otherwise be too short for the defined speed +limit). Note that it is not intended to work with "virtually infinite" ingest +speeds (such as, for example, reading directly from a file). Therefore the +application is not allowed to stream data with maximum speed -- it must take care +that the speed of data being sent is in rhythm with timestamps in the live stream. +Otherwise the behavior is undefined and might be surprisingly disappointing. + +The reading function will always return only a payload that was +sent, and it will HANGUP until the time to play has come for this +packet (if TSBPD mode is on) or when it is available without gaps of +lost packets (if TSBPD mode is off - see [`SRTO_TSBPDMODE`](API-socket-options.md#SRTO_TSBPDMODE)). + +You may wish to tweak some of the parameters below: + +- `SRTO_TSBPDMODE`: You can turn off controlled latency if your application uses +its own method of latency control. + +- `SRTO_RCVLATENCY`: You can increase the latency time, if this is +too short. Setting a shorter latency than the default is strongly +discouraged, although in some very specific and dedicated networks +this may still be reasonable. Note that `SRTO_PEERLATENCY` is an option +for the sending party, which is the minimum possible value for a receiver. + +- `SRTO_TLPKTDROP`: When true (default), this will drop the packets +that haven't been retransmitted on time, that is, before the next packet +that is already received becomes ready to play. You can turn this off to always +ensure a clean delivery. However, a lost packet can simply pause a +delivery for some longer, potentially undefined time, and cause even +worse tearing for the player. Setting higher latency will help much more in +the case when TLPKTDROP causes packet drops too often. + +- `SRTO_NAKREPORT`: Turns on repeated sending of loss reports, when the lost +packet was not recovered quickly enough, which raises suspicions that the +loss report itself was lost. Without it, the loss report will be always reported +just once and never repeated again, and then the lost payload packet will +be probably dropped by the TLPKTDROP mechanism. + +- `SRTO_RETRANSMITALGO`: Given the receiver sends periodic NAK reports, +the sender can reduce the retransmission overhead by not retransmitting a loss +more often than once per RTT (value 1). + +- `SRTO_PAYLOADSIZE`: Default value is for MPEG TS. If you are going +to use SRT to send any different kind of payload, such as, for example, +wrapping a live stream in very small frames, then you can use a bigger +maximum frame size, though not greater than 1456 bytes. + +Parameters from the modified for transmission type list, not mentioned in the +list above, are crucial for Live mode and shall not be changed. + +The BLIND REXMIT situation is resolved using the FASTREXMIT algorithm by LiveCC: +sending non-acknowledged packets blindly on the premise that the receiver lingers +too long before acknowledging them. This mechanism isn't used (i.e. the BLIND REXMIT +situation isn't handled at all) when `SRTO_NAKREPORT` is set by the peer -- the +NAKREPORT method is considered so effective that FASTREXMIT isn't necessary. + +### Transmission Method: Buffer + +Setting `SRTO_TRANSTYPE` to `SRTT_FILE` sets the following [socket options](API-socket-options.md): + +- [`SRTO_TSBPDMODE`](API-socket-options.md#SRTO_TSBPDMODE) = false +- [`SRTO_RCVLATENCY`](API-socket-options.md#SRTO_RCVLATENCY) = 0 +- [`SRTO_PEERLATENCY`](API-socket-options.md#SRTO_PEERLATENCY) = 0 +- [`SRTO_TLPKTDROP`](API-socket-options.md#SRTO_TLPKTDROP) = false +- [`SRTO_LINGER`](API-socket-options.md#SRTO_LINGER) = 180 s +- [`SRTO_MESSAGEAPI`](API-socket-options.md#SRTO_MESSAGEAPI) = false +- [`SRTO_NAKREPORT`](API-socket-options.md#SRTO_NAKREPORT) = false +- [`SRTO_RETRANSMITALGO`](API-socket-options.md#SRTO_RETRANSMITALGO) = 0 +- [`SRTO_PAYLOADSIZE`](API-socket-options.md#SRTO_PAYLOADSIZE) = 0 +- [`SRTO_CONGESTION`](API-socket-options.md#SRTO_CONGESTION) = "file" + +In this mode, calling a sending function is allowed to potentially send +virtually any size of data. The sending function will HANGUP only if the +sending buffer is completely filled, and RESUME if the sending buffers are +available for at least one smallest portion of data passed for sending. The +sending function need not send everything in this call, and the caller must +be aware that the sending function might return sent data of smaller size +than was actually requested. + +From the receiving function there will be retrieved as many data as the minimum +of the passed buffer size and available data; data still available and not +retrieved by this call will be available for retrieval in the next call. + +There is also a dedicated pair of functions that can only be used in this mode: +`srt_sendfile` and `srt_recvfile`. These functions can be used to transmit the +whole file, or a fragment of it, based on the offset and size. + +This mode uses the `FileCC` congestion control class, which is a direct copy of +UDT's `CUDTCC` congestion control class, adjusted to the needs of SRT's +congestion control framework. This class generally sends the data with maximum +speed in the beginning, until the flight window is full, and then keeps the +speed at the edge of the flight window, only slowing down in the case where +packet loss was detected. The bandwidth usage can be directly limited by the +`SRTO_MAXBW` option. + +The BLIND REXMIT situation is resolved in FileCC using the LATEREXMIT +algorithm: when the repeated ACK was received for the same packet, or when the +loss list is empty and the flight window is full, all packets since the last +ACK are sent again (that's more or less the TCP behavior, but in contrast to +TCP, this is done as a very low probability fallback). + +Most of the parameters described above have `false` or `0` values as they usually +designate features used in Live mode. None are used with File mode. The only option +that makes sense to modify after the `SRTT_FILE` type was set is `SRTO_MESSAGEAPI`, +which is described below. + +### Transmission Method: Message + +Setting `SRTO_TRANSTYPE` to `SRTT_FILE` and then setting `SRTO_MESSAGEAPI` to +`true` implies usage of the Message transmission method. Parameters are set as +described above for the Buffer method, with the exception of `SRTO_MESSAGEAPI`. +The "file" congestion controller is also used in this mode. It differs from the +Buffer method, however, in terms of the rules concerning sending and receiving. + +**HISTORICAL INFO**: The library on which SRT was based (UDT) somewhat misleadingly +used the terms `STREAM` and `DGRAM`, and used the system symbols `SOCK_STREAM` and +`SOCK_DGRAM` in the socket creation function. A "datagram" in the UDT terminology +has nothing to do with the "datagram" term in networking terminology, where its +size is limited to as much it can fit in one MTU. In UDT it is actually a message, +which may span multiple UDP packets and has clearly defined boundaries. It's rather +similar to the **SCTP** protocol. Also, in UDP the API functions were strictly bound +to `DGRAM` or `STREAM` mode: `UDT::send/UDT::recv` were only for `STREAM` and +`UDT::sendmsg/UDT::recvmsg` only for `DGRAM`. In SRT this is changed: all functions +can be used in all modes, except `srt_sendfile/srt_recvfile`, and how the functions +actually work is controlled by the `SRTO_MESSAGEAPI` flag. + +In message mode, every sending function sends **exactly** as much data as it is +passed in a single sending function call. The receiver also receives not less than +**exactly** the number of bytes that was sent (although every message may have a +different size). Every message may also have extra parameters: + +- **TTL** defines how much time (in ms) the message should wait in the sending +buffer for the opportunity to be picked up by the sender thread and sent over +the network; otherwise it is dropped. Note that this TTL only applies to packets that +have been lost and should be retransmitted. + +- **INORDER**, when true, means the messages must be read by the receiver in +exactly the same order in which they were sent. In the situation where a message +suffers a packet loss, this prevents any subsequent messages from achieving +completion status prior to recovery of the preceding message. + +The sending function will HANGUP when the free space in the sending buffer does +not exactly fit the whole message, and it will only RESUME if the free space in +the sending buffer grows up to this size. The call to the sending function also +returns with an error when the size of the message exceeds the total size of the +buffer (this can be modified by the `SRTO_SNDBUF` option). In other words, it is +not designed to send just a part of the message -- either the whole message is +sent, or nothing at all. + +The receiving function will HANGUP until the whole message is available for reading; +if the message spans multiple UDP packets, then the function RESUMES only when +every single packet from the message has been received, including recovered packets, +if any. When the INORDER flag is set to false and parts of multiple messages are +currently available, the first message that is complete (possibly recovered) is +returned. Otherwise the function does a HANGUP until the next message is complete. +The call to the receiving function is rejected if the buffer size is too small +for a single message to fit in it. + +Note that you can use any of the sending and receiving functions for sending and +receiving messages, except `sendfile/recvfile`, which are dedicated exclusively +for Buffer API. + +For more information, see [SRT API Socket Options](API-socket-options.md). + +[Return to Top of Page](#srt-api) diff --git a/docs/API/configuration-guidelines.md b/docs/API/configuration-guidelines.md new file mode 100644 index 0000000..83693d1 --- /dev/null +++ b/docs/API/configuration-guidelines.md @@ -0,0 +1,109 @@ +# Configuration Guidelines + +## Receiver Buffer Size + +The receiver buffer can be configured with the [`SRTO_RCVBUF`](./API-socket-options.md#SRTO_RCVBUF) socket option. +Buffer size in bytes is expected to be passed in the `optval` argument of the `srt_setsockopt(..)` function. +However, internally the value will be converted into the number of packets stored in the receiver buffer. + +The allowed value of `SRTO_RCVBUF` is also limited by the value of the flow control window size [`SRTO_FC`](./API-socket-options.md#SRTO_FC) socket option. +See issue [#700](https://github.com/Haivision/srt/issues/700). + +The default flow control window size is 25600 packets. It is approximately: + +- **270 Mbits** of payload in the default live streaming configuration with an SRT payload size of **1316 bytes**; +- **300 Mbits** of payload in the default file transfer configuration with an SRT payload size of **1456 bytes**. + +The default receiver buffer size is 8192 packets. It is approximately: +- **86 Mbits** of payload with the effective SRT payload size of **1316 bytes**. + +### Setting Receiver Buffer Size + +As already mentioned, the maximum allowed size of the receiver buffer is limited by the value of `SRTO_FC`. +When the `SRTO_RCVBUF` option value is set using the `srt_setsockopt(..)` function, +the provided size in bytes is internally converted to the corresponding size in packets +using the configured value of the `SRTO_MSS` option to estimate the maximum possible payload of a packet. + +The following function returns the buffer size in packets: + +```c++ +int getRbufSizePkts(int SRTO_RCVBUF, int SRTO_MSS, int SRTO_FC) +{ + // UDP header size is assumed to be 28 bytes + // 20 bytes IPv4 + 8 bytes of UDP + const int UDPHDR_SIZE = 28; + const int pkts = (rbuf_size / (SRTO_MSS - UDPHDR_SIZE)); + + return min(pkts, SRTO_FC); +} +``` + +If the value of `SRTO_RCVBUF` in packets exceeds `SRTO_FC`, then it is silently set to the value in bytes corresponding to `SRTO_FC`. +Therefore, to set higher values of `SRTO_RCVBUF` the value of `SRTO_FC` must be increased first. + +### Calculating Target Size in Packets + +The minimum size of the receiver buffer in packets can be calculated as follows: + +`pktsRBufSize = bps / 8 × (RTTsec + latency_sec) / bytePayloadSize` + +where + +- `bps` is the payload bitrate of the stream in bits per second; +- `RTTsec` is the RTT of the network connection in seconds; + +- `bytePayloadSize` is the expected size of the payload of the SRT data packet. + +If the whole remainder of the MTU is expected to be used, payload size is calculated as follows: + +`bytePayloadSize = MSS - 44` + +where + +- 44 is the size in bytes of an **IPv4** header: + - 20 bytes **IPv4** + - 8 bytes of UDP + - 16 bytes of SRT packet header. + +- `MSS` is the Maximum Segment Size (aka MTU); see `SRTO_MSS`. + +### Calculating Target Size to Set + +To determine the value to pass in `srt_setsockopt(..)` with `SRTO_RCVBUF` +the size in packets `pktsRBufSize` must be converted to the size in bytes +assuming the internal conversion of the `srt_setsockopt(..)` function. + +The target size of the payload stored by the receiver buffer would be: + +`SRTO_RCVBUF = pktsRBufSize × (SRTO_MSS - UDPHDR_SIZE)` + +where + +- `UDPHDR_SIZE` = 28 (20 bytes IPv4, 8 bytes of UDP) +- `SRTO_MSS` is the corresponding socket option value at the moment of setting `SRTO_RCVBUF`. + + +### Summing Up + + +```c++ +auto CalculateTargetRBufSize(int msRTT, int bpsRate, int bytesPayloadSize, int msLatency, int SRTO_MSS) +{ + const int UDPHDR_SIZE = 28; + const long long targetPayloadBytes = static_cast(msLatency + msRTT / 2) * bpsRate / 1000 / 8; + const long long targetNumPackets = targetPayloadBytes / bytesPayloadSize; + const long long targetSizeValue = targetNumPackets * (SRTO_MSS - UDPHDR_SIZE); + return {targetNumPackets, targetSizeValue}; +} + +// Configuring + +const auto [fc, rcvbuf] = CalculateTargetRBufSize(msRTT, bpsRate, bytesPayloadSize, SRTO_RCVLATENCY, SRTO_MSS); + +int optval = fc; +int optlen = sizeof optval; +srt_setsockopt(sock, 0, SRTO_FC, (void*) &optval, optlen); + +optval = rcvbuf; +srt_setsockopt(sock, 0, SRTO_RCVBUF, (void*) &optval, optlen); +``` diff --git a/docs/API/statistics.md b/docs/API/statistics.md new file mode 100644 index 0000000..a34478f --- /dev/null +++ b/docs/API/statistics.md @@ -0,0 +1,825 @@ + +# SRT Statistics + +1. [SRT Socket Statistics](#srt-socket-statistics) + - [Summary Table](#summary-table) + - [Accumulated Statistics](#accumulated-statistics) + - [Interval-Based Statistics](#interval-based-statistics) + - [Instantaneous Statistics](#instantaneous-statistics) +2. [SRT Group Statistics](#srt-group-statistics) + - [Summary Table](#group-summary-table) + - [Accumulated Statistics](#group-accumulated-statistics) + - [Interval-Based Statistics](#group-interval-based-statistics) + - [Formulas](#group-formulas) + +## SRT Socket Statistics + +SRT provides a powerful set of statistical data on a socket. This data can be used to keep an eye on a socket's health and track faulty behavior. + +Statistics are calculated independently on each side (receiver and sender) and are not exchanged between peers unless explicitly stated. + +The following API functions can be used to retrieve statistics on an SRT socket: + +* `int srt_bstats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear)` +* `int srt_bistats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear, int instantaneous)` + +Refer to the documentation of the [SRT API Functions](API-functions.md) for usage instructions. + +### Summary Table + +The table below provides a summary of SRT socket statistics: name, type, unit of measurement, data type, and whether it is calculated by the sender or receiver. + +There are three types of statistics: + +- **Accumulated:** the statistic is accumulated since the time an SRT socket has been created (after the successful call to `srt_connect(...)` or `srt_bind(...)` function), e.g., [pktSentTotal](#pktSentTotal), etc., +- **Interval-based:** the statistic is accumulated during a specified time interval (e.g., 100 milliseconds if SRT statistics is collected each 100 milliseconds) from the time an SRT socket has been created, e.g., [pktSent](#pktSent), etc. The value of the statistic can be reset by calling the `srt_bstats(..., int clear)` function with `clear = 1`, +- **Instantaneous:** the statistic is obtained at the moment the `srt_bistats()` function is called, e.g., [msRTT](#msRTT), etc. + +See sections [Accumulated Statistics](#accumulated-statistics), [Interval-Based Statistics](#interval-based-statistics), and [Instantaneous Statistics](#instantaneous-statistics) for a detailed description of each statistic. + + +| Statistic | Type of Statistic | Unit of Measurement | Available for Sender | Available for Receiver | Data Type | +| --------------------------------------------------- | ----------------- | ------------------- | -------------------- | ---------------------- | --------- | +| [msTimeStamp](#msTimeStamp) | accumulated | ms (milliseconds) | ✓ | ✓ | int64_t | +| [pktSentTotal](#pktSentTotal) | accumulated | packets | ✓ | - | int64_t | +| [pktRecvTotal](#pktRecvTotal) | accumulated | packets | - | ✓ | int64_t | +| [pktSentUniqueTotal](#pktSentUniqueTotal) | accumulated | packets | ✓ | - | int64_t | +| [pktRecvUniqueTotal](#pktRecvUniqueTotal) | accumulated | packets | - | ✓ | int64_t | +| [pktSndLossTotal](#pktSndLossTotal) | accumulated | packets | ✓ | - | int32_t | +| [pktRcvLossTotal](#pktRcvLossTotal) | accumulated | packets | - | ✓ | int32_t | +| [pktRetransTotal](#pktRetransTotal) | accumulated | packets | ✓ | - | int32_t | +| [pktRcvRetransTotal](#pktRcvRetransTotal) | accumulated | packets | - | ✓ | int32_t | +| [pktSentACKTotal](#pktSentACKTotal) | accumulated | packets | - | ✓ | int32_t | +| [pktRecvACKTotal](#pktRecvACKTotal) | accumulated | packets | ✓ | - | int32_t | +| [pktSentNAKTotal](#pktSentNAKTotal) | accumulated | packets | - | ✓ | int32_t | +| [pktRecvNAKTotal](#pktRecvNAKTotal) | accumulated | packets | ✓ | - | int32_t | +| [usSndDurationTotal](#usSndDurationTotal) | accumulated | us (microseconds) | ✓ | - | int64_t | +| [pktSndDropTotal](#pktSndDropTotal) | accumulated | packets | ✓ | - | int32_t | +| [pktRcvDropTotal](#pktRcvDropTotal) | accumulated | packets | - | ✓ | int32_t | +| [pktRcvUndecryptTotal](#pktRcvUndecryptTotal) | accumulated | packets | - | ✓ | int32_t | +| [pktSndFilterExtraTotal](#pktSndFilterExtraTotal) | accumulated | packets | ✓ | - | int32_t | +| [pktRcvFilterExtraTotal](#pktRcvFilterExtraTotal) | accumulated | packets | - | ✓ | int32_t | +| [pktRcvFilterSupplyTotal](#pktRcvFilterSupplyTotal) | accumulated | packets | - | ✓ | int32_t | +| [pktRcvFilterLossTotal](#pktRcvFilterLossTotal) | accumulated | packets | - | ✓ | int32_t | +| [byteSentTotal](#byteSentTotal) | accumulated | bytes | ✓ | - | uint64_t | +| [byteRecvTotal](#byteRecvTotal) | accumulated | bytes | - | ✓ | uint64_t | +| [byteSentUniqueTotal](#byteSentUniqueTotal) | accumulated | bytes | ✓ | - | uint64_t | +| [byteRecvUniqueTotal](#byteRecvUniqueTotal) | accumulated | bytes | - | ✓ | uint64_t | +| [byteRcvLossTotal](#byteRcvLossTotal) | accumulated | bytes | - | ✓ | uint64_t | +| [byteRetransTotal](#byteRetransTotal) | accumulated | bytes | ✓ | - | uint64_t | +| [byteSndDropTotal](#byteSndDropTotal) | accumulated | bytes | ✓ | - | uint64_t | +| [byteRcvDropTotal](#byteRcvDropTotal) | accumulated | bytes | - | ✓ | uint64_t | +| [byteRcvUndecryptTotal](#byteRcvUndecryptTotal) | accumulated | bytes | - | ✓ | uint64_t | +| [pktSent](#pktSent) | interval-based | packets | ✓ | - | int64_t | +| [pktRecv](#pktRecv) | interval-based | packets | - | ✓ | int64_t | +| [pktSentUnique](#pktSentUnique) | interval-based | packets | ✓ | - | int64_t | +| [pktRecvUnique](#pktRecvUnique) | interval-based | packets | - | ✓ | int64_t | +| [pktSndLoss](#pktSndLoss) | interval-based | packets | ✓ | - | int32_t | +| [pktRcvLoss](#pktRcvLoss) | interval-based | packets | - | ✓ | int32_t | +| [pktRetrans](#pktRetrans) | interval-based | packets | ✓ | - | int32_t | +| [pktRcvRetrans](#pktRcvRetrans) | interval-based | packets | - | ✓ | int32_t | +| [pktSentACK](#pktSentACK) | interval-based | packets | - | ✓ | int32_t | +| [pktRecvACK](#pktRecvACK) | interval-based | packets | ✓ | - | int32_t | +| [pktSentNAK](#pktSentNAK) | interval-based | packets | - | ✓ | int32_t | +| [pktRecvNAK](#pktRecvNAK) | interval-based | packets | ✓ | - | int32_t | +| [pktSndFilterExtra](#pktSndFilterExtra) | interval-based | packets | ✓ | - | int32_t | +| [pktRcvFilterExtra](#pktRcvFilterExtra) | interval-based | packets | - | ✓ | int32_t | +| [pktRcvFilterSupply](#pktRcvFilterSupply) | interval-based | packets | - | ✓ | int32_t | +| [pktRcvFilterLoss](#pktRcvFilterLoss) | interval-based | packets | - | ✓ | int32_t | +| [mbpsSendRate](#mbpsSendRate) | interval-based | Mbps | ✓ | - | double | +| [mbpsRecvRate](#mbpsRecvRate) | interval-based | Mbps | - | ✓ | double | +| [usSndDuration](#usSndDuration) | interval-based | us (microseconds) | ✓ | - | int64_t | +| [pktReorderDistance](#pktReorderDistance) | interval-based | packets | - | ✓ | int32_t | +| [pktRcvBelated](#pktRcvBelated) | interval-based | packets | - | ✓ | int64_t | +| [pktSndDrop](#pktSndDrop) | interval-based | packets | ✓ | - | int32_t | +| [pktRcvDrop](#pktRcvDrop) | interval-based | packets | - | ✓ | int32_t | +| [pktRcvUndecrypt](#pktRcvUndecrypt) | interval-based | packets | - | ✓ | int32_t | +| [byteSent](#byteSent) | interval-based | bytes | ✓ | - | uint64_t | +| [byteRecv](#byteRecv) | interval-based | bytes | - | ✓ | uint64_t | +| [byteSentUnique](#byteSentUnique) | interval-based | bytes | ✓ | - | uint64_t | +| [byteRecvUnique](#byteRecvUnique) | interval-based | bytes | - | ✓ | uint64_t | +| [byteRcvLoss](#byteRcvLoss) | interval-based | bytes | - | ✓ | uint64_t | +| [byteRetrans](#byteRetrans) | interval-based | bytes | ✓ | - | uint64_t | +| [byteSndDrop](#byteSndDrop) | interval-based | bytes | ✓ | - | uint64_t | +| [byteRcvDrop](#byteRcvDrop) | interval-based | bytes | - | ✓ | uint64_t | +| [byteRcvUndecrypt](#byteRcvUndecrypt) | interval-based | bytes | - | ✓ | uint64_t | +| [usPktSndPeriod](#usPktSndPeriod) | instantaneous | us (microseconds) | ✓ | - | double | +| [pktFlowWindow](#pktFlowWindow) | instantaneous | packets | ✓ | - | int32_t | +| [pktCongestionWindow](#pktCongestionWindow) | instantaneous | packets | ✓ | - | int32_t | +| [pktFlightSize](#pktFlightSize) | instantaneous | packets | ✓ | - | int32_t | +| [msRTT](#msRTT) | instantaneous | ms (milliseconds) | ✓ | ✓ | double | +| [mbpsBandwidth](#mbpsBandwidth) | instantaneous | Mbps | ✓ | ✓ | double | +| [byteAvailSndBuf](#byteAvailSndBuf) | instantaneous | bytes | ✓ | - | int32_t | +| [byteAvailRcvBuf](#byteAvailRcvBuf) | instantaneous | bytes | - | ✓ | int32_t | +| [mbpsMaxBW](#mbpsMaxBW) | instantaneous | Mbps | ✓ | - | double | +| [byteMSS](#byteMSS) | instantaneous | bytes | ✓ | ✓ | int32_t | +| [pktSndBuf](#pktSndBuf) | instantaneous | packets | ✓ | - | int32_t | +| [byteSndBuf](#byteSndBuf) | instantaneous | bytes | ✓ | - | int32_t | +| [msSndBuf](#msSndBuf) | instantaneous | ms (milliseconds) | ✓ | - | int32_t | +| [msSndTsbPdDelay](#msSndTsbPdDelay) | instantaneous | ms (milliseconds) | ✓ | - | int32_t | +| [pktRcvBuf](#pktRcvBuf) | instantaneous | packets | - | ✓ | int32_t | +| [byteRcvBuf](#byteRcvBuf) | instantaneous | bytes | - | ✓ | int32_t | +| [msRcvBuf](#msRcvBuf) | instantaneous | ms (milliseconds) | - | ✓ | int32_t | +| [msRcvTsbPdDelay](#msRcvTsbPdDelay) | instantaneous | ms (milliseconds) | - | ✓ | int32_t | +| [pktReorderTolerance](#pktReorderTolerance) | instantaneous | packets | - | ✓ | int32_t | +| [pktRcvAvgBelatedTime](#pktRcvAvgBelatedTime) | instantaneous | ms (milliseconds) | - | ✓ | double | + +### Accumulated Statistics + +#### msTimeStamp + +The time elapsed, in milliseconds, since the SRT socket has been created (after successful call to `srt_connect(...)` or `srt_bind(...)` function). Available both for sender and receiver. + +#### pktSentTotal + +The total number of sent DATA packets, including retransmitted packets ([pktRetransTotal](#pktRetransTotal)). Available for sender. + +If the `SRTO_PACKETFILTER` socket option is enabled (refer to [SRT API Socket Options](API-socket-options.md)), this statistic counts sent packet filter control packets ([pktSndFilterExtraTotal](#pktSndFilterExtraTotal)) as well. Introduced in SRT v1.4.0. + +#### pktRecvTotal + +The total number of received DATA packets, including retransmitted packets ([pktRcvRetransTotal](#pktRcvRetransTotal)). Available for receiver. + +If the `SRTO_PACKETFILTER` socket option is enabled (refer to [SRT API Socket Options](API-socket-options.md)), this statistic counts received packet filter control packets ([pktRcvFilterExtraTotal](#pktRcvFilterExtraTotal)) as well. Introduced in SRT v1.4.0. + +#### pktSentUniqueTotal + +The total number of *unique* DATA packets sent by the SRT sender. Available for sender. + +This value contains only *unique* *original* DATA packets. Retransmitted DATA packets ([pktRetransTotal](#pktRetransTotal)) are not taken into account. If the `SRTO_PACKETFILTER` socket option is enabled (refer to [SRT API Socket Options](API-socket-options.md)), packet filter control packets ([pktSndFilterExtraTotal](#pktSndFilterExtraTotal)) are also not taken into account. + +This value corresponds to the number of original DATA packets sent by the SRT sender. It counts every packet sent over the network for the first time, and can be calculated as follows: `pktSentUniqueTotal = pktSentTotal – pktRetransTotal`, or by `pktSentUniqueTotal = pktSentTotal – pktRetransTotal - pktSndFilterExtraTotal` if the `SRTO_PACKETFILTER` socket option is enabled. The original DATA packets are sent only once. + +#### pktRecvUniqueTotal + +The total number of *unique* original, retransmitted or recovered by the packet filter DATA packets *received in time*, *decrypted without errors* and, as a result, scheduled for delivery to the upstream application by the SRT receiver. Available for receiver. + +Unique means "first arrived" DATA packets. There is no difference whether a packet is original or, in case of loss, retransmitted or recovered by the packet filter. Whichever packet comes first is taken into account. + +This statistic doesn't count + +- duplicate packets (retransmitted or sent several times by defective hardware/software), +- arrived too late packets (retransmitted or original packets arrived out of order) that were already dropped by the TLPKTDROP mechanism (see [pktRcvDropTotal](#pktRcvDropTotal) statistic), +- arrived in time packets, but decrypted with errors (see [pktRcvUndecryptTotal](#pktRcvUndecryptTotal) statistic), and, as a result, dropped by the TLPKTDROP mechanism (see [pktRcvDropTotal](#pktRcvDropTotal) statistic). + +DATA packets recovered by the packet filter ([pktRcvFilterSupplyTotal](#pktRcvFilterSupplyTotal)) are taken into account if the `SRTO_PACKETFILTER` socket option is enabled (refer to [SRT API Socket Options](API-socket-options.md)). Do not mix up with the control packets received by the packet filter ([pktRcvFilterExtraTotal](#pktRcvFilterExtraTotal)). + +#### pktSndLossTotal + +The total number of data packets considered or reported as lost at the sender side. Does not correspond to the packets detected as lost at the receiver side. Available for sender. + +A packet is considered lost in two cases: +1. Sender receives a loss report from a receiver, +2. Sender initiates retransmission after not receiving an ACK packet for a certain timeout. Refer to `FASTREXMIT` and `LATEREXMIT` algorithms. + +#### pktRcvLossTotal + +The total number of SRT DATA packets detected as presently missing (either reordered or lost) at the receiver side. Available for receiver. + +The detection of presently missing packets is triggered by a newly received DATA packet with the sequence number `s`. If `s` is greater than the sequence number `next_exp` of the next expected packet (`s > next_exp`), the newly arrived packet `s` is considered in-order and there is a sequence discontinuity of size `s - next_exp` associated with this packet. The presence of sequence discontinuity means that some packets of the original sequence have not yet arrived (presently missing), either reordered or lost. Once the sequence discontinuity is detected, its size `s - next_exp` is added to `pktRcvLossTotal` statistic. Refer to [RFC 4737 - Packet Reordering Metrics](https://tools.ietf.org/html/rfc4737) for details. + +If the packet `s` is received out of order (`s < next_exp`), the statistic is not affected. + +Note that only original (not retransmitted) SRT DATA packets are taken into account. Refer to [pktRcvRetransTotal](#pktRcvRetransTotal) for the formula for obtaining the total number of lost retransmitted packets. + +In SRT v1.4.0, v1.4.1, the `pktRcvLossTotal` statistic includes packets that failed to be decrypted. To receive the number of presently missing packets, substract [pktRcvUndecryptTotal](#pktRcvUndecryptTotal) from the current one. This is going to be fixed in SRT v.1.5.0. + +#### pktRetransTotal + +The total number of retransmitted packets sent by the SRT sender. Available for sender. + +This statistic is not interchangeable with the receiver [pktRcvRetransTotal](#pktRcvRetransTotal) statistic. + +#### pktRcvRetransTotal + +The total number of retransmitted packets registered at the receiver side. Available for receiver. + +This statistic is not interchangeable with the sender [pktRetransTotal](#pktRetransTotal) statistic. + +Note that the total number of lost retransmitted packets can be calculated as the total number of retransmitted packets sent by receiver minus the total number of retransmitted packets registered at the receiver side: `pktRetransTotal - pktRcvRetransTotal`. + +This is going to be implemented in SRT v1.5.0, see issue [#1208](https://github.com/Haivision/srt/issues/1208). + +#### pktSentACKTotal + +The total number of sent ACK (Acknowledgement) control packets. Available for receiver. + +#### pktRecvACKTotal + +The total number of received ACK (Acknowledgement) control packets. Available for sender. + +#### pktSentNAKTotal + +The total number of sent NAK (Negative Acknowledgement) control packets. Available for receiver. + +#### pktRecvNAKTotal + +The total number of received NAK (Negative Acknowledgement) control packets. Available for sender. + +#### usSndDurationTotal + +The total accumulated time in microseconds, during which the SRT sender has some data to transmit, including packets that have been sent, but not yet acknowledged. In other words, the total accumulated duration in microseconds when there was something to deliver (non-empty senders' buffer). Available for sender. + +#### pktSndDropTotal + +The total number of _dropped_ by the SRT sender DATA packets that have no chance to be delivered in time (refer to [Too-Late Packet Drop](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-4.6) mechanism). Available for sender. + +Packets may be dropped conditionally when both `SRTO_TSBPDMODE` and `SRTO_TLPKTDROP` socket options are enabled, refer to [SRT API Socket Options](API-socket-options.md). + +The delay before TLPKTDROP mechanism is triggered is calculated as follows +`SRTO_PEERLATENCY + SRTO_SNDDROPDELAY + 2 * interval between sending ACKs`, +where `SRTO_PEERLATENCY` is the configured SRT latency, `SRTO_SNDDROPDELAY` adds an extra to `SRTO_PEERLATENCY` delay, the default `interval between sending ACKs` is 10 milliseconds. The minimum delay is `1000 + 2 * interval between sending ACKs` milliseconds. Refer to `SRTO_PEERLATENCY`, `SRTO_SNDDROPDELAY` socket options in [SRT API Socket Options](API-socket-options.md). + +#### pktRcvDropTotal + +The total number of _dropped_ by the SRT receiver and, as a result, not delivered to the upstream application DATA packets (refer to [Too-Late Packet Drop](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-4.6) mechanism). Available for receiver. + +This statistic counts + +- not arrived packets including those signalled for dropping by the sender, that were dropped in favor of the subsequent existing packets, +- arrived too late packets (retransmitted or original packets arrived out of order), +- arrived in time packets, but decrypted with errors (see also [pktRcvUndecryptTotal](#pktRcvUndecryptTotal) statistic). + +Packets may be dropped conditionally when both `SRTO_TSBPDMODE` and `SRTO_TLPKTDROP` socket options are enabled, refer to [SRT API Socket Options](API-socket-options.md). + +#### pktRcvUndecryptTotal + +The total number of packets that failed to be decrypted at the receiver side. Available for receiver. + +#### pktSndFilterExtraTotal + +The total number of packet filter control packets generated by the packet filter (refer to [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md)). Available for sender. + +Packet filter control packets contain only control information necessary for the packet filter. The type of these packets is DATA. + +If the `SRTO_PACKETFILTER` socket option is disabled (refer to [SRT API Socket Options](API-socket-options.md)), this statistic is equal to 0. Introduced in SRT v1.4.0. + +#### pktRcvFilterExtraTotal + +The total number of packet filter control packets received by the packet filter (refer to [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md)). Available for receiver. + +Packet filter control packets contain only control information necessary for the packet filter. The type of these packets is DATA. + +If the `SRTO_PACKETFILTER` socket option is disabled (refer to [SRT API Socket Options](API-socket-options.md)), this statistic is equal to 0. Introduced in SRT v1.4.0. + +#### pktRcvFilterSupplyTotal + +The total number of lost DATA packets recovered by the packet filter at the receiver side (e.g., FEC rebuilt packets; refer to [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md)). Available for receiver. + +If the `SRTO_PACKETFILTER` socket option is disabled (refer to [SRT API Socket Options](API-socket-options.md)), this statistic is equal to 0. Introduced in SRT v1.4.0. + +#### pktRcvFilterLossTotal + +The total number of lost DATA packets **not** recovered by the packet filter at the receiver side (refer to [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md)). Available for receiver. + +If the `SRTO_PACKETFILTER` socket option is disabled (refer to [SRT API Socket Options](API-socket-options.md)), this statistic is equal to 0. Introduced in SRT v1.4.0. + +#### byteSentTotal + +Same as [pktSentTotal](#pktSentTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for sender. + +#### byteRecvTotal + +Same as [pktRecvTotal](#pktRecvTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for receiver. + +#### byteSentUniqueTotal + +Same as [pktSentUniqueTotal](#pktSentUniqueTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for sender. + +#### byteRecvUniqueTotal + +Same as [pktRecvUniqueTotal](#pktRecvUniqueTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for receiver. + +#### byteRcvLossTotal + +Same as [pktRcvLossTotal](#pktRcvLossTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Bytes for the presently missing (either reordered or lost) packets' payloads are estimated based on the average packet size. Available for receiver. + +#### byteRetransTotal + +Same as [pktRetransTotal](#pktRetransTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for sender. + +#### byteSndDropTotal + +Same as [pktSndDropTotal](#pktSndDropTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for sender. + +#### byteRcvDropTotal + +Same as [pktRcvDropTotal](#pktRcvDropTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Bytes for the dropped packets' payloads are estimated based on the average packet size. Available for receiver. + +#### byteRcvUndecryptTotal + +Same as [pktRcvUndecryptTotal](#pktRcvUndecryptTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for receiver. + + +### Interval-Based Statistics + +#### pktSent + +Same as [pktSentTotal](#pktSentTotal), but for a specified interval. + +#### pktRecv + +Same as [pktRecvTotal](#pktRecvTotal), but for a specified interval. + +#### pktSentUnique + +Same as [pktSentUniqueTotal](#pktSentUniqueTotal), but for a specified interval. + +#### pktRecvUnique + +Same as [pktRecvUniqueTotal](#pktRecvUniqueTotal), but for a specified interval. + +#### pktSndLoss + +Same as [pktSndLossTotal](#pktSndLossTotal), but for a specified interval. + +#### pktRcvLoss + +Same as [pktRcvLossTotal](#pktRcvLossTotal), but for a specified interval. + +#### pktRetrans + +Same as [pktRetransTotal](#pktRetransTotal), but for a specified interval. + +#### pktRcvRetrans + +Same as [pktRcvRetransTotal](#pktRcvRetransTotal), but for a specified interval. + +#### pktSentACK + +Same as [pktSentACKTotal](#pktSentACKTotal), but for a specified interval. + +#### pktRecvACK + +Same as [pktRecvACKTotal](#pktRecvACKTotal), but for a specified interval. + +#### pktSentNAK + +Same as [pktSentNAKTotal](#pktSentNAKTotal), but for a specified interval. + +#### pktRecvNAK + +Same as [pktRecvNAKTotal](#pktRecvNAKTotal), but for a specified interval. + +#### pktSndFilterExtra + +Same as [pktSndFilterExtraTotal](#pktSndFilterExtraTotal), but for a specified interval. + +Introduced in v1.4.0. Refer to [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md). + +#### pktRcvFilterExtra + +Same as [pktRcvFilterExtraTotal](#pktRcvFilterExtraTotal), but for a specified interval. + +Introduced in v1.4.0. Refer to [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md). + +#### pktRcvFilterSupply + +Same as [pktRcvFilterSupplyTotal](#pktRcvFilterSupplyTotal), but for a specified interval. + +Introduced in v1.4.0. Refer to [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md). + +#### pktRcvFilterLoss + +Same as [pktRcvFilterLossTotal](#pktRcvFilterLossTotal), but for a specified interval. + +Introduced in v1.4.0. Refer to [SRT Packet Filtering & FEC](../features/packet-filtering-and-fec.md). + +#### mbpsSendRate + +Sending rate in Mbps. Sender side. + +#### mbpsRecvRate + +Receiving rate in Mbps. Receiver side. + +#### usSndDuration + +Same as [usSndDurationTotal](#usSndDurationTotal), but measured on a specified interval. + +#### pktReorderDistance + +The distance in sequence numbers between the two original (not retransmitted) packets, +that were received out of order. Receiver only. + +The traceable distance values are limited by the maximum reorder tolerance set by  `SRTO_LOSSMAXTTL`. + +#### pktRcvBelated + +The number of packets received but IGNORED due to having arrived too late. + +Makes sense only if TSBPD and TLPKTDROP are enabled. + +An offset between sequence numbers of the newly arrived DATA packet and latest +acknowledged DATA packet is calculated. +If the offset is negative, the packet is considered late, meaning that it was +either already acknowledged or dropped by TSBPD as too late to be delivered. + +Retransmitted packets can also be considered late. + +#### pktSndDrop + +Same as [pktSndDropTotal](#pktSndDropTotal), but for a specified interval. + +#### pktRcvDrop + +Same as [pktRcvDropTotal](#pktRcvDropTotal), but for a specified interval. + +#### pktRcvUndecrypt + +Same as [pktRcvUndecryptTotal](#pktRcvUndecryptTotal), but for a specified interval. + +#### byteSent + +Same as [byteSentTotal](#byteSentTotal), but for a specified interval. + +#### byteRecv + +Same as [byteRecvTotal](#byteRecvTotal), but for a specified interval. + +#### byteSentUnique + +Same as [byteSentUniqueTotal](#byteSentUniqueTotal), but for a specified interval. + +#### byteRecvUnique + +Same as [byteRecvUniqueTotal](#byteRecvUniqueTotal), but for a specified interval. + +#### byteRcvLoss + +Same as [byteRcvLossTotal](#byteRcvLossTotal), but for a specified interval. + +#### byteRetrans + +Same as [byteRetransTotal](#byteRetransTotal), but for a specified interval. + +#### byteSndDrop + +Same as [byteSndDropTotal](#byteSndDropTotal), but for a specified interval. + +#### byteRcvDrop + +Same as [byteRcvDropTotal](#byteRcvDropTotal), but for a specified interval. + +#### byteRcvUndecrypt + +Same as [byteRcvUndecryptTotal](#byteRcvUndecryptTotal), but for a specified interval. + + +### Instantaneous Statistics + +#### usPktSndPeriod + +Current minimum time interval between which consecutive packets are sent, in +microseconds. Sender only. + +Note that several sockets sharing one outgoing port use the same sending queue. +They may have different pacing of the outgoing packets, but all the packets will +be placed in the same sending queue, which may affect the send timing. + +`usPktSndPeriod` is the minimum time (sending period) that must be kept +between two packets sent consecutively over the link used by an SRT socket. +It is not the EXACT time interval between two consecutive packets. In the case where the time spent by an +application between sending two consecutive packets exceeds `usPktSndPeriod`, the next +packet will be sent faster, or even immediately, to preserve the average sending rate. + +**Note**: Does not apply to probing packets. + +#### pktFlowWindow + +The maximum number of packets that can be "in flight". Sender only. +See also [pktFlightSize](#pktFlightSize). + +The value retrieved on the sender side represents an estimation of the amount +of free space in the buffer of the peer receiver. +The actual amount of available space is periodically reported back by the receiver in ACK packets. +When this value drops to zero, the next packet sent will be dropped by the receiver +without processing. In **file mode** this may cause a slowdown of sending in +order to wait until the receiver has more space available, after it +eventually extracts the packets waiting in its receiver buffer; in **live +mode** the receiver buffer contents should normally occupy not more than half +of the buffer size (default 8192). If `pktFlowWindow` value is less than that +and becomes even less in the next reports, it means that the receiver +application on the peer side cannot process the incoming stream fast enough and +this may lead to a dropped connection. + +#### pktCongestionWindow + +Congestion window size, in number of packets. Sender only. + +Dynamically limits the maximum number of packets that can be in flight. +Congestion control module dynamically changes the value. + +In **file mode** this value starts at 16 and is increased to the number of reported +acknowledged packets. This value is also updated based on the delivery rate, reported by the receiver. +It represents the maximum number of packets that can be safely +sent without causing network congestion. The higher this value is, the faster the +packets can be sent. In **live mode** this field is not used. + +#### pktFlightSize + +The number of packets in flight. Sender only. + +`pktFlightSize <= pktFlowWindow` and `pktFlightSize <= pktCongestionWindow` + +This is the distance +between the packet sequence number that was last reported by an ACK message and +the sequence number of the latest packet sent (at the moment when the statistics +are being read). + +**NOTE:** ACKs are received periodically (at least every 10 ms). This value is most accurate just +after receiving an ACK and becomes a little exaggerated over time until the +next ACK arrives. This is because with a new packet sent, +while the ACK number stays the same for a moment, +the value of `pktFlightSize` increases. +But the exact number of packets arrived since the last ACK report is unknown. +A new statistic might be added which only reports the distance +between the ACK sequence and the sent sequence at the moment when an ACK arrives, +and isn't updated until the next ACK arrives. The difference between this value +and `pktFlightSize` would then reveal the number of packets with an unknown state +at that moment. + +#### msRTT + +Smoothed round-trip time (SRTT), an exponentially-weighted moving average (EWMA) of an endpoint's RTT samples, in milliseconds. +Available both for sender and receiver. + +See [Section 4.10. Round-Trip Time Estimation](https://tools.ietf.org/html/draft-sharabayko-srt-01#section-4.10) of the [Internet Draft](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01) and [[RFC6298] Paxson, V., Allman, M., Chu, J., and M. Sargent, "Computing TCP's Retransmission Timer"](https://datatracker.ietf.org/doc/html/rfc6298) for more details. + +#### mbpsBandwidth + +Estimated bandwidth of the network link, in Mbps. Sender only. + +The bandwidth is estimated at the receiver. +The estimation is based on the time between two probing DATA packets. +Every 16th data packet is sent immediately after the previous data packet. +By measuring the delay between probe packets on arrival, +it is possible to estimate the maximum available transmission rate, +which is interpreted as the bandwidth of the link. +The receiver then sends back a running average calculation to the sender with an ACK message. + +#### byteAvailSndBuf + +The available space in the sender's buffer, in bytes. Sender only. + +This value decreases with data scheduled for sending by the application, and increases +with every ACK received from the receiver, after the packets are sent over +the UDP link. + +#### byteAvailRcvBuf + +The available space in the receiver's buffer, in bytes. Receiver only. + +This value increases after the application extracts the data from the socket +(uses one of `srt_recv*` functions) and decreases with every packet received +from the sender over the UDP link. + +#### mbpsMaxBW + +Transmission bandwidth limit, in Mbps. Sender only. +Usually this is the setting from +the `SRTO_MAXBW` option, which may include the value 0 (unlimited). Under certain +conditions a nonzero value might be be provided by a congestion +control module, although none of the built-in congestion control modules +currently use it. + +Refer to `SRTO_MAXBW` and `SRTO_INPUTBW` in [SRT API Socket Options](API-socket-options.md). + +#### byteMSS + +Maximum Segment Size (MSS), in bytes. +Same as the value from the `SRTO_MSS` socket option. +Should not exceed the size of the maximum transmission unit (MTU), in bytes. Sender and Receiver. +The default size of the UDP packet used for transport, +including all possible headers (Ethernet, IP and UDP), is 1500 bytes. + +Refer to `SRTO_MSS` in [SRT API Socket Options](API-socket-options.md). + +#### pktSndBuf + +The number of packets in the sender's buffer that are already +scheduled for sending or even possibly sent, but not yet acknowledged. +Sender only. + +Once the receiver acknowledges the receipt of a packet, or the TL packet drop +is triggered, the packet is removed from the sender's buffer. +Until this happens, the packet is considered as unacknowledged. + +A moving average value is reported when the value is retrieved by calling +`srt_bstats(...)` or `srt_bistats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear, int instantaneous)` +with `instantaneous=false`. + +The current state is returned if `srt_bistats(...)` is called with `instantaneous=true`. + +#### byteSndBuf + +Instantaneous (current) value of `pktSndBuf`, but expressed in bytes, including payload and all headers (SRT+UDP+IP). \ +20 bytes IPv4 + 8 bytes of UDP + 16 bytes SRT header. Sender side. + +#### msSndBuf + +The timespan (msec) of packets in the sender's buffer (unacknowledged packets). Sender only. + +A moving average value is reported when the value is retrieved by calling +`srt_bstats(...)` or `srt_bistats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear, int instantaneous)` +with `instantaneous=false`. + +The current state is returned if `srt_bistats(...)` is called with `instantaneous=true`. + +#### msSndTsbPdDelay + +Timestamp-based Packet Delivery Delay value of the peer. +If `SRTO_TSBPDMODE` is on (default for **live mode**), it +returns the value of `SRTO_PEERLATENCY`, otherwise 0. +The sender reports the TSBPD delay value of the receiver. +The receiver reports the TSBPD delay of the sender. + +#### pktRcvBuf + +The number of acknowledged packets in receiver's buffer. Receiver only. + +This measurement does not include received but not acknowledged packets, stored in the receiver's buffer. + +A moving average value is reported when the value is retrieved by calling +`srt_bstats(...)` or `srt_bistats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear, int instantaneous)` +with `instantaneous=false`. + +The current state is returned if `srt_bistats(...)` is called with `instantaneous=true`. + +#### byteRcvBuf + +Instantaneous (current) value of `pktRcvBuf`, expressed in bytes, including payload and all headers (SRT+UDP+IP). \ +20 bytes IPv4 + 8 bytes of UDP + 16 bytes SRT header. Receiver side. + +#### msRcvBuf + +The timespan (msec) of acknowledged packets in the receiver's buffer. Receiver side. + +If TSBPD mode is enabled (defualt for **live mode**), +a packet can be acknowledged, but not yet ready to play. +This range includes all packets regardless of whether +they are ready to play or not. + +A moving average value is reported when the value is retrieved by calling +`srt_bstats(...)` or `srt_bistats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear, int instantaneous)` +with `instantaneous=false`. + +The current state is returned if `srt_bistats(...)` is called with `instantaneous=true`. + +Instantaneous value is only reported if TSBPD mode is enabled, otherwise 0 is reported (see #900). + +#### msRcvTsbPdDelay + +Timestamp-based Packet Delivery Delay value set on the socket via `SRTO_RCVLATENCY` or `SRTO_LATENCY`. +The value is used to apply TSBPD delay for reading the received data on the socket. Receiver side. + +If `SRTO_TSBPDMODE` is off (default for **file mode**), 0 is returned. + +#### pktReorderTolerance + +Instant value of the packet reorder tolerance. Receiver side. Refer to [pktReorderDistance](#pktReorderDistance). + +`SRTO_LOSSMAXTTL` sets the maximum reorder tolerance value. The value defines the maximum +time-to-live for the original packet, that was received after with a gap in the sequence of incoming packets. +Those missing packets are expected to come out of order, therefore no loss is reported. +The actual TTL value (**pktReorderTolerance**) specifies the number of packets to receive further, before considering +the preceding packets lost, and sending the loss report. + +The internal algorithm checks the order of incoming packets and adjusts the tolerance based on the reorder +distance (**pktReorderTolerance**), but not to a value higher than the maximum (`SRTO_LOSSMAXTTL`). + +SRT starts from tolerance value set in `SRTO_LOSSMAXTTL` (initial tolerance is set to 0 in SRT v1.4.0 and prior versions). +Once the receiver receives the first reordered packet, it increases the tolerance to the distance in the sequence +discontinuity of the two packets. \ +After 10 consecutive original (not retransmitted) packets come in order, the reorder distance +is decreased by 1 for every such packet. + +For example, assume packets with the following sequence +numbers are being received: \ +1, 2, 4, 3, 5, 7, 6, 10, 8, 9 +SRT starts from 0 tolerance. Receiving packet with sequence number 4 has a discontinuity +equal to one packet. The loss is reported to the sender. +With the next packet (sequence number 3) a reordering is detected. Reorder tolerance is increased to 1. \ +The next sequence discontinuity is detected when the packet with sequence number 7 is received. +The current tolerance value is 1, which is equal to the gap (between 5 and 7). No loss is reported. \ +Next packet with sequence number 10 has a higher sequence discontinuity equal to 2. +Missing packets with sequence numbers 8 and 9 will be reported lost with the next received packet +(reorder distance is still at 1). +The next received packet has sequence number 8. Reorder tolerance value is increased to 2. +The packet with sequence number 9 is reported lost. + +#### pktRcvAvgBelatedTime + +Accumulated difference between the current time and the time-to-play of a packet +that is received late. + + +## SRT Group Statistics + +SRT group statistics are implemented for [SRT Connection Bonding](../features/bonding-quick-start.md) feature and available since SRT v1.5.0. + +The `srt_bistats(SRTSOCKET u, ...)` function can be used with a socket group ID as the first argument to get statistics for a group. `SRT_TRACEBSTATS` values will mostly be zeros, except for the fields listed in the [Summary Table](#group-summary-table) below. Refer to the [SRT API Functions](../API/API-functions.md#socket-group-management) documentation for usage instructions. + +### Summary Table + +The table below provides a summary of SRT group statistics: name, type, unit of measurement, data type, and whether it is calculated by the sender or receiver. See sections [Accumulated Statistics](#group-accumulated-statistics) and [Interval-Based Statistics](#group-interval-based-statistics) for a detailed description of each statistic. + +| Statistic | Type of Statistic | Unit of Measurement | Available for Sender | Available for Receiver | Data Type | +| ------------------------------------------------- | ----------------- | ------------------- | -------------------- | ---------------------- | --------- | +| [msTimeStamp](#group-msTimeStamp) | accumulated | ms (milliseconds) | ✓ | ✓ | int64_t | +| [pktSentUniqueTotal](#group-pktSentUniqueTotal) | accumulated | packets | ✓ | - | int64_t | +| [pktRecvUniqueTotal](#group-pktRecvUniqueTotal) | accumulated | packets | - | ✓ | int64_t | +| [pktRcvDropTotal](#group-pktRcvDropTotal) | accumulated | packets | - | ✓ | int32_t | +| [byteSentUniqueTotal](#group-byteSentUniqueTotal) | accumulated | packets | ✓ | - | int64_t | +| [byteRecvUniqueTotal](#group-byteRecvUniqueTotal) | accumulated | packets | - | ✓ | int64_t | +| [byteRcvDropTotal](#group-byteRcvDropTotal) | accumulated | packets | - | ✓ | int32_t | +| [pktSentUnique](#group-pktSentUnique) | interval-based | packets | ✓ | - | int64_t | +| [pktRecvUnique](#group-pktRecvUnique) | interval-based | packets | - | ✓ | int64_t | +| [pktRcvDrop](#group-pktRcvDrop) | interval-based | packets | - | ✓ | int32_t | +| [byteSentUnique](#group-byteSentUnique) | interval-based | packets | ✓ | - | int64_t | +| [byteRecvUnique](#group-byteRecvUnique) | interval-based | packets | - | ✓ | int64_t | +| [byteRcvDrop](#group-byteRcvDrop) | interval-based | packets | - | ✓ | int32_t | + +### Accumulated Statistics + +#### msTimeStamp + +The time elapsed, in milliseconds, since the time ("connection" time) when the initial group connection has been initiated (the time when the first connection in the group has been made and therefore made the group connected). This "connection" time will be then set in this statistic in every next socket that will become a member of the group as the new connections are established. A new connection to an already connected group doesn’t change the value of "connection" time. Available both for sender and receiver. + +#### pktSentUniqueTotal + +The number of *unique original* DATA packets sent by the socket group. Available for sender. + +This value counts every *original* DATA packet sent over the network for the first time by the socket group. There is no difference between Connection Bonding modes (broadcast, backup and balancing). For example, sending the packet with a particular sequence number over multiple links in case of broadcast mode (it means sending this packet multiple times) does not affect the statistic and this very packet is taken into account only once. + +This statistic does not count retransmitted DATA packets that are individual per socket connection within the group. See the corresponding [pktRetransTotal](#pktRetransTotal) socket statistic. + +If the `SRTO_PACKETFILTER` socket option is enabled (refer to [SRT API Socket Options](API-socket-options.md)), this statistic does not count packet filter control packets that are individual per socket connection within the group. See the corresponding [pktSndFilterExtraTotal](#pktSndFilterExtraTotal) socket statistic. + +#### pktRecvUniqueTotal + +The number of *unique* DATA packets *received in time* by the socket group and, as a result, scheduled for delivery to the upstream application. Available for receiver. + +Unique means "first arrived over multiple links" DATA packets. Whichever packet comes first over whichever link is taken into account. + +This statistic doesn't count + +- discarded as duplicate by the group reader packets, see [pktRcvDiscardTotal](#group-pktRcvDiscardTotal) statistic, +- dropped by the socket group packets, see [pktRcvDropTotal](#group-pktRcvDropTotal) statistic. + +#### pktRcvDropTotal + +The number of *dropped* and, as a result, *not delivered* to the upstream application by the socket group DATA packets. Available for receiver. + +A packet is considered dropped by the socket group if it has been dropped by the TLPKTDROP mechanism over all the links from the group. See the corresponding socket [pktRcvDropTotal](#pktRcvDropTotal) statistic. + +For example, if a packet with a particular sequence number has been dropped over one or several links, but has not been dropped over at least one link, it is *not* considered dropped by the socket group and can be delivered to the upstream application. Only if a packet has been dropped over all the links from the group, it is considered dropped by the socket group and can not be delivered to the upstream application. + +In fact, only sockets can drop the packets and the group is simply responsible for delivering received over multiple sockets packets to the application. + +#### byteSentUniqueTotal + +Same as [pktSentUniqueTotal](#group-pktSentUniqueTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for sender. + +#### byteRecvUniqueTotal + +Same as [pktRecvUniqueTotal](#group-pktRecvUniqueTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for receiver. + +#### byteRcvDropTotal + +Same as [pktRcvDropTotal](#group-pktRcvDropTotal), but expressed in bytes, including payload and all the headers (20 bytes IPv4 + 8 bytes UDP + 16 bytes SRT). Available for receiver. + +### Interval-Based Statistics + +#### pktSentUnique + +Same as [pktSentUniqueTotal](#group-pktSentUniqueTotal), but for a specified interval. + +#### pktRecvUnique + +Same as [pktRecvUniqueTotal](#group-pktRecvUniqueTotal), but for a specified interval. + +#### pktRcvDrop + +Same as [pktRcvDropTotal](#group-pktRcvDropTotal), but for a specified interval. + +#### byteSentUnique + +Same as [byteSentUniqueTotal](#group-byteSentUniqueTotal), but for a specified interval. + +#### byteRecvUnique + +Same as [byteRecvUniqueTotal](#group-byteRecvUniqueTotal), but for a specified interval. + +#### byteRcvDrop + +Same as [byteRcvDropTotal](#group-byteRcvDropTotal), but for a specified interval. + +### Formulas + +The ratio of unrecovered by the socket group packets `Dropped Packets Ratio` can be calculated as follows: + +``` +Dropped Packets Ratio = pktRcvDropTotal / pktSentUniqueTotal; in case both sender and receiver statistics is available +Dropped Packets Ratio = pktRcvDropTotal / (pktRecvUniqueTotal + pktRcvDropTotal); in case receiver only statistics is available +``` \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..7a5bb43 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,75 @@ +# Documentation Overview + +## SRT API Documents + +| Document Title | Folder | File Name | Description | +| :----------------------------------------------------- | :---------------------------- | :------------------------------------------------- | :--------------------------------------------------- | +| [SRT API](API/API.md) | [API](API/) | [API.md](API/API.md) | Detailed description of the SRT C API. | +| [SRT API Functions](API/API-functions.md) | [API](API/) | [API-functions.md](API/API-functions.md) | Reference document for SRT API functions. | +| [SRT API Socket Options](API/API-socket-options.md) | [API](API/) | [API-socket-options.md](API/API-socket-options.md) | Instructions and list of socket options for SRT API. | +| [SRT Statistics](API/statistics.md) | [API](API/) | [statistics.md](API/statistics.md) | How to use SRT socket and socket group statistics. | +| [Configuration Guidelines](API/configuration-guidelines.md) | [API](API/) | [configuration-guidelines.md](API/configuration-guidelines.md) | How to configure SRT buffers. | +| | | | | + +## Build Instructions + +| Document Title | Folder | File Name | Description | +| :----------------------------------------------------------- | :---------------------------- | :----------------------------------------- | :----------------------------------------------------------- | +| [SRT Build Options](build/build-options.md) | [build](build/) | [build-options.md](build/build-options.md) | Description of CMake build system, configure script, and build options. | +| [Building SRT on Linux (Ubuntu/CentOS)](build/build-linux.md) | [build](build/) | [build-linux.md](build/build-linux.md) | Build instructions for Linux (Ubuntu/CentOS). | +| [Building SRT on Windows](build/build-win.md) | [build](build/) | [build-win.md](build/build-win.md) | Build instructions for Windows. | +| [Building SRT on macOS](build/build-macOS.md) | [build](build/) | [build-macOS.md](build/build-macOS.md) | Build instructions for macOS. | +| [Building SRT on iOS](build/build-iOS.md) | [build](build/) | [build-iOS.md](build/build-iOS.md) | Build instructions for iOS. | +| [Building SRT on Android](build/build-android.md) | [build](build/) | [build-android.md](build/build-android.md) | Build instructions for Android. | +| | | | | + +## Development Documents + +| Document Title | Folder | File Name | Description | +| :----------------------------------------------- | :---------------------------- | :----------------------------------------------- | :----------------------------------------------------------- | +| [SRT Developer's Guide](dev/developers-guide.md) | [dev](dev/) | [developers-guide.md](dev/developers-guide.md) | Development setup, project structure, coding rules,
submitting issues & PRs, etc. | +| [Low Level Info](dev/low-level-info.md) | [dev](dev/) | [low-level-info.md](dev/low-level-info.md) | Low level information for the SRT project (only
mutex locking). | +| [Making SRT Better](dev/making-srt-better.md) | [dev](dev/) | [making-srt-better.md](dev/making-srt-better.md) | Guidelines for problem reporting, collecting debug logs
and pcaps. | +| | | | | + +## Features + +| Document Title | Folder | File Name | Description | +| :----------------------------------------------------------- | :---------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | +| [SRT Access Control
(Stream ID) Guidelines](features/access-control.md) | [features](features/) | [access-control.md](features/access-control.md) | Access Control (Stream ID) guidelines. | +| [SRT Connection Bonding: Quick Start](features/bonding-quick-start.md) | [features](features/) | [bonding-quick-start.md](features/bonding-quick-start.md) | SRT Connection Bonding Quick Start. | +| [SRT Connection Bonding: Introduction](features/bonding-intro.md) | [features](features/) | [bonding-intro.md](features/bonding-intro.md) | Introduction to Connection Bonding. Description
of group (bonded) connections. | +| [SRT Connection Bonding: Socket Groups](features/socket-groups.md) | [features](features/) | [socket-groups.md](features/socket-groups.md) | Description of socket groups in SRT (Connection
Bonding). Here you will also find information
regarding the `srt-test-live` application for testing
Connection Bonding. | +| [SRT Connection Bonding: Main/Backup][main-backup] | [features](features/) | [bonding-main-backup.md][main-backup] | Main/Backup mode description. | +| [SRT Encryption](features/encryption.md) | [features](features/) | [encryption.md](features/encryption.md) | Description of SRT encryption mechanism. This
document might be outdated, please consult
[Section 6. Encryption][srt-internet-draft-sec-6] of the [Internet Draft][srt-internet-draft] additionally. | +| [SRT Handshake](features/handshake.md) | [features](features/) | [handshake.md](features/handshake.md) | Description of SRT handshake mechanism. This
document might be outdated, please consult
[Section 3.2.1 Handshake][srt-internet-draft-sec-3-2-1] and
[Section 4.3 Handshake Messages](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-4.3) of the
[Internet Draft][srt-internet-draft] additionally. | +| [Live Streaming
Guidelines](features/live-streaming.md) | [features](features/) | [live-streaming.md](features/live-streaming.md) | Guidelines for live streaming with SRT. See also
best practices and configuration tips in
[Section 7.1 Live Streaming](https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-7.1) of the [Internet Draft][srt-internet-draft]. | +| [SRT Packet
Filtering & FEC][packet-filter] | [features](features/) | [packet-filtering-and-fec.md][packet-filter] | Description of SRT packet filtering mechanism,
including FEC. | +| | | | | + +## Sample Applications + +| Document Title | Folder | File Name | Description | +| :--------------------------------------------------------------------- | :-------------------- | :-------------------------------------------------- | :------------------------------------------------------------ | +| [Using the
`srt-live-transmit` App](apps/srt-live-transmit.md) | [apps](apps/) | [srt-live-transmit.md](apps/srt-live-transmit.md) | A sample application to transmit a live stream from
source medium (UDP/SRT/`stdin`) to the target medium
(UDP/SRT/`stdout`). | +| [Using the
`srt-file-transmit` App](apps/srt-file-transmit.md) | [apps](apps/) | [srt-file-transmit.md](apps/srt-file-transmit.md) | A sample application to transmit a file over SRT | +| [Using the
`srt-tunnel` App](apps/srt-tunnel.md) | [apps](apps/) | [srt-tunnel.md](apps/srt-tunnel.md) | A sample application to set up an SRT tunnel for TCP traffic. | +| [Using the
`srt-test-multiplex` App](apps/srt-test-multiplex.md) | [apps](apps/) | [srt-test-multiplex.md](apps/srt-test-multiplex.md) | Testing application that allows to send multiple streams over one UDP link. | +| [Using the
`srt-test-relay` App](apps/srt-test-relay.md) | [apps](apps/) | [srt-test-relay.md](apps/srt-test-relay.md) | Testing application for bidirectional stream sending over one connection. | +| | | | | + +## Miscellaneous + +| Document Title | Folder | File Name | Description | +| :------------------------------------------------- | :---------------------------- | :---------------------------------------------------- | :----------------------------------------------------------- | +| [Why SRT Was Created](misc/why-srt-was-created.md) | [misc](misc/) | [why-srt-was-created.md](misc/why-srt-was-created.md) | Background and history of SRT. See also
[Section 1. Introduction][srt-internet-draft-sec-1] of the [Internet Draft][srt-internet-draft]. | +| | | | | + + +[srt-internet-draft]: https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01 +[srt-internet-draft-sec-1]: https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-1 +[srt-internet-draft-sec-3-2-1]: https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-3.2.1 +[srt-internet-draft-sec-6]: https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01#section-6 + +[main-backup]: features/bonding-main-backup.md +[packet-filter]: features/packet-filtering-and-fec.md diff --git a/docs/apps/srt-file-transmit.md b/docs/apps/srt-file-transmit.md new file mode 100644 index 0000000..2bf3b11 --- /dev/null +++ b/docs/apps/srt-file-transmit.md @@ -0,0 +1,55 @@ +# srt-file-transmit + +The `srt-file-transmit` tool is a tool for transmitting files over SRT. + +You need: + + - a file to transmit + - a destination to store it into + - this application run on both sides, one sending, one receiving + +## Introduction + +The `srt-file-transmit` application will transmit your file over the SRT connection, +the application on the other side will receive it and store to the desired location. +Both caller-listener and rendezvous arrangement of the connection are possible +and in whatever direction. + +The `streamid` socket option will be used to pass the filename to the other side +so that it is either written with this name or matched with the filename internally. + +The application the will be sending a file should use the file path as source and +SRT URI as a destination, and vice versa for receiving. + +## Caller mode + +If you use sender in caller mode, then the caller SRT URI destination should be +specified, and the "root name" from the file path will be set to `streamid`. +This will allow the listener to use it when writing. + +If a receiver is used as a caller, then the destination filepath's rootname +will be also passed as `streamid` so that the listener receiver can pick up the +file by name. + +In caller mode you must specify the full filename path of the received or sent +file. + +## Listener mode + +If you use sender in listener mode, then you start it with specifying either the +full filename path, or only the directory where the file is located; in the latter +case the filename will be tried from the `streamid` option extracted from the +connected socket (as set by the other side's caller). If the full filename was +specified, it must match the rootname extraced from this option, or otherwise +transmission will not be done. + +If you use receiver in listener mode, then you start it with specifying either +the full filename path, or just the directory. In the latter case the root name +will be extracted from `streamid` socket option, and this one will be transmitted. + +## Usage + +``` +srt-file-transmit [options] +``` + diff --git a/docs/apps/srt-live-transmit.md b/docs/apps/srt-live-transmit.md new file mode 100644 index 0000000..320e184 --- /dev/null +++ b/docs/apps/srt-live-transmit.md @@ -0,0 +1,478 @@ +# srt-live-transmit + +The `srt-live-transmit` tool is a universal data transport tool with a purpose to transport data between SRT and other medium. +At the same time it is just a sample application to show some of the powerful features of SRT. We encourage you to use SRT library itself integrated into your products. + +## Introduction + +The `srt-live-transmit` can be both used as a universal SRT-to-something-else flipper, as well as a testing tool for SRT. + +The general usage is the following: + +```shell +srt-live-transmit [options] +``` + +The following medium types are handled by `srt-live-transmit`: + +- SRT - use SRT for reading or writing, in listener, caller or rendezvous mode, with possibly additional parameters +- UDP - read or write the given UDP address (also multicast) +- Local file - read or store the stream into the file +- Process's pipeline - use the process's `stdin` and `stdout` standard streams + +Any medium can be used with any direction, although some of them may +have special direction-dependent cases. + +Mind that the URI has a standard syntax: + +```yaml +scheme://HOST:PORT/PATH?PARAM1=VALUE1&PARAM2=VALUE2&... +``` + +The first parameter is introduced with a `?` and all following can be appended with an `&` character. + +If you specify only the path (no **://** specified), then the scheme +defaults to **file**. The path can be also specified as relative this +way. Note also that empty host (`scheme://:PORT`) defaults to 0.0.0.0, +and an empty port (when there's no `:PORT` part) defaults to port number 0. + +Special options for particular medium may be specified in **PARAM** +items. All options are medium-specific, although there may happen some +options common for multiple media types. + +Note also that the **HOST** part is always tried to be resolved as a name, +if its form is not directly the IPv4 address. + +### Example for Smoke Testing + +First we need to start up the `srt-live-transmit` app, listening for unicast UDP TS input on port 1234 and making SRT available on port 4201. Note, these are randomly chosen ports. We also open the app in verbose mode for debugging: + +```shell +srt-live-transmit udp://:1234 srt://:4201 -v +``` + +Now we need to generate a UDP stream. ffmpeg can be used to generate bars and tone as follows, doing a simple unicast push to our listening `srt-live-transmit` application: + +```shell +ffmpeg -f lavfi -re -i smptebars=duration=300:size=1280x720:rate=30 -f lavfi -re -i sine=frequency=1000:duration=60:sample_rate=44100 -pix_fmt yuv420p -c:v libx264 -b:v 1000k -g 30 -keyint_min 120 -profile:v baseline -preset veryfast -f mpegts "udp://127.0.0.1:1234?pkt_size=1316" +``` + +You should see the stream connect in `srt-live-transmit`. + +Now you can test in VLC (make sure you're using the latest version!) - just go to file -> open network stream and enter +`srt://127.0.0.1:4201` and you should see bars and tone right away. + +Or you can test using ffplay or ffprobe to inspect the stream: + +```shell +ffplay srt://127.0.0.1:4201 +``` +-or- +```shell +ffprobe srt://127.0.0.1:4201 +``` + +If you're having trouble, make sure this works, then add complexity one step at a time (multicast, push vs listen, etc.). + +## URI Syntax + +Transmission mediums are specified as the standard URI format: + +```yaml +SCHEME://HOST:PORT?PARAM1=VALUE1&PARAM2=VALUE2&... +``` + +The applications supports the following schemes: + +- `file` - for file or standard input and output +- `udp` - UDP output (unicast and multicast) +- `srt` - SRT connection + +Note that this application doesn't support file as a medium, but this +can be handled by other applications from this project. + +### Medium: FILE (including standard process pipes) + +**NB!** File mode, except `file://con`, is not supported in the `srt-file-transmit` tool! + +The general syntax is: `file:///global/path/to/the/file`. No parameters in the URL are extracted. There's one (non-standard!) special case, though: + +```yaml +file://con +``` + +That is, **con** is used as a *HOST* part of the URI. If you use this +URI for \, then the data will be read from the standard +input. If \, the data will be send to the standard output. +Be careful with options being specified together with having standard +output as output URI - some of them are not allowed as the extra output +controlled by options might interfere with the data output. + +## Medium: UDP + +UDP can only be used in listening mode for input, and in calling mode +for output. Multicast Streaming is also possible, without any special declaration. Just use an IP address from the multicast range. +The specification and meaning of the fields in the URI depend on the mode. + +The **PORT** part is always mandatory and it designates either the port number +for the target host or the port number to be bound to read from. + +The following options are available through URI parameters: + +- **iptos**: sets the `IP_TOS` socket option +- **ttl**: sets the `IP_TTL` or `IP_MULTICAST_TTL` option, depending on mode +- **mcloop**: sets the `IP_MULTICAST_LOOP` option (multicast mode only) +- **rcvbuf**: sets the `SO_RCVBUF` socket option +- **sndbuf**: sets the `SO_SNDBUF` socket option +- **adapter**: sets the local binding address +- **source**: uses `IP_ADD_SOURCE_MEMBERSHIP`, see below for details + +For sending to unicast: + +```yaml +udp://TARGET:PORT?parameters... +``` + +- The **HOST** part (here: TARGET) is mandatory and designates the target host + +- The **iptos** parameter designates the Type-Of-Service (TOS) field for +outgoing packets via `IP_TOS` socket option. + +- The **ttl** parameter will set time-to-live value for outgoing packets via +`IP_TTL` socket options. + +For receiving from unicast: + +```yaml +udp://LOCALADDR:PORT?parameters... +``` + +- The **HOST** part (here: LOCALADDR) designates the local interface to bind. +It's optional (can be empty) and defaults to 0.0.0.0 (`INADDR_ANY`). + +For multicast the scheme is: + +```yaml +udp://GROUPADDR:PORT?parameters... +``` + +- The **HOST** part (here: GROUPADDR) is mandatory always and designates the +target multicast group. The `@` character is handled in this case, but it's not +necessary, as the IGMP addresses are recognized by their mask. + +For sending to a multicast group: + +- The **iptos** parameter designates the Type-Of-Service (TOS) field for +outgoing packets via `IP_TOS` socket option. + +- The **ttl** parameter will set time-to-live value for outgoing packets via +`IP_MULTICAST_TTL` socket options. + +- The **adapter** parameter can be used to specify the adapter to be set +through `IP_MULTICAST_IF` option to override the default device used for +sending + +For receiving from a multicast group: + +- The **adapter** parameter can be used to specify the adapter through which +the given multicast group can be reached (it's used to bind the socket) + +- The **source** parameter enforces the use of `IP_ADD_SOURCE_MEMBERSHIP` +instead of `IP_ADD_MEMBERSHIP` and the value is set to `imr_sourceaddr` field. + +Explanations for the symbols and terms used above can be found in POSIX +manual pages, like `ip(7)` and on Microsoft docs pages under `IPPROTO_IP`. + +### Medium: SRT + +Most important about SRT is that it can be either input or output and in +both these cases it can work in listener, caller and rendezvous mode. SRT +also handles several parameters special way, in addition to standard SRT +options that can be set through the parameters. + +SRT can be connected using one of three connection modes: + +- **caller**: the "agent" (this application) sends the connection request to +the peer, which must be **listener**, and this way it initiates the +connection. + +- **listener**: the "agent" waits to be contacted by any peer **caller**. +Note that a listener can accept multiple callers, but *srt-live-transmit* +does not use this ability; after the first connection, it no longer +accepts new connections. + +- **rendezvous**: A one-to-one only connection where both parties are +equivalent and both attempt to initiate a connection simultaneously. Whichever party happens +to start first (or succeeds in punching through the firewall first) is considered to have +initiated the connection. + +This mode can be specified explicitly using the **mode** parameter. When it's +not specified, then it is derived based on the *host* part in the URI and +the presence of the **adapter** parameter: + +* Listener mode: if you leave the *host* part empty (**adapter** may be specified): + - `srt://:1234` +* Caller mode: if you specify *host* part, but not **adapter** parameter: + - `srt://remote.host.com:1234` +* Rendezvous mode: if you specify *host* AND **adapter** parameter: + - `srt://remote.host.com:1234&adapter=my.remote.addr` + +Sometimes the required parameter specification results in a different mode +than desired; in this case you should specify the mode explicitly. + +The interpretation of the *host* and *port* parts is the following: + +- In **LISTENER** mode: + - *host* part: the local IP address to bind (default: 0.0.0.0 - "all devices") + - *port* part: the local port to bind (mandatory) + - **adapter** parameter: alternative for *host* part, e.g.: + +```yaml +srt://10.10.10.100:5001?mode=listener +``` + +or + +```yaml +srt://:5001?adapter=10.10.10.100 +``` + +- In **CALLER** mode: + - *host* part: remote IP address to connect to (mandatory) + - *port* part: remote port to connect to (mandatory) + - **port** parameter: the local port to bind (default: 0 - "system autoselection") + - **adapter** parameter: the local IP address to bind (default: 0.0.0.0 - "system selected device") + +```yaml +srt://remote.host.com:5001 +``` + +```yaml +srt://remote.host.com:5001?adapter=local1&port=4001&mode=caller +``` + +- In **RENDEZVOUS** mode: same as **CALLER** except that the local +port, if not specified by the **port** parameter, defaults to the +value of the remote port (specified in the *port* part in the URI). + +```yaml +srt://remote.host.com:5001?mode=rendezvous +``` +(uses `remote.host.com` port 5001 for a remote host and the default +network device for routing to this host; the connection from the peer is +expected on that device and port 5001) + + +```yaml +srt://remote.host.com:5001?port=4001&adapter=local1 +``` +(uses `remote.host.com` port 5001 for a remote host and the peer +is expected to connect to `local1` address and port 4001) + + +**IMPORTANT** information about IPv6. + +This application can also use an address specified as IPv6 with +the following restrictions: + +1. The IPv6 address in the URI is specified in square brackets: e.g. +`srt://[::1]:5000`. + +2. In listener mode, if you leave the host empty, the socket is bound to +`INADDR_ANY` for IPv4 only. If you want to make it listen on IPv6, you need to +specify the host as `::`. +NOTE: Don't use square brackets syntax in the **adapter** parameter +specification, as in this case only the host is expected. + +3. If you want to listen for connections from both IPv4 and IPv6, mind the +`ipv6only` option. The default value for this option is system default (see +system manual for `IPV6_V6ONLY` socket option); if unsure, you might want to +enforce `ipv6only=0` in order to be able to accept both IPv4 and IPv6 +connections by the same listener, or set `ipv6only=1` to accept exclusively IPv6. + +4. In rendezvous mode you may only interconnect both parties using IPv4, +or both using IPv6. Unlike listener mode, if you want to leave the socket +default-bound (you don't specify `adapter`), the socket will be bound with the +same IP version as the target address. If you do specify `adapter`, +then both this address and the target address must be of the same family. + +Examples: + +* `srt://:5000` defines listener mode with IPv4. + +* `srt://[::]:5000` defines caller mode (!) with IPv6. + +* `srt://[::]:5000?mode=listener` defines listener mode with IPv6. If the + default value for `IPV6_V6ONLY` system socket option is 0, it will accept + also IPv4 connections. + +* `srt://192.168.0.5:5000?mode=rendezvous` will make a rendezvous connection + with local address `INADDR_ANY` (IPv4) and port 5000 to a destination with + port 5000. + +* `srt://[::1]:5000?mode=rendezvous&port=4000` will make a rendezvous + connection with local address `inaddr6_any` (IPv6) and port 4000 to a + destination with port 5000. + +* `srt://[::1]:5000?adapter=127.0.0.1` - this URI is invalid + (different IP versions for binding and target address in rendezvous mode) + +Some parameters handled for SRT medium are specific, all others are socket options. The following parameters are handled in a special way by `srt-live-transmit`: + +- **mode**: enforce caller, listener or rendezvous mode +- **port**: enforce the **outgoing** port (the port number that will be set in the UDP packet as a source port when sent from this host). Not used in **listener** mode. +- **blocking**: sets the `SRTO_RCVSYN` for input medium or `SRTO_SNDSYN` for output medium +- **timeout**: sets `SRTO_RCVTIMEO` for input medium or `SRTO_SNDTIMEO` for output medium +- **adapter**: sets the local IP address to bind + +All other parameters are SRT socket options. The Values column uses the +following type specification: + +- `bool`. Possible values: `yes`/`no`, `on`/`off`, `true`/`false`, `1`/`0`. +- `bytes` positive integer `[1; INT32_MAX]`. +- `ms` - positive integer value of milliseconds. + +| URI param | Values | SRT Option | Description | +| -------------------- | ---------------- | ------------------------- | ----------- | +| `congestion` | {`live`, `file`} | `SRTO_CONGESTION` | Type of congestion control. | +| `conntimeo` | `ms` | `SRTO_CONNTIMEO` | Connection timeout. | +| `drifttracer` | `bool` | `SRTO_DRIFTTRACER` | Enable drift tracer. | +| `enforcedencryption` | `bool` | `SRTO_ENFORCEDENCRYPTION` | Reject connection if parties set different passphrase. | +| `fc` | `bytes` | `SRTO_FC` | Flow control window size. | +| `groupconnect` | {`0`, `1`} | `SRTO_GROUPCONNECT` | Accept group connections. | +| `groupminstabletimeo`| 60.. `ms` | `SRTO_GROUPMINSTABLETIMEO`| Group minimum stability timeout. | +| `inputbw` | `bytes` | `SRTO_INPUTBW` | Input bandwidth. | +| `iptos` | 0..255 | `SRTO_IPTOS` | IP socket type of service | +| `ipttl` | 1..255 | `SRTO_IPTTL` | Defines IP socket "time to live" option. | +| `ipv6only` | -1..1 | `SRTO_IPV6ONLY` | Allow only IPv6. | +| `kmpreannounce` | 0.. | `SRTO_KMPREANNOUNCE` | Duration of Stream Encryption key switchover (in packets). | +| `kmrefreshrate` | 0.. | `SRTO_KMREFRESHRATE` | Stream encryption key refresh rate (in packets). | +| `latency` | 0.. | `SRTO_LATENCY` | Defines the maximum accepted transmission latency. | +| `linger` | 0.. | `SRTO_LINGER` | Link linger value | +| `lossmaxttl` | 0.. | `SRTO_LOSSMAXTTL` | Packet reorder tolerance. | +| `maxbw` | 0.. | `SRTO_MAXBW` | Bandwidth limit in bytes | +| `mininputbw` | 0.. | `SRTO_MININPUTBW` | Minimum allowed estimate of `SRTO_INPUTBW` | +| `messageapi` | `bool` | `SRTO_MESSAGEAPI` | Enable SRT message mode. | +| `minversion` | maj.min.rev | `SRTO_MINVERSION` | Minimum SRT library version of a peer. | +| `mss` | 76.. | `SRTO_MSS` | MTU size | +| `nakreport` | `bool` | `SRTO_NAKREPORT` | Enables/disables periodic NAK reports | +| `oheadbw` | 5..100 | `SRTO_OHEADBW` | limits bandwidth overhead, percents | +| `packetfilter` | `string` | `SRTO_PACKETFILTER` | Set up the packet filter. | +| `passphrase` | `string` | `SRTO_PASSPHRASE` | Password for the encrypted transmission. (must be 10 to 79 characters) | +| `payloadsize` | 0.. | `SRTO_PAYLOADSIZE` | Maximum payload size. | +| `pbkeylen` | {16, 24, 32} | `SRTO_PBKEYLEN` | Crypto key length in bytes. | +| `peeridletimeo` | `ms` | `SRTO_PEERIDLETIMEO` | Peer idle timeout. | +| `peerlatency` | `ms` | `SRTO_PEERLATENCY` | Minimum receiver latency to be requested by sender. | +| `rcvbuf` | `bytes` | `SRTO_RCVBUF` | Receiver buffer size | +| `rcvlatency` | `ms` | `SRTO_RCVLATENCY` | Receiver-side latency. | +| `retransmitalgo` | {`0`, `1`} | `SRTO_RETRANSMITALGO` | Packet retransmission algorithm to use. | +| `sndbuf` | `bytes` | `SRTO_SNDBUF` | Sender buffer size. | +| `snddropdelay` | `ms` | `SRTO_SNDDROPDELAY` | Sender's delay before dropping packets. | +| `streamid` | `string` | `SRTO_STREAMID` | Stream ID (settable in caller mode only, visible on the listener peer). | +| `tlpktdrop` | `bool` | `SRTO_TLPKTDROP` | Drop too late packets. | +| `transtype` | {`live`, `file`} | `SRTO_TRANSTYPE` | Transmission type | +| `tsbpdmode` | `bool` | `SRTO_TSBPDMODE` | Timestamp-based packet delivery mode. | + +The list of socket options can also be found in SRT header file `srt.h` (`SRT_SOCKOPT` enum type). +Please note that the set of available options may be version dependent. +All options are available under the lowercase name of the option without the `SRTO_` prefix. +For example, `SRTO_PASSPHRASE` can be set using a **passphrase** parameter. +The mapping table `srt_options` can be found in `common/socketoptions.hpp` file. + +Important thing about the options (which holds true also for options for +TCP and UDP, even though it's not described anywhere explicitly) is +that there are two categories of options: + +- PRE options: these options must be set to the socket prior to connecting and they cannot be altered after the connection is made. A PRE option set to a listening socket will be also derived by the socket returned by `srt_accept()`. +- POST options: these options can be set to a socket at any time. The option set to a listening socket will not be derived by an accepted socket. + +You don't have to worry about that actually - the application is aware +of this and it sets these options at appropriate time. + +Note also that **blocking** option has no practical use for users. +Normally the non-blocking mode is used only when you have an event-driven application that needs a common +signal bar for multiple event sources, or you prefer fibers to threads, when working with multiple SRT sockets in one application. The *srt-live-transmit* application isn't defined this way. This makes that the practical result of non-blocking mode here is that it uses polling on exactly one socket with infinite timeout. Every reading and writing operation will then return always without blocking, but when they report the "again" situation the application will stall on `srt_epoll_wait()` call. This option then exists for the testing purposes, as well as educational, to serve as an example of how your application should use the non-blocking mode. + +## Command-Line Options + +The following options are available in the application. Note that some may affect specifically only selected type of medium. + +Options usually have values and they are set using **colon**: for +example, **-t:60**. Alternatively you can also separate them by a space, +but this space must be part of the parameter and not extracted by a +shell (using **"** **"** quotes or backslash). + +- **-timeout, -t, -to** - Sets the timeout for any activity from any medium (in seconds). Default is 0 for infinite (that is, turn this mechanism off). The mechanism is such that the SIGALRM is set up to be called after the given time and it's reset after every reading succeeded. When the alarm expires due to no reading activity in defined time, it will break the application. **Notes:** + - The alarm is set up after the reading loop has started, **not when the application has started**. That is, a caller will still wait the standard timeout to connect, and a listener may wait infinitely until some peer connects; only after the connection is established is the alarm counting started. + - **The timeout mechanism doesn't work on Windows at all.** It behaves as if the timeout was set to **-1** and it's not modifiable. +- **-timeout-mode, -tm** - Timeout mode used. Default is 0 - timeout will happen after the specified time. Mode 1 cancels the timeout if the connection was established. +- **-st, -srctime, -sourcetime** - Enable source time passthrough. Default: disabled. It is recommended to build SRT with monotonic (`-DENABLE_MONOTONIC_CLOCK=ON`) or C++ 11 steady (`-DENABLE_STDCXX_SYNC=ON`) clock to use this feature. +- **-buffering** - Enable source buffering up to the specified number of packets. Default: 10. Minimum: 1 (no buffering). +- **-chunk, -c** - use given size of the buffer. The default size is 1456 bytes, which is the maximum payload size for a single SRT packet. +- **-verbose, -v** - Display additional information on the standard output. Note that it's not allowed to be combined with output specified as **file://con**. +- **-statsout** - SRT statistics output: filename. Without this option specified, the statistics will be printed to the standard output. +- **-pf**, **-statspf** - SRT statistics print format. Values: json, csv, default. After a comma, options can be specified (e.g. "json,pretty"). +- **-s**, **-stats**, **-stats-report-frequency** - The frequency of SRT statistics collection, based on the number of packets. +- **-loglevel** - lowest logging level for SRT, one of: *fatal, error, warn, note, debug* (default: *warn*) +- **-logfa, -lfa** - selected FAs in SRT to be logged (default: all are enabled). See the list of FAs running `-help:logging`. +- **-logfile:logs.txt** - Output of logs is written to file logs.txt instead of being printed to `stderr`. +- **-help, -h** - Show help. +- **-version** - Show version info. + +## Testing Considerations + +Before starting any test with `srt-live-transmit` please make sure your video source works properly. For example: if you use VLC as a test player, send a UDP stream directly to it before routing it through `srt-live-transmit`. + +For any MPEG-TS UDP based source make sure it has packet sizes of 1316 bytes. When using `ffmpeg` like in the "Example for Smoke Testing" section above set the `pkt_size=1316` parameter in case your input is a continuous data stream like from a file, camera or data-generator. + +When leaving the LAN for testing, please keep an eye on statistics and make sure your round-trip-time (RTT) is not drifting. It's recommended to set the latency 3 to 4 times higher than RTT. Especially on wireless links such as WLAN, Line-of-Sight Radio (LOS) and mobile links such as LTE/4G or 5G the RTT can vary a lot. + +If you perform tests on the public Internet, consider checking your firewall rules. The **SRT listener** must be reachable on the chosen UDP port. Same applies to routers using NAT. Please set a port forwarding rule with protocol UDP to the local IP address of the **SRT listener**. + +The initiation of an SRT connection (handshake) is decoupled from the stream direction. The +sender of a stream can be an **SRT listener** or an **SRT caller**, as long as the receiving end +uses the opposite connection mode. Typically you use the **SRT listener** on the receiving end, +since it is easier to configure in terms of firewall/router setup. It also makes sense to leave the +Sender in listener mode when trying to connect from various end points with possibly +unknown IP addresses. + +### UDP Performance + +Performance issues concerning reading from UDP medium were reported +in [#933](https://github.com/Haivision/srt/issues/933) and +[#762](https://github.com/Haivision/srt/issues/762). + +The dedicated research showed that at high and bursty data rates (~60 Mbps) +the `epoll_wait(udp_socket)` is not fast enough to signal about the possibility +of reading from a socket. It results in losing data when the input bitrate is very high (above 20 Mbps). + +PR [#1152](https://github.com/Haivision/srt/pull/1152) (SRT v1.4.2 and above) adds the possibility +of setting the buffer size of the UDP socket in `srt-live-transmit`. +Having a bigger buffer of UDP socket to store incoming data, `srt-live-transmit` handles higher bitrates. + +The following steps have to be performed to use the bigger UDP buffer size. + +### Increase the system-default max rcv buffer size + +```bash +$ cat /proc/sys/net/core/rmem_max +212992 +$ sudo sysctl -w net.core.rmem_max=26214400 +net.core.rmem_max = 26214400 +$ cat /proc/sys/net/core/rmem_max +26214400 +``` + +### Specify the size of the UDP socket buffer via the URI + +Example URI: + +```bash +"udp://:4200?rcvbuf=67108864" +``` + +Example full URI: + +```bash +./srt-live-transmit "udp://:4200?rcvbuf=67108864" srt://192.168.0.10:4200 -v +``` diff --git a/docs/apps/srt-test-multiplex.md b/docs/apps/srt-test-multiplex.md new file mode 100644 index 0000000..8e855a1 --- /dev/null +++ b/docs/apps/srt-test-multiplex.md @@ -0,0 +1,99 @@ +# srt-test-multiplex + +**srt-test-multiplex** (formerly called "SIPLEX") is a sample program that can +send multiple streams in one direction. This tool demonstrates two SRT features: + - the ability to use a single UDP link (a source and destination pair + specified by IP address and port) for multiple SRT connections + - the use of the `streamid` socket option to identify multiplexed resources + +NOTE: To make this application compiled, you need the `-DENABLE_TESTING=1` +cmake option. + +Note also that this application is intended for demonstration only. It can +simply exit with error message in case of wrong usage or broken connection. + + +## Usage + +`srt-test-multiplex -i [id1] [id2]...` + + - Reads all given input streams and sends them each one over a separate + SRT connection, all using the same remote address and source port (hence + using the same UDP link). + +`srt-test-multiplex -o [id] [id]...` + + - Transmits data from a multiplexed SRT stream to the specified output URI(s). + +An `` can be identified as input or output using the **-i** or **-o** +options. When `-i` is specified, the URIs provided are used as input, and will +be output over the `` socket. The reverse is true for any output URIs +specified by `-o`. + +If SRT-URI is caller mode, then for every declared input or output medium a +separate connection will be made, each one using the same source port (if +specified, the same will be used for all connections, otherwise the first one +will be automatically selected and then reused for all next ones) and with the +`streamid` socket option set to the value extracted from the medium's +`id` specified parameter: +``` +URI1?id=a --> s1(streamid=a).connect(remhost:2000) +URI2?id=b --> s2(streamid=b).connect(remhost:2000) +URI3?id=c --> s3(streamid=c).connect(remhost:2000) +``` + +If SRT-URI is listener mode, then it will extract the value from `streamid` +socket option and every accepted connection will be matched against the `id` +parameter of the specified input or output medium. +``` +(remhost:2000) -> accept --> s(SRT socket) --> in URI array find such that uri.id == s.streamid +``` + +Note that the rendezvous mode is not supported because you cannot make +multiple connections over the same UDP link in rendezvous mode. + +This `streamid` is the SRT socket option (`SRTO_STREAMID` in the API). The idea +is that it can be set on a socket used for connecting. When a listener is +getting an accepted socket for that connection, the `streamid` socket option +can be read from it, with the result that it will be the same as was set on +the caller side. + + +## Examples + + - **Sender:** + - `srt-test-multiplex srt://remhost:2000 -i udp://:5000?id=low udp://:6000?id=high` + - **Receiver:** + - `srt-test-multiplex srt://:2000 -o output-high.ts?id=high output-low.ts?id=low` + +In this example a Sender is created which will connect to `remhost` port 2000 +using multiple SRT sockets, all of which will be using the same outgoing port. +Here the outgoing port is automatically selected when connecting. Subsequent +sockets will reuse that port. Alternatively you can enforce the outgoing port +using the `port` parameter with the ``. + + - **Sender:** + - `srt-test-multiplex srt://remhost:2000?port=5555 ...` + +A separate connection is made for every input resource. An appropriate resource +ID will be set to each socket assigned to that resource according to the `id` +parameter. +``` + +-- --+ + | id=1 id=1 | + | ------ ------- | + | \ -----> / | + | id=2 \ ---------------------------- / id=2 | +port=5555 -| --------- ( multiplexed UDP stream ) ---------- |- port=2000 + | / ---------------------------- \ | + | id=3 / \ id=3 | + | ------ ------ | + +-- --+ +``` +When a socket is accepted on the listener side (the Receiver in this example), +srt-test-multiplex will search for the resource ID among the registered resources +(input/output URIs) and set an ID that matches the one on the caller side. If +the resource is not found, the connection is closed immediately. + +The srt-test-multiplex program works the same way for connections initiated by a +caller or a listener. diff --git a/docs/apps/srt-test-relay.md b/docs/apps/srt-test-relay.md new file mode 100644 index 0000000..85789b6 --- /dev/null +++ b/docs/apps/srt-test-relay.md @@ -0,0 +1,34 @@ +# srt-test-relay + +**srt-test-relay** is a sample program that can utilize SRT connection for +bidirectional traffic. Hence beside the SRT connection you can specify both +input and output media to and from which the traffic will be flipped. + +Effectively the specified input will be sent through the SRT connection as +output, and the input read from the SRT connection will be redirected to +the given output media. + +NOTE: To make this application compiled, you need the `-DENABLE_TESTING=1` +cmake option. + +Note also that this application is intended for demonstration only. It can +simply exit with error message in case of wrong usage or broken connection. + +## Usage + +`srt-test-relay -i -o ` + +Establish a connection, send to it the stream received from INPUT URI and +write the data read from the SRT connection to OUTPUT URI. + +`srt-test-relay -e -o ` + +Establish a connection, read the data from the SRT connection, and write +them back over the SRT connection, and additionally write them as well +to OUTPUT URI and OUTPUT URI2. + +Note that you can also control the single portion of data to be sent +at once by one sending call by `-c` option and you can use both live +and file mode for the connection (the latter should be simply enforced +by `transtype` socket option). + diff --git a/docs/apps/srt-tunnel.md b/docs/apps/srt-tunnel.md new file mode 100644 index 0000000..c664173 --- /dev/null +++ b/docs/apps/srt-tunnel.md @@ -0,0 +1,37 @@ +# srt-tunnel + + +## Purpose + +SRT Tunnel is a typical tunnelling application, that is, it simply passes the +transmission from a given endpoint to another endpoint in both directions. + +Tunnels can be also "chained", that is, there can be more than one tunnel on +the way between the real peers. + +This tunnel application can use both TCP and SRT as endpoint type and the +typically predicted use case is to hand over the transmission for SRT for a +longer distance, leaving TCP close to the caller and listener locations: + +``` + --> SRT> --> ... + .... + (long distance) + .... + --> TCP> --> +``` + +## Usage + +The `srt-tunnel` command line accepts two argument, beside the options: +* Listener: the URI at which this tunnel should await connections +* Caller: where this tunnel should connect when its Listener connected + +Options: + +* -ll, -loglevel: logging level, default:error +* -lf, -logfa: logging Functional Area enabled +* -c, -chunk: piece of data amount read at once, default=4096 bytes +* -v, -verbose: display transmission details +* -s, -skipflush: exit without waiting for data to complete + diff --git a/docs/build/build-android.md b/docs/build/build-android.md new file mode 100644 index 0000000..7c13c94 --- /dev/null +++ b/docs/build/build-android.md @@ -0,0 +1,18 @@ +# Building SRT on Android + +**NOTE:** The scripts have been moved to [scripts/build-android](../../scripts/build-android/) folder. + +## Install the NDK and CMake + +The Android NDK is required to build native modules for Android. +[Install and configure the NDK](https://developer.android.com/studio/projects/install-ndk) + +Consider installing the latest version of cmake. The higher version of cmake the better. As of writing the current version of CMake is 3.18.4 +You can download Cmake from the following website: +[https://cmake.org/download](https://cmake.org/download/) + +## Build SRT for Android + +Run ```./build-android -n /path/to/ndk```. E.g. ```./build-android -n /home/username/Android/Sdk/ndk/21.4.7075529``` + +[Include prebuilt native libraries](https://developer.android.com/studio/projects/gradle-external-native-builds#jniLibs) from ```prebuilt``` folder into Android Studio project. diff --git a/docs/build/build-iOS.md b/docs/build/build-iOS.md new file mode 100644 index 0000000..92ee517 --- /dev/null +++ b/docs/build/build-iOS.md @@ -0,0 +1,44 @@ +# Building SRT on iOS + +## Prerequisites +* Xcode should be installed. Check in terminal whether `xcode-select -p` points to **/Applications/Xcode.app/Contents/Developer** +* Install Homebrew according to instructions on [https://brew.sh/](https://brew.sh/) +* Install CMake and pkg-config with Homebrew: +``` +brew install cmake +brew install pkg-config +``` + +## Building OpenSSL +There is [OpenSSL for iPhone](https://github.com/x2on/OpenSSL-for-iPhone) project which have all necessary to build OpenSSL for our needs. It fetches OpenSSL code by itself, so you don't need to download it separately. So simply clone it and build with command: +``` +./build-libssl.sh --archs="arm64" +``` + +Results (both libraries and headers) will be placed in bin/<SDK_VERSION>-<ARCH>.sdk directory (for example, *bin/iPhoneOS11.2-arm64.sdk*). We assume you set **IOS_OPENSSL** variable to this path (e.g. `export IOS_OPENSSL="/Users/johndoe/sources/OpenSSL-for-iPhone/bin/iPhoneOS11.2-arm64.sdk"`). + +## Building SRT code +Now you can build SRT providing path to OpenSSL library and toolchain file for iOS + +``` +./configure --cmake-prefix-path=$IOS_OPENSSL --use-openssl-pc=OFF --cmake-toolchain-file=scripts/iOS.cmake +make +``` + +Optionally you may add following iOS-specifc settings to configure: + +* `--ios-disable-bitcode=1` - disable embedding bitcode to library. +* `--ios-arch=armv7|armv7s|arm64` - specify if you want to build for specific architecture (arm64 by default) +* `--ios-platform=OS|SIMULATOR|SIMULATOR64` - specify for build simulator code +* `--cmake-ios-developer-root=<path>`- specify path for platform directory; {XCODE_ROOT}/Platforms/iPhoneOS.platform/Developer by default +* `--cmake-ios-sdk-root=` - by default searches for latest SDK version within {CMAKE_IOS_DEVELOPER_ROOT}/SDKs, set if you want to use another SDK version + +Note that resulting .dylib file has install path @executable_path/Frameworks/libsrt.1.dylib, so if you need to place it in some other place with your application, you may change it with *install_name_tool* command: ``install_name_tool -id "" ``, for example ``install_name_tool -id "@executable_path/Frameworks/libsrt.1.3.0.dylib" libsrt.1.3.0.dylib`` + +## Adding to Xcode project +In Xcode project settings in General tab, add libsrt to **Linked Frameworks and Libraries** section - click Plus sign, then click "Add Other" and find libsrt.1.dylib + +Click plus sign in **Embedded binaries** section and choose Frameworks/libsrt.1.dylib + +In **Build settings** tab find **Header Search Paths** setting +and add paths to SRT library sources (you should add srt, srt/common and srt/common directories). diff --git a/docs/build/build-linux.md b/docs/build/build-linux.md new file mode 100644 index 0000000..678e966 --- /dev/null +++ b/docs/build/build-linux.md @@ -0,0 +1,44 @@ +# Building SRT on Linux + +Install `cmake` and `openssl-devel` (or equivalent) packages. For `pthreads`, add +the `-lpthreads` linker flag. + +Default installation path prefix of `make install` is `/usr/local`. + +To define a different installation path prefix, use the `--prefix` option with `configure` +or the [`-DCMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html) CMake option. + +To uninstall, call `make -n install` to list all the dependencies, and then pass the list to `rm`. + +Here is a link to a demo showing how CMake can be used to build SRT: +[Quickstart: Running SRT and FFmpeg on Ubuntu](https://www.youtube.com/watch?v=XOtUOVhussc&t=5s). + +## Ubuntu 14 + +```shell +sudo apt-get update +sudo apt-get upgrade +sudo apt-get install tclsh pkg-config cmake libssl-dev build-essential +./configure +make +``` + +## CentOS 7 + +```shell +sudo yum update +sudo yum install tcl pkgconfig openssl-devel cmake gcc gcc-c++ make automake +./configure +make +``` + +## CentOS 6 + +```shell +sudo yum update +sudo yum install tcl pkgconfig openssl-devel cmake gcc gcc-c++ make automake +sudo yum install centos-release-scl-rh devtoolset-3-gcc devtoolset-3-gcc-c++ +scl enable devtoolset-3 bash +./configure --use-static-libstdc++ --with-compiler-prefix=/opt/rh/devtoolset-3/root/usr/bin/ +make +``` diff --git a/docs/build/build-macOS.md b/docs/build/build-macOS.md new file mode 100644 index 0000000..6f6565b --- /dev/null +++ b/docs/build/build-macOS.md @@ -0,0 +1,32 @@ +# Building SRT on macOS + +[Homebrew](https://brew.sh/) supports the **srt** formula. + +```shell +brew update +brew install srt +``` + +If you prefer using a head commit of `master` branch, add the `--HEAD` option +to `brew` command. + +```shell +brew install --HEAD srt +``` + +Install [CMake](https://cmake.org/) and OpenSSL with development files from `brew`. It is recommended to install the latest version of OpenSSL from the `brew` system rather than relying on the version that is presently installed in the system. + +```shell +brew install cmake +brew install openssl +``` + +SRT can be now built with `cmake` or `make` on Mac. + +```shell +export OPENSSL_ROOT_DIR=$(brew --prefix openssl) +export OPENSSL_LIB_DIR=$(brew --prefix openssl)"/lib" +export OPENSSL_INCLUDE_DIR=$(brew --prefix openssl)"/include" +./configure +make +``` diff --git a/docs/build/build-options.md b/docs/build/build-options.md new file mode 100644 index 0000000..8c87229 --- /dev/null +++ b/docs/build/build-options.md @@ -0,0 +1,656 @@ +# Build System + +The SRT build system uses [`CMake`](https://cmake.org/) 2.8.12 or above. + +A wrapper script named [`configure`](https://github.com/Haivision/srt/blob/master/configure) +is also available. The `configure` script can simplify the build process, such as +by trying to automatically detect the OpenSSL path in a system. Note that you must +have the Tcl interpreter installed to use this script. + + +Here is a link to a demo showing how CMake can be used to build SRT: +[Quickstart: Running SRT and FFmpeg on Ubuntu](https://www.youtube.com/watch?v=XOtUOVhussc&t=5s). + + +Additional information on building for Windows is available in the +[Building SRT for Windows](https://github.com/Haivision/srt/blob/master/docs/build/build-win.md) +document and in the [SRT CookBook](https://srtlab.github.io/srt-cookbook/getting-started/build-on-windows/). + + +## List of Build Options + +The following table lists available build options in alphabetical order. +Option details are given further below. + + +| Option Name | Since | Type | Default | Short Description | +| :----------------------------------------------------------- | :---: | :-------: | :--------: | ----------------- | +| [`CMAKE_INSTALL_PREFIX`](#cmake_install_prefix) | 1.3.0 | `STRING` | OFF | Standard CMake variable that establishes the root directory for installation, inside of which a GNU/POSIX compatible directory layout will be used. | +| [`CYGWIN_USE_POSIX`](#cygwin_use_posix) | 1.2.0 | `BOOL` | OFF | Determines when to compile on Cygwin using POSIX API. | +| [`ENABLE_APPS`](#enable_apps) | 1.3.3 | `BOOL` | ON | Enables compiling sample applications (srt-live-trasnmit, etc.). | +| [`ENABLE_BONDING`](#enable_bonding) | 1.5.0 | `BOOL` | OFF | Enables the [Connection Bonding](../features/bonding-quick-start.md) feature. | +| [`ENABLE_CXX_DEPS`](#enable_cxx_deps) | 1.3.2 | `BOOL` | OFF | The `pkg-confg` file (`srt.pc`) will be generated with the `libstdc++` library as a dependency. | +| [`ENABLE_CXX11`](#enable_cxx11) | 1.2.0 | `BOOL` | ON | Enable compiling in C++11 mode for those parts that may require it. Default: ON except for GCC<4.7 | +| [`ENABLE_CODE_COVERAGE`](#enable_code_coverage) | 1.4.0 | `BOOL` | OFF | Enables instrumentation for code coverage. | +| [`ENABLE_DEBUG`](#enable_debug>) | 1.2.0 | `INT` | ON | Allows release/debug control through the `CMAKE_BUILD_TYPE` variable. | +| [`ENABLE_ENCRYPTION`](#enable_encryption) | 1.3.3 | `BOOL` | ON | Enables encryption feature enabled, with dependency on an external encryption library. | +| [`ENABLE_GETNAMEINFO`](#enable_getnameinfo) | 1.3.0 | `BOOL` | OFF | Enables the use of `getnameinfo` to allow using reverse DNS to resolve an internal IP address into a readable internet domain name. | +| [`ENABLE_HAICRYPT_LOGGING`](#enable_haicrypt_logging) | 1.3.1 | `BOOL` | OFF | Enables logging in the *haicrypt* module, which serves as a connector to an encryption library. | +| [`ENABLE_HEAVY_LOGGING`](#enable_heavy_logging) | 1.3.0 | `BOOL` | OFF | Enables heavy logging instructions in the code that occur often and cover many detailed aspects of library behavior. Default: OFF in release mode. | +| [`ENABLE_INET_PTON`](#enable_inet_pton) | 1.3.2 | `BOOL` | ON | Enables usage of the `inet_pton` function used to resolve the network endpoint name into an IP address. | +| [`ENABLE_LOGGING`](#enable_logging) | 1.2.0 | `BOOL` | ON | Enables normal logging, including errors. | +| [`ENABLE_MONOTONIC_CLOCK`](#enable_monotonic_clock) | 1.4.0 | `BOOL` | ON* | Enforces the use of `clock_gettime` with a monotonic clock that is independent of the currently set time in the system. | +| [`ENABLE_NEW_RCVBUFFER`](#enable_new_rcvbuffer) | 1.5.0 | `BOOL` | ON | Enables the new implementation of the receiver buffer with behavior and code improvements. | +| [`ENABLE_PROFILE`](#enable_profile) | 1.2.0 | `BOOL` | OFF | Enables code instrumentation for profiling (only for GNU-compatible compilers). | +| [`ENABLE_RELATIVE_LIBPATH`](#enable_relative_libpath) | 1.3.2 | `BOOL` | OFF | Enables adding a relative path to a library for linking against a shared SRT library by reaching out to a sibling directory. | +| [`ENABLE_SHARED`](#enable_shared--enable_static) | 1.2.0 | `BOOL` | ON | Enables building SRT as a shared library | +| [`ENABLE_SHOW_PROJECT_CONFIG`](#enable_show_project_config) | 1.5.0 | `BOOL` | OFF | When ON, the project configuration is displayed at the end of the CMake Configuration Step. | +| [`ENABLE_STATIC`](#enable_shared--enable_static) | 1.3.0 | `BOOL` | ON | Enables building SRT as a tatic library | +| [`ENABLE_STDCXX_SYNC`](#enable_stdcxx_sync) | 1.4.2 | `BOOL` | ON* | Enables the standard C++11 `thread` and `chrono` libraries to be used by SRT instead of the `pthreads`. | +| [`ENABLE_TESTING`](#enable_testing) | 1.3.0 | `BOOL` | OFF | Enables compiling of developer testing applications (srt-test-live, etc.). | +| [`ENABLE_THREAD_CHECK`](#enable_thread_check) | 1.3.0 | `BOOL` | OFF | Enables `#include `, which implements `THREAD_*` macros" to support better thread debugging. | +| [`ENABLE_UNITTESTS`](#enable_unittests) | 1.3.2 | `BOOL` | OFF | Enables building unit tests. | +| [`OPENSSL_CRYPTO_LIBRARY`](#openssl_crypto_library) | 1.3.0 | `STRING` | OFF | Configures the path to an OpenSSL Crypto library. | +| [`OPENSSL_INCLUDE_DIR`](#openssl_include_dir) | 1.3.0 | `STRING` | OFF | Configures the path to include files for an OpenSSL library. | +| [`OPENSSL_SSL_LIBRARY`](#openssl_ssl_library) | 1.3.0 | `STRING` | OFF | Configures the path to an OpenSSL SSL library. | +| [`PKG_CONFIG_EXECUTABLE`](#pkg_config_executable) | 1.3.0 | `BOOL` | OFF | Configures the path to the `pkg-config` tool. | +| [`PTHREAD_INCLUDE_DIR`](#pthread_include_dir) | 1.3.0 | `STRING` | OFF | Configures the path to include files for a pthread library. | +| [`PTHREAD_LIBRARY`](#pthread_library) | 1.3.0 | `STRING` | OFF | Configures the path to a pthread library. | +| [`USE_BUSY_WAITING`](#use_busy_waiting) | 1.3.3 | `BOOL` | OFF | Enables more accurate sending times at the cost of potentially higher CPU load. | +| [`USE_CXX_STD`](#use_cxx_std) | 1.4.2 | `STRING` | OFF | Enforces using a particular C++ standard (11, 14, 17, etc.) when compiling. | +| [`USE_ENCLIB`](#use_enclib) | 1.3.3 | `STRING` | openssl | Encryption library to be used (`openssl`, `gnutls`, `mbedtls`). | +| [`USE_GNUSTL`](#use_gnustl) | 1.3.4 | `BOOL` | OFF | Use `pkg-config` with the `gnustl` package name to extract the header and library path for the C++ standard library. | +| [`USE_OPENSSL_PC`](#use_openssl_pc) | 1.3.0 | `BOOL` | ON | Use `pkg-config` to find OpenSSL libraries. | +| [`OPENSSL_USE_STATIC_LIBS`](#openssl_use_static_libs) | 1.5.0 | `BOOL` | OFF | Link OpenSSL statically. | +| [`USE_STATIC_LIBSTDCXX`](#use_static_libstdcxx) | 1.2.0 | `BOOL` | OFF | Enforces linking the SRT library against the static libstdc++ library. | +| [`WITH_COMPILER_PREFIX`](#with_compiler_prefix) | 1.3.0 | `STRING` | OFF | Sets C/C++ toolchains as `` and ``, overriding the default compiler. | +| [`WITH_COMPILER_TYPE`](#with_compiler_type) | 1.3.0 | `STRING` | OFF | Sets the compiler type to be used (values: gcc, cc, clang, etc.). | +| [`WITH_EXTRALIBS`](#with_extralibs) | 1.3.0 | `STRING` | OFF | Option required for unusual situations when a platform-specific workaround is needed and some extra libraries must be passed explicitly for linkage. | +| [`WITH_SRT_NAME`](#with_srt_name) | 1.3.0 | `STRING` | OFF | Configure the SRT library name adding a custom `` | +| | | | | | + + +\* See the option description for more details. + +## Using CMake + +If you choose to use CMake directly for the build configuration stage, you must +specify option values in the CMake format: + +`-D