diff --git a/HaishinKit.xcodeproj/project.pbxproj b/HaishinKit.xcodeproj/project.pbxproj index cb15f2fbd..5d961c313 100644 --- a/HaishinKit.xcodeproj/project.pbxproj +++ b/HaishinKit.xcodeproj/project.pbxproj @@ -2229,7 +2229,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MACOSX_DEPLOYMENT_TARGET = 10.13; MARKETING_VERSION = 1.6.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; @@ -2275,7 +2275,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MACOSX_DEPLOYMENT_TARGET = 10.13; MARKETING_VERSION = 1.6.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; @@ -2441,7 +2441,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MACOSX_DEPLOYMENT_TARGET = 13.0; OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ExistentialAny"; PRODUCT_BUNDLE_IDENTIFIER = "com.haishinkit.HaishinKit.Example-macOS"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2469,7 +2469,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MACOSX_DEPLOYMENT_TARGET = 13.0; OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ExistentialAny"; PRODUCT_BUNDLE_IDENTIFIER = "com.haishinkit.HaishinKit.Example-macOS"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2583,7 +2583,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 1.6.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++20"; @@ -2637,7 +2637,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 1.6.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++20"; diff --git a/Vendor/SRT/Includes/access_control.h b/Vendor/SRT/Includes/access_control.h deleted file mode 100644 index 97a1104a8..000000000 --- a/Vendor/SRT/Includes/access_control.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SRT - Secure, Reliable, Transport - * Copyright (c) 2020 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/. - * - */ - -/***************************************************************************** -written by - Haivision Systems Inc. - *****************************************************************************/ - -#ifndef INC_F_ACCESS_CONTROL_H -#define INC_F_ACCESS_CONTROL_H - -// A list of rejection codes that are SRT specific. - -#define SRT_REJX_FALLBACK 1000 // A code used in case when the application wants to report some problem, but can't precisely specify it. -#define SRT_REJX_KEY_NOTSUP 1001 // The key used in the StreamID keyed string is not supported by the service. -#define SRT_REJX_FILEPATH 1002 // The resource type designates a file and the path is either wrong syntax or not found -#define SRT_REJX_HOSTNOTFOUND 1003 // The `h` host specification was not recognized by the service - -// The list of http codes adopted for SRT. -// An example C++ header for HTTP codes can be found at: -// https://github.com/j-ulrich/http-status-codes-cpp - -// Some of the unused code can be revived in the future, if there -// happens to be a good reason for it. - -#define SRT_REJX_BAD_REQUEST 1400 // General syntax error in the SocketID specification (also a fallback code for undefined cases) -#define SRT_REJX_UNAUTHORIZED 1401 // Authentication failed, provided that the user was correctly identified and access to the required resource would be granted -#define SRT_REJX_OVERLOAD 1402 // The server is too heavily loaded, or you have exceeded credits for accessing the service and the resource. -#define SRT_REJX_FORBIDDEN 1403 // Access denied to the resource by any kind of reason. -#define SRT_REJX_NOTFOUND 1404 // Resource not found at this time. -#define SRT_REJX_BAD_MODE 1405 // The mode specified in `m` key in StreamID is not supported for this request. -#define SRT_REJX_UNACCEPTABLE 1406 // The requested parameters specified in SocketID cannot be satisfied for the requested resource. Also when m=publish and the data format is not acceptable. -// CODE NOT IN USE 407: unused: proxy functionality not predicted -// CODE NOT IN USE 408: unused: no timeout predicted for listener callback -#define SRT_REJX_CONFLICT 1409 // The resource being accessed is already locked for modification. This is in case of m=publish and the specified resource is currently read-only. -// CODE NOT IN USE 410: unused: treated as a specific case of 404 -// CODE NOT IN USE 411: unused: no reason to include lenght in the protocol -// CODE NOT IN USE 412: unused: preconditions not predicted in AC -// CODE NOT IN USE 413: unused: AC size is already defined as 512 -// CODE NOT IN USE 414: unused: AC size is already defined as 512 -#define SRT_REJX_NOTSUP_MEDIA 1415 // The media type is not supported by the application. This is the `t` key that specifies the media type as stream, file and auth, possibly extended by the application. -// CODE NOT IN USE 416: unused: no detailed specification defined -// CODE NOT IN USE 417: unused: expectations not supported -// CODE NOT IN USE 418: unused: sharks do not drink tea -// CODE NOT IN USE 419: not defined in HTTP -// CODE NOT IN USE 420: not defined in HTTP -// CODE NOT IN USE 421: unused: misdirection not supported -// CODE NOT IN USE 422: unused: aligned to general 400 -#define SRT_REJX_LOCKED 1423 // The resource being accessed is locked for any access. -#define SRT_REJX_FAILED_DEPEND 1424 // The request failed because it specified a dependent session ID that has been disconnected. -// CODE NOT IN USE 425: unused: replaying not supported -// CODE NOT IN USE 426: unused: tempting, but it requires resend in connected -// CODE NOT IN USE 427: not defined in HTTP -// CODE NOT IN USE 428: unused: renders to 409 -// CODE NOT IN USE 429: unused: renders to 402 -// CODE NOT IN USE 451: unused: renders to 403 -#define SRT_REJX_ISE 1500 // Unexpected internal server error -#define SRT_REJX_UNIMPLEMENTED 1501 // The request was recognized, but the current version doesn't support it. -#define SRT_REJX_GW 1502 // The server acts as a gateway and the target endpoint rejected the connection. -#define SRT_REJX_DOWN 1503 // The service has been temporarily taken over by a stub reporting this error. The real service can be down for maintenance or crashed. -// CODE NOT IN USE 504: unused: timeout not supported -#define SRT_REJX_VERSION 1505 // SRT version not supported. This might be either unsupported backward compatibility, or an upper value of a version. -// CODE NOT IN USE 506: unused: negotiation and references not supported -#define SRT_REJX_NOROOM 1507 // The data stream cannot be archived due to lacking storage space. This is in case when the request type was to send a file or the live stream to be archived. -// CODE NOT IN USE 508: unused: no redirection supported -// CODE NOT IN USE 509: not defined in HTTP -// CODE NOT IN USE 510: unused: extensions not supported -// CODE NOT IN USE 511: unused: intercepting proxies not supported - - - -#endif diff --git a/Vendor/SRT/Includes/api.h b/Vendor/SRT/Includes/api.h deleted file mode 100644 index ca812bf9e..000000000 --- a/Vendor/SRT/Includes/api.h +++ /dev/null @@ -1,487 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 09/28/2010 -modified by - Haivision Systems Inc. -*****************************************************************************/ - -#ifndef INC_SRT_API_H -#define INC_SRT_API_H - -#include -#include -#include -#include "netinet_any.h" -#include "udt.h" -#include "packet.h" -#include "queue.h" -#include "cache.h" -#include "epoll.h" -#include "handshake.h" -#include "core.h" -#if ENABLE_BONDING -#include "group.h" -#endif - -// Please refer to structure and locking information provided in the -// docs/dev/low-level-info.md document. - -namespace srt -{ - -class CUDT; - -/// @brief Class CUDTSocket is a control layer on top of the CUDT core functionality layer. -/// CUDTSocket owns CUDT. -class CUDTSocket -{ -public: - CUDTSocket() - : m_Status(SRTS_INIT) - , m_SocketID(0) - , m_ListenSocket(0) - , m_PeerID(0) -#if ENABLE_BONDING - , m_GroupMemberData() - , m_GroupOf() -#endif - , m_iISN(0) - , m_UDT(this) - , m_AcceptCond() - , m_AcceptLock() - , m_uiBackLog(0) - , m_iMuxID(-1) - { - construct(); - } - - CUDTSocket(const CUDTSocket& ancestor) - : m_Status(SRTS_INIT) - , m_SocketID(0) - , m_ListenSocket(0) - , m_PeerID(0) -#if ENABLE_BONDING - , m_GroupMemberData() - , m_GroupOf() -#endif - , m_iISN(0) - , m_UDT(this, ancestor.m_UDT) - , m_AcceptCond() - , m_AcceptLock() - , m_uiBackLog(0) - , m_iMuxID(-1) - { - construct(); - } - - ~CUDTSocket(); - - void construct(); - - SRT_ATTR_GUARDED_BY(m_ControlLock) - sync::atomic m_Status; //< current socket state - - /// Time when the socket is closed. - /// When the socket is closed, it is not removed immediately from the list - /// of sockets in order to prevent other methods from accessing invalid address. - /// A timer is started and the socket will be removed after approximately - /// 1 second (see CUDTUnited::checkBrokenSockets()). - sync::steady_clock::time_point m_tsClosureTimeStamp; - - sockaddr_any m_SelfAddr; //< local address of the socket - sockaddr_any m_PeerAddr; //< peer address of the socket - - SRTSOCKET m_SocketID; //< socket ID - SRTSOCKET m_ListenSocket; //< ID of the listener socket; 0 means this is an independent socket - - SRTSOCKET m_PeerID; //< peer socket ID -#if ENABLE_BONDING - groups::SocketData* m_GroupMemberData; //< Pointer to group member data, or NULL if not a group member - CUDTGroup* m_GroupOf; //< Group this socket is a member of, or NULL if it isn't -#endif - - int32_t m_iISN; //< initial sequence number, used to tell different connection from same IP:port - -private: - CUDT m_UDT; //< internal SRT socket logic - -public: - std::set m_QueuedSockets; //< set of connections waiting for accept() - - sync::Condition m_AcceptCond; //< used to block "accept" call - sync::Mutex m_AcceptLock; //< mutex associated to m_AcceptCond - - unsigned int m_uiBackLog; //< maximum number of connections in queue - - // XXX A refactoring might be needed here. - - // There are no reasons found why the socket can't contain a list iterator to a - // multiplexer INSTEAD of m_iMuxID. There's no danger in this solution because - // the multiplexer is never deleted until there's at least one socket using it. - // - // The multiplexer may even physically be contained in the CUDTUnited object, - // just track the multiple users of it (the listener and the accepted sockets). - // When deleting, you simply "unsubscribe" yourself from the multiplexer, which - // will unref it and remove the list element by the iterator kept by the - // socket. - int m_iMuxID; //< multiplexer ID - - sync::Mutex m_ControlLock; //< lock this socket exclusively for control APIs: bind/listen/connect - - CUDT& core() { return m_UDT; } - const CUDT& core() const { return m_UDT; } - - static int64_t getPeerSpec(SRTSOCKET id, int32_t isn) { return (int64_t(id) << 30) + isn; } - int64_t getPeerSpec() { return getPeerSpec(m_PeerID, m_iISN); } - - SRT_SOCKSTATUS getStatus(); - - /// This function shall be called always wherever - /// you'd like to call cudtsocket->m_pUDT->close(), - /// from within the GC thread only (that is, only when - /// the socket should be no longer visible in the - /// connection, including for sending remaining data). - void breakSocket_LOCKED(); - - /// This makes the socket no longer capable of performing any transmission - /// operation, but continues to be responsive in the connection in order - /// to finish sending the data that were scheduled for sending so far. - void setClosed(); - - /// This does the same as setClosed, plus sets the m_bBroken to true. - /// Such a socket can still be read from so that remaining data from - /// the receiver buffer can be read, but no longer sends anything. - void setBrokenClosed(); - void removeFromGroup(bool broken); - - // Instrumentally used by select() and also required for non-blocking - // mode check in groups - bool readReady(); - bool writeReady() const; - bool broken() const; - -private: - CUDTSocket& operator=(const CUDTSocket&); -}; - -//////////////////////////////////////////////////////////////////////////////// - -class CUDTUnited -{ - friend class CUDT; - friend class CUDTGroup; - friend class CRendezvousQueue; - friend class CCryptoControl; - -public: - CUDTUnited(); - ~CUDTUnited(); - - // Public constants - static const int32_t MAX_SOCKET_VAL = SRTGROUP_MASK - 1; // maximum value for a regular socket - -public: - enum ErrorHandling - { - ERH_RETURN, - ERH_THROW, - ERH_ABORT - }; - static std::string CONID(SRTSOCKET sock); - - /// initialize the UDT library. - /// @return 0 if success, otherwise -1 is returned. - int startup(); - - /// release the UDT library. - /// @return 0 if success, otherwise -1 is returned. - int cleanup(); - - /// Create a new UDT socket. - /// @param [out] pps Variable (optional) to which the new socket will be written, if succeeded - /// @return The new UDT socket ID, or INVALID_SOCK. - SRTSOCKET newSocket(CUDTSocket** pps = NULL); - - /// Create (listener-side) a new socket associated with the incoming connection request. - /// @param [in] listen the listening socket ID. - /// @param [in] peer peer address. - /// @param [in,out] hs handshake information from peer side (in), negotiated value (out); - /// @param [out] w_error error code in case of failure. - /// @param [out] w_acpu reference to the existing associated socket if already exists. - /// @return 1: if the new connection was successfully created (accepted), @a w_acpu is NULL; - /// 0: the connection already exists (reference to the corresponding socket is returned in @a w_acpu). - /// -1: The connection processing failed due to memory alloation error, exceeding listener's backlog, - /// any error propagated from CUDT::open and CUDT::acceptAndRespond. - int newConnection(const SRTSOCKET listen, - const sockaddr_any& peer, - const CPacket& hspkt, - CHandShake& w_hs, - int& w_error, - CUDT*& w_acpu); - - int installAcceptHook(const SRTSOCKET lsn, srt_listen_callback_fn* hook, void* opaq); - int installConnectHook(const SRTSOCKET lsn, srt_connect_callback_fn* hook, void* opaq); - - /// Check the status of the UDT socket. - /// @param [in] u the UDT socket ID. - /// @return UDT socket status, or NONEXIST if not found. - SRT_SOCKSTATUS getStatus(const SRTSOCKET u); - - // socket APIs - - int bind(CUDTSocket* u, const sockaddr_any& name); - int bind(CUDTSocket* u, UDPSOCKET udpsock); - int listen(const SRTSOCKET u, int backlog); - SRTSOCKET accept(const SRTSOCKET listen, sockaddr* addr, int* addrlen); - SRTSOCKET accept_bond(const SRTSOCKET listeners[], int lsize, int64_t msTimeOut); - int connect(SRTSOCKET u, const sockaddr* srcname, const sockaddr* tarname, int tarlen); - int connect(const SRTSOCKET u, const sockaddr* name, int namelen, int32_t forced_isn); - int connectIn(CUDTSocket* s, const sockaddr_any& target, int32_t forced_isn); -#if ENABLE_BONDING - int groupConnect(CUDTGroup* g, SRT_SOCKGROUPCONFIG targets[], int arraysize); - int singleMemberConnect(CUDTGroup* g, SRT_SOCKGROUPCONFIG* target); -#endif - int close(const SRTSOCKET u); - int close(CUDTSocket* s); - void getpeername(const SRTSOCKET u, sockaddr* name, int* namelen); - void getsockname(const SRTSOCKET u, sockaddr* name, int* namelen); - int select(UDT::UDSET* readfds, UDT::UDSET* writefds, UDT::UDSET* exceptfds, const timeval* timeout); - int selectEx(const std::vector& fds, - std::vector* readfds, - std::vector* writefds, - std::vector* exceptfds, - int64_t msTimeOut); - int epoll_create(); - int epoll_clear_usocks(int eid); - int epoll_add_usock(const int eid, const SRTSOCKET u, const int* events = NULL); - int epoll_add_usock_INTERNAL(const int eid, CUDTSocket* s, const int* events); - int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events = NULL); - int epoll_remove_usock(const int eid, const SRTSOCKET u); - template - int epoll_remove_entity(const int eid, EntityType* ent); - int epoll_remove_socket_INTERNAL(const int eid, CUDTSocket* ent); -#if ENABLE_BONDING - int epoll_remove_group_INTERNAL(const int eid, CUDTGroup* ent); -#endif - int epoll_remove_ssock(const int eid, const SYSSOCKET s); - int epoll_update_ssock(const int eid, const SYSSOCKET s, const int* events = NULL); - int epoll_uwait(const int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut); - int32_t epoll_set(const int eid, int32_t flags); - int epoll_release(const int eid); - -#if ENABLE_BONDING - // [[using locked(m_GlobControlLock)]] - CUDTGroup& addGroup(SRTSOCKET id, SRT_GROUP_TYPE type) - { - // This only ensures that the element exists. - // If the element was newly added, it will be NULL. - CUDTGroup*& g = m_Groups[id]; - if (!g) - { - // This is a reference to the cell, so it will - // rewrite it into the map. - g = new CUDTGroup(type); - } - - // Now we are sure that g is not NULL, - // and persistence of this object is in the map. - // The reference to the object can be safely returned here. - return *g; - } - - void deleteGroup(CUDTGroup* g); - void deleteGroup_LOCKED(CUDTGroup* g); - - // [[using locked(m_GlobControlLock)]] - CUDTGroup* findPeerGroup_LOCKED(SRTSOCKET peergroup) - { - for (groups_t::iterator i = m_Groups.begin(); i != m_Groups.end(); ++i) - { - if (i->second->peerid() == peergroup) - return i->second; - } - return NULL; - } -#endif - - CEPoll& epoll_ref() { return m_EPoll; } - -private: - /// Generates a new socket ID. This function starts from a randomly - /// generated value (at initialization time) and goes backward with - /// with next calls. The possible values come from the range without - /// the SRTGROUP_MASK bit, and the group bit is set when the ID is - /// generated for groups. It is also internally checked if the - /// newly generated ID isn't already used by an existing socket or group. - /// - /// Socket ID value range. - /// - [0]: reserved for handshake procedure. If the destination Socket ID is 0 - /// (destination Socket ID unknown) the packet will be sent to the listening socket - /// or to a socket that is in the rendezvous connection phase. - /// - [1; 2 ^ 30): single socket ID range. - /// - (2 ^ 30; 2 ^ 31): group socket ID range. Effectively any positive number - /// from [1; 2 ^ 30) with bit 30 set to 1. Bit 31 is zero. - /// The most significant bit 31 (sign bit) is left unused so that checking for a value <= 0 identifies an invalid - /// socket ID. - /// - /// @param group The socket id should be for socket group. - /// @return The new socket ID. - /// @throw CUDTException if after rolling over all possible ID values nothing can be returned - SRTSOCKET generateSocketID(bool group = false); - -private: - typedef std::map sockets_t; // stores all the socket structures - sockets_t m_Sockets; - -#if ENABLE_BONDING - typedef std::map groups_t; - groups_t m_Groups; -#endif - - sync::Mutex m_GlobControlLock; // used to synchronize UDT API - - sync::Mutex m_IDLock; // used to synchronize ID generation - - SRTSOCKET m_SocketIDGenerator; // seed to generate a new unique socket ID - SRTSOCKET m_SocketIDGenerator_init; // Keeps track of the very first one - - std::map > - m_PeerRec; // record sockets from peers to avoid repeated connection request, int64_t = (socker_id << 30) + isn - -private: - friend struct FLookupSocketWithEvent_LOCKED; - - CUDTSocket* locateSocket(SRTSOCKET u, ErrorHandling erh = ERH_RETURN); - // This function does the same as locateSocket, except that: - // - lock on m_GlobControlLock is expected (so that you don't unlock between finding and using) - // - only return NULL if not found - CUDTSocket* locateSocket_LOCKED(SRTSOCKET u); - CUDTSocket* locatePeer(const sockaddr_any& peer, const SRTSOCKET id, int32_t isn); - -#if ENABLE_BONDING - CUDTGroup* locateAcquireGroup(SRTSOCKET u, ErrorHandling erh = ERH_RETURN); - CUDTGroup* acquireSocketsGroup(CUDTSocket* s); - - struct GroupKeeper - { - CUDTGroup* group; - - // This is intended for API functions to lock the group's existence - // for the lifetime of their call. - GroupKeeper(CUDTUnited& glob, SRTSOCKET id, ErrorHandling erh) { group = glob.locateAcquireGroup(id, erh); } - - // This is intended for TSBPD thread that should lock the group's - // existence until it exits. - GroupKeeper(CUDTUnited& glob, CUDTSocket* s) { group = glob.acquireSocketsGroup(s); } - - ~GroupKeeper() - { - if (group) - { - // We have a guarantee that if `group` was set - // as non-NULL here, it is also acquired and will not - // be deleted until this busy flag is set back to false. - sync::ScopedLock cgroup(*group->exp_groupLock()); - group->apiRelease(); - // Only now that the group lock is lifted, can the - // group be now deleted and this pointer potentially dangling - } - } - }; - -#endif - void updateMux(CUDTSocket* s, const sockaddr_any& addr, const UDPSOCKET* = NULL); - bool updateListenerMux(CUDTSocket* s, const CUDTSocket* ls); - - // Utility functions for updateMux - void configureMuxer(CMultiplexer& w_m, const CUDTSocket* s, int af); - uint16_t installMuxer(CUDTSocket* w_s, CMultiplexer& sm); - - /// @brief Checks if channel configuration matches the socket configuration. - /// @param cfgMuxer multiplexer configuration. - /// @param cfgSocket socket configuration. - /// @return tru if configurations match, false otherwise. - static bool channelSettingsMatch(const CSrtMuxerConfig& cfgMuxer, const CSrtConfig& cfgSocket); - -private: - std::map m_mMultiplexer; // UDP multiplexer - sync::Mutex m_MultiplexerLock; - -private: - CCache* m_pCache; // UDT network information cache - -private: - srt::sync::atomic m_bClosing; - sync::Mutex m_GCStopLock; - sync::Condition m_GCStopCond; - - sync::Mutex m_InitLock; - int m_iInstanceCount; // number of startup() called by application - bool m_bGCStatus; // if the GC thread is working (true) - - sync::CThread m_GCThread; - static void* garbageCollect(void*); - - sockets_t m_ClosedSockets; // temporarily store closed sockets -#if ENABLE_BONDING - groups_t m_ClosedGroups; -#endif - - void checkBrokenSockets(); - void removeSocket(const SRTSOCKET u); - - CEPoll m_EPoll; // handling epoll data structures and events - -private: - CUDTUnited(const CUDTUnited&); - CUDTUnited& operator=(const CUDTUnited&); -}; - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/atomic.h b/Vendor/SRT/Includes/atomic.h deleted file mode 100644 index f1394a7da..000000000 --- a/Vendor/SRT/Includes/atomic.h +++ /dev/null @@ -1,311 +0,0 @@ -//---------------------------------------------------------------------------- -// This is free and unencumbered software released into the public domain. -// -// Anyone is free to copy, modify, publish, use, compile, sell, or distribute -// this software, either in source code form or as a compiled binary, for any -// purpose, commercial or non-commercial, and by any means. -// -// In jurisdictions that recognize copyright laws, the author or authors of -// this software dedicate any and all copyright interest in the software to the -// public domain. We make this dedication for the benefit of the public at -// large and to the detriment of our heirs and successors. We intend this -// dedication to be an overt act of relinquishment in perpetuity of all present -// and future rights to this software under copyright law. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// For more information, please refer to -//----------------------------------------------------------------------------- - -// SRT Project information: -// This file was adopted from a Public Domain project from -// https://github.com/mbitsnbites/atomic -// Only namespaces were changed to adopt it for SRT project. - -#ifndef SRT_SYNC_ATOMIC_H_ -#define SRT_SYNC_ATOMIC_H_ - -// Macro for disallowing copying of an object. -#if __cplusplus >= 201103L -#define ATOMIC_DISALLOW_COPY(T) \ - T(const T&) = delete; \ - T& operator=(const T&) = delete; -#else -#define ATOMIC_DISALLOW_COPY(T) \ - T(const T&); \ - T& operator=(const T&); -#endif - -// A portable static assert. -#if __cplusplus >= 201103L -#define ATOMIC_STATIC_ASSERT(condition, message) \ - static_assert((condition), message) -#else -// Based on: http://stackoverflow.com/a/809465/5778708 -#define ATOMIC_STATIC_ASSERT(condition, message) \ - _impl_STATIC_ASSERT_LINE(condition, __LINE__) -#define _impl_PASTE(a, b) a##b -#ifdef __GNUC__ -#define _impl_UNUSED __attribute__((__unused__)) -#else -#define _impl_UNUSED -#endif -#define _impl_STATIC_ASSERT_LINE(condition, line) \ - typedef char _impl_PASTE( \ - STATIC_ASSERT_failed_, \ - line)[(2 * static_cast(!!(condition))) - 1] _impl_UNUSED -#endif - -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - // NOTE: Defined at the top level. -#elif __cplusplus >= 201103L - // NOTE: Prefer to use the c++11 std::atomic. - #define ATOMIC_USE_CPP11_ATOMIC -#elif (defined(__clang__) && defined(__clang_major__) && (__clang_major__ > 5)) \ - || defined(__xlc__) - // NOTE: Clang <6 does not support GCC __atomic_* intrinsics. I am unsure - // about Clang6. Since Clang sets __GNUC__ and __GNUC_MINOR__ of this era - // to <4.5, older Clang will catch the setting below to use the - // POSIX Mutex Implementation. - #define ATOMIC_USE_GCC_INTRINSICS -#elif defined(__GNUC__) \ - && ( (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) ) - // NOTE: The __atomic_* family of intrisics were introduced in GCC-4.7.0. - // NOTE: This follows #if defined(__clang__), because most if, not all, - // versions of Clang define __GNUC__ and __GNUC_MINOR__ but often define - // them to 4.4 or an even earlier version. Most of the newish versions - // of Clang also support GCC Atomic Intrisics even if they set GCC version - // macros to <4.7. - #define ATOMIC_USE_GCC_INTRINSICS -#elif defined(__GNUC__) && !defined(ATOMIC_USE_SRT_SYNC_MUTEX) - // NOTE: GCC compiler built-ins for atomic operations are pure - // compiler extensions prior to GCC-4.7 and were grouped into the - // the __sync_* family of functions. GCC-4.7, both the c++11 and C11 - // standards had been finalized, and GCC updated their built-ins to - // better reflect the new memory model and the new functions grouped - // into the __atomic_* family. Also the memory models were defined - // differently, than in pre 4.7. - // TODO: PORT to the pre GCC-4.7 __sync_* intrinsics. In the meantime use - // the POSIX Mutex Implementation. - #define ATOMIC_USE_SRT_SYNC_MUTEX 1 -#elif defined(_MSC_VER) - #define ATOMIC_USE_MSVC_INTRINSICS - #include "atomic_msvc.h" -#else - #error Unsupported compiler / system. -#endif -// Include any necessary headers for the selected Atomic Implementation. -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - #include "sync.h" -#endif -#if defined(ATOMIC_USE_CPP11_ATOMIC) - #include -#endif - -namespace srt { -namespace sync { -template -class atomic { -public: - ATOMIC_STATIC_ASSERT(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || - sizeof(T) == 8, - "Only types of size 1, 2, 4 or 8 are supported"); - - atomic() - : value_(static_cast(0)) -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - , mutex_() -#endif - { - // No-Op - } - - explicit atomic(const T value) - : value_(value) -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - , mutex_() -#endif - { - // No-Op - } - - ~atomic() - { - // No-Op - } - - /// @brief Performs an atomic increment operation (value + 1). - /// @returns The new value of the atomic object. - T operator++() { -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - ScopedLock lg_(mutex_); - const T t = ++value_; - return t; -#elif defined(ATOMIC_USE_GCC_INTRINSICS) - return __atomic_add_fetch(&value_, 1, __ATOMIC_SEQ_CST); -#elif defined(ATOMIC_USE_MSVC_INTRINSICS) - return msvc::interlocked::increment(&value_); -#elif defined(ATOMIC_USE_CPP11_ATOMIC) - return ++value_; -#else - #error "Implement Me." -#endif - } - - /// @brief Performs an atomic decrement operation (value - 1). - /// @returns The new value of the atomic object. - T operator--() { -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - ScopedLock lg_(mutex_); - const T t = --value_; - return t; -#elif defined(ATOMIC_USE_GCC_INTRINSICS) - return __atomic_sub_fetch(&value_, 1, __ATOMIC_SEQ_CST); -#elif defined(ATOMIC_USE_MSVC_INTRINSICS) - return msvc::interlocked::decrement(&value_); -#elif defined(ATOMIC_USE_CPP11_ATOMIC) - return --value_; -#else - #error "Implement Me." -#endif - } - - /// @brief Performs an atomic compare-and-swap (CAS) operation. - /// - /// The value of the atomic object is only updated to the new value if the - /// old value of the atomic object matches @c expected_val. - /// - /// @param expected_val The expected value of the atomic object. - /// @param new_val The new value to write to the atomic object. - /// @returns True if new_value was written to the atomic object. - bool compare_exchange(const T expected_val, const T new_val) { -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - ScopedLock lg_(mutex_); - bool result = false; - if (expected_val == value_) - { - value_ = new_val; - result = true; - } - return result; -#elif defined(ATOMIC_USE_GCC_INTRINSICS) - T e = expected_val; - return __atomic_compare_exchange_n( - &value_, &e, new_val, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); -#elif defined(ATOMIC_USE_MSVC_INTRINSICS) - const T old_val = - msvc::interlocked::compare_exchange(&value_, new_val, expected_val); - return (old_val == expected_val); -#elif defined(ATOMIC_USE_CPP11_ATOMIC) - T e = expected_val; - return value_.compare_exchange_weak(e, new_val); -#else - #error "Implement Me." -#endif - } - - /// @brief Performs an atomic set operation. - /// - /// The value of the atomic object is unconditionally updated to the new - /// value. - /// - /// @param new_val The new value to write to the atomic object. - void store(const T new_val) { -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - ScopedLock lg_(mutex_); - value_ = new_val; -#elif defined(ATOMIC_USE_GCC_INTRINSICS) - __atomic_store_n(&value_, new_val, __ATOMIC_SEQ_CST); -#elif defined(ATOMIC_USE_MSVC_INTRINSICS) - (void)msvc::interlocked::exchange(&value_, new_val); -#elif defined(ATOMIC_USE_CPP11_ATOMIC) - value_.store(new_val); -#else - #error "Implement Me." -#endif - } - - /// @returns the current value of the atomic object. - /// @note Be careful about how this is used, since any operations on the - /// returned value are inherently non-atomic. - T load() const { -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - ScopedLock lg_(mutex_); - const T t = value_; - return t; -#elif defined(ATOMIC_USE_GCC_INTRINSICS) - return __atomic_load_n(&value_, __ATOMIC_SEQ_CST); -#elif defined(ATOMIC_USE_MSVC_INTRINSICS) - // TODO(m): Is there a better solution for MSVC? - return value_; -#elif defined(ATOMIC_USE_CPP11_ATOMIC) - return value_; -#else - #error "Implement Me." -#endif - } - - /// @brief Performs an atomic exchange operation. - /// - /// The value of the atomic object is unconditionally updated to the new - /// value, and the old value is returned. - /// - /// @param new_val The new value to write to the atomic object. - /// @returns the old value. - T exchange(const T new_val) { -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - ScopedLock lg_(mutex_); - const T t = value_; - value_ = new_val; - return t; -#elif defined(ATOMIC_USE_GCC_INTRINSICS) - return __atomic_exchange_n(&value_, new_val, __ATOMIC_SEQ_CST); -#elif defined(ATOMIC_USE_MSVC_INTRINSICS) - return msvc::interlocked::exchange(&value_, new_val); -#elif defined(ATOMIC_USE_CPP11_ATOMIC) - return value_.exchange(new_val); -#else - #error "Implement Me." -#endif - } - - T operator=(const T new_value) { - store(new_value); - return new_value; - } - - operator T() const { - return load(); - } - -private: -#if defined(ATOMIC_USE_SRT_SYNC_MUTEX) && (ATOMIC_USE_SRT_SYNC_MUTEX == 1) - T value_; - mutable Mutex mutex_; -#elif defined(ATOMIC_USE_GCC_INTRINSICS) - volatile T value_; -#elif defined(ATOMIC_USE_MSVC_INTRINSICS) - volatile T value_; -#elif defined(ATOMIC_USE_CPP11_ATOMIC) - std::atomic value_; -#else - #error "Implement Me. (value_ type)" -#endif - - ATOMIC_DISALLOW_COPY(atomic) -}; - -} // namespace sync -} // namespace srt - -// Undef temporary defines. -#undef ATOMIC_USE_GCC_INTRINSICS -#undef ATOMIC_USE_MSVC_INTRINSICS -#undef ATOMIC_USE_CPP11_ATOMIC - -#endif // ATOMIC_ATOMIC_H_ diff --git a/Vendor/SRT/Includes/atomic_clock.h b/Vendor/SRT/Includes/atomic_clock.h deleted file mode 100644 index e01012313..000000000 --- a/Vendor/SRT/Includes/atomic_clock.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SRT - Secure, Reliable, Transport - * Copyright (c) 2021 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/. - * - */ - -#ifndef INC_SRT_SYNC_ATOMIC_CLOCK_H -#define INC_SRT_SYNC_ATOMIC_CLOCK_H - -#include "sync.h" -#include "atomic.h" - -namespace srt -{ -namespace sync -{ - -template -class AtomicDuration -{ - atomic dur; - typedef typename Clock::duration duration_type; - typedef typename Clock::time_point time_point_type; -public: - - AtomicDuration() ATR_NOEXCEPT : dur(0) {} - - duration_type load() - { - int64_t val = dur.load(); - return duration_type(val); - } - - void store(const duration_type& d) - { - dur.store(d.count()); - } - - AtomicDuration& operator=(const duration_type& s) - { - dur = s.count(); - return *this; - } - - operator duration_type() const - { - return duration_type(dur); - } -}; - -template -class AtomicClock -{ - atomic dur; - typedef typename Clock::duration duration_type; - typedef typename Clock::time_point time_point_type; -public: - - AtomicClock() ATR_NOEXCEPT : dur(0) {} - - time_point_type load() const - { - int64_t val = dur.load(); - return time_point_type(duration_type(val)); - } - - void store(const time_point_type& d) - { - dur.store(uint64_t(d.time_since_epoch().count())); - } - - AtomicClock& operator=(const time_point_type& s) - { - dur = s.time_since_epoch().count(); - return *this; - } - - operator time_point_type() const - { - return time_point_type(duration_type(dur.load())); - } -}; - -} // namespace sync -} // namespace srt - -#endif // INC_SRT_SYNC_ATOMIC_CLOCK_H diff --git a/Vendor/SRT/Includes/atomic_msvc.h b/Vendor/SRT/Includes/atomic_msvc.h deleted file mode 100644 index 9e4df2dbd..000000000 --- a/Vendor/SRT/Includes/atomic_msvc.h +++ /dev/null @@ -1,245 +0,0 @@ -//----------------------------------------------------------------------------- -// This is free and unencumbered software released into the public domain. -// -// Anyone is free to copy, modify, publish, use, compile, sell, or distribute -// this software, either in source code form or as a compiled binary, for any -// purpose, commercial or non-commercial, and by any means. -// -// In jurisdictions that recognize copyright laws, the author or authors of -// this software dedicate any and all copyright interest in the software to the -// public domain. We make this dedication for the benefit of the public at -// large and to the detriment of our heirs and successors. We intend this -// dedication to be an overt act of relinquishment in perpetuity of all present -// and future rights to this software under copyright law. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// For more information, please refer to -//----------------------------------------------------------------------------- - -// SRT Project information: -// This file was adopted from a Public Domain project from -// https://github.com/mbitsnbites/atomic -// Only namespaces were changed to adopt it for SRT project. - -#ifndef SRT_SYNC_ATOMIC_MSVC_H_ -#define SRT_SYNC_ATOMIC_MSVC_H_ - -// Define which functions we need (don't include ). -extern "C" { -short _InterlockedIncrement16(short volatile*); -long _InterlockedIncrement(long volatile*); -__int64 _InterlockedIncrement64(__int64 volatile*); - -short _InterlockedDecrement16(short volatile*); -long _InterlockedDecrement(long volatile*); -__int64 _InterlockedDecrement64(__int64 volatile*); - -char _InterlockedExchange8(char volatile*, char); -short _InterlockedExchange16(short volatile*, short); -long __cdecl _InterlockedExchange(long volatile*, long); -__int64 _InterlockedExchange64(__int64 volatile*, __int64); - -char _InterlockedCompareExchange8(char volatile*, char, char); -short _InterlockedCompareExchange16(short volatile*, short, short); -long __cdecl _InterlockedCompareExchange(long volatile*, long, long); -__int64 _InterlockedCompareExchange64(__int64 volatile*, __int64, __int64); -}; - -// Define which functions we want to use as inline intriniscs. -#pragma intrinsic(_InterlockedIncrement) -#pragma intrinsic(_InterlockedIncrement16) - -#pragma intrinsic(_InterlockedDecrement) -#pragma intrinsic(_InterlockedDecrement16) - -#pragma intrinsic(_InterlockedCompareExchange) -#pragma intrinsic(_InterlockedCompareExchange8) -#pragma intrinsic(_InterlockedCompareExchange16) - -#pragma intrinsic(_InterlockedExchange) -#pragma intrinsic(_InterlockedExchange8) -#pragma intrinsic(_InterlockedExchange16) - -#if defined(_M_X64) -#pragma intrinsic(_InterlockedIncrement64) -#pragma intrinsic(_InterlockedDecrement64) -#pragma intrinsic(_InterlockedCompareExchange64) -#pragma intrinsic(_InterlockedExchange64) -#endif // _M_X64 - -namespace srt { -namespace sync { -namespace msvc { -template -struct interlocked { -}; - -template -struct interlocked { - static inline T increment(T volatile* x) { - // There's no _InterlockedIncrement8(). - char old_val, new_val; - do { - old_val = static_cast(*x); - new_val = old_val + static_cast(1); - } while (_InterlockedCompareExchange8(reinterpret_cast(x), - new_val, - old_val) != old_val); - return static_cast(new_val); - } - - static inline T decrement(T volatile* x) { - // There's no _InterlockedDecrement8(). - char old_val, new_val; - do { - old_val = static_cast(*x); - new_val = old_val - static_cast(1); - } while (_InterlockedCompareExchange8(reinterpret_cast(x), - new_val, - old_val) != old_val); - return static_cast(new_val); - } - - static inline T compare_exchange(T volatile* x, - const T new_val, - const T expected_val) { - return static_cast( - _InterlockedCompareExchange8(reinterpret_cast(x), - static_cast(new_val), - static_cast(expected_val))); - } - - static inline T exchange(T volatile* x, const T new_val) { - return static_cast(_InterlockedExchange8( - reinterpret_cast(x), static_cast(new_val))); - } -}; - -template -struct interlocked { - static inline T increment(T volatile* x) { - return static_cast( - _InterlockedIncrement16(reinterpret_cast(x))); - } - - static inline T decrement(T volatile* x) { - return static_cast( - _InterlockedDecrement16(reinterpret_cast(x))); - } - - static inline T compare_exchange(T volatile* x, - const T new_val, - const T expected_val) { - return static_cast( - _InterlockedCompareExchange16(reinterpret_cast(x), - static_cast(new_val), - static_cast(expected_val))); - } - - static inline T exchange(T volatile* x, const T new_val) { - return static_cast( - _InterlockedExchange16(reinterpret_cast(x), - static_cast(new_val))); - } -}; - -template -struct interlocked { - static inline T increment(T volatile* x) { - return static_cast( - _InterlockedIncrement(reinterpret_cast(x))); - } - - static inline T decrement(T volatile* x) { - return static_cast( - _InterlockedDecrement(reinterpret_cast(x))); - } - - static inline T compare_exchange(T volatile* x, - const T new_val, - const T expected_val) { - return static_cast( - _InterlockedCompareExchange(reinterpret_cast(x), - static_cast(new_val), - static_cast(expected_val))); - } - - static inline T exchange(T volatile* x, const T new_val) { - return static_cast(_InterlockedExchange( - reinterpret_cast(x), static_cast(new_val))); - } -}; - -template -struct interlocked { - static inline T increment(T volatile* x) { -#if defined(_M_X64) - return static_cast( - _InterlockedIncrement64(reinterpret_cast(x))); -#else - // There's no _InterlockedIncrement64() for 32-bit x86. - __int64 old_val, new_val; - do { - old_val = static_cast<__int64>(*x); - new_val = old_val + static_cast<__int64>(1); - } while (_InterlockedCompareExchange64( - reinterpret_cast(x), new_val, old_val) != - old_val); - return static_cast(new_val); -#endif // _M_X64 - } - - static inline T decrement(T volatile* x) { -#if defined(_M_X64) - return static_cast( - _InterlockedDecrement64(reinterpret_cast(x))); -#else - // There's no _InterlockedDecrement64() for 32-bit x86. - __int64 old_val, new_val; - do { - old_val = static_cast<__int64>(*x); - new_val = old_val - static_cast<__int64>(1); - } while (_InterlockedCompareExchange64( - reinterpret_cast(x), new_val, old_val) != - old_val); - return static_cast(new_val); -#endif // _M_X64 - } - - static inline T compare_exchange(T volatile* x, - const T new_val, - const T expected_val) { - return static_cast(_InterlockedCompareExchange64( - reinterpret_cast(x), - static_cast(new_val), - static_cast(expected_val))); - } - - static inline T exchange(T volatile* x, const T new_val) { -#if defined(_M_X64) - return static_cast( - _InterlockedExchange64(reinterpret_cast(x), - static_cast(new_val))); -#else - // There's no _InterlockedExchange64 for 32-bit x86. - __int64 old_val; - do { - old_val = static_cast<__int64>(*x); - } while (_InterlockedCompareExchange64( - reinterpret_cast(x), new_val, old_val) != - old_val); - return static_cast(old_val); -#endif // _M_X64 - } -}; -} // namespace msvc -} // namespace sync -} // namespace srt - -#endif // ATOMIC_ATOMIC_MSVC_H_ diff --git a/Vendor/SRT/Includes/buffer.h b/Vendor/SRT/Includes/buffer.h deleted file mode 100644 index 48bcb4311..000000000 --- a/Vendor/SRT/Includes/buffer.h +++ /dev/null @@ -1,611 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 05/05/2009 -modified by - Haivision Systems Inc. -*****************************************************************************/ - -#ifndef INC_SRT_BUFFER_H -#define INC_SRT_BUFFER_H - -#include "udt.h" -#include "list.h" -#include "queue.h" -#include "tsbpd_time.h" -#include "utilities.h" - -// The notation used for "circular numbers" in comments: -// The "cicrular numbers" are numbers that when increased up to the -// maximum become zero, and similarly, when the zero value is decreased, -// it turns into the maximum value minus one. This wrapping works the -// same for adding and subtracting. Circular numbers cannot be multiplied. - -// Operations done on these numbers are marked with additional % character: -// a %> b : a is later than b -// a ++% (++%a) : shift a by 1 forward -// a +% b : shift a by b -// a == b : equality is same as for just numbers - -namespace srt { - -/// The AvgBufSize class is used to calculate moving average of the buffer (RCV or SND) -class AvgBufSize -{ - typedef sync::steady_clock::time_point time_point; - -public: - AvgBufSize() - : m_dBytesCountMAvg(0.0) - , m_dCountMAvg(0.0) - , m_dTimespanMAvg(0.0) - { - } - -public: - bool isTimeToUpdate(const time_point& now) const; - void update(const time_point& now, int pkts, int bytes, int timespan_ms); - -public: - inline double pkts() const { return m_dCountMAvg; } - inline double timespan_ms() const { return m_dTimespanMAvg; } - inline double bytes() const { return m_dBytesCountMAvg; } - -private: - time_point m_tsLastSamplingTime; - double m_dBytesCountMAvg; - double m_dCountMAvg; - double m_dTimespanMAvg; -}; - -/// The class to estimate source bitrate based on samples submitted to the buffer. -/// Is currently only used by the CSndBuffer. -class CRateEstimator -{ - typedef sync::steady_clock::time_point time_point; - typedef sync::steady_clock::duration duration; -public: - CRateEstimator(); - -public: - uint64_t getInRatePeriod() const { return m_InRatePeriod; } - - /// Retrieve input bitrate in bytes per second - int getInputRate() const { return m_iInRateBps; } - - void setInputRateSmpPeriod(int period); - - /// Update input rate calculation. - /// @param [in] time current time in microseconds - /// @param [in] pkts number of packets newly added to the buffer - /// @param [in] bytes number of payload bytes in those newly added packets - /// - /// @return Current size of the data in the sending list. - void updateInputRate(const time_point& time, int pkts = 0, int bytes = 0); - - void resetInputRateSmpPeriod(bool disable = false) { setInputRateSmpPeriod(disable ? 0 : INPUTRATE_FAST_START_US); } - -private: // Constants - static const uint64_t INPUTRATE_FAST_START_US = 500000; // 500 ms - static const uint64_t INPUTRATE_RUNNING_US = 1000000; // 1000 ms - static const int64_t INPUTRATE_MAX_PACKETS = 2000; // ~ 21 Mbps of 1316 bytes payload - static const int INPUTRATE_INITIAL_BYTESPS = BW_INFINITE; - -private: - int m_iInRatePktsCount; // number of payload bytes added since InRateStartTime - int m_iInRateBytesCount; // number of payload bytes added since InRateStartTime - time_point m_tsInRateStartTime; - uint64_t m_InRatePeriod; // usec - int m_iInRateBps; // Input Rate in Bytes/sec -}; - -class CSndBuffer -{ - typedef sync::steady_clock::time_point time_point; - typedef sync::steady_clock::duration duration; - -public: - // XXX There's currently no way to access the socket ID set for - // whatever the buffer is currently working for. Required to find - // some way to do this, possibly by having a "reverse pointer". - // Currently just "unimplemented". - std::string CONID() const { return ""; } - - /// @brief CSndBuffer constructor. - /// @param size initial number of blocks (each block to store one packet payload). - /// @param maxpld maximum packet payload. - CSndBuffer(int size = 32, int maxpld = 1500); - ~CSndBuffer(); - -public: - /// Insert a user buffer into the sending list. - /// For @a w_mctrl the following fields are used: - /// INPUT: - /// - msgttl: timeout for retransmitting the message, if lost - /// - inorder: request to deliver the message in order of sending - /// - srctime: local time as a base for packet's timestamp (0 if unused) - /// - pktseq: sequence number to be stamped on the packet (-1 if unused) - /// - msgno: message number to be stamped on the packet (-1 if unused) - /// OUTPUT: - /// - srctime: local time stamped on the packet (same as input, if input wasn't 0) - /// - pktseq: sequence number to be stamped on the next packet - /// - msgno: message number stamped on the packet - /// @param [in] data pointer to the user data block. - /// @param [in] len size of the block. - /// @param [inout] w_mctrl Message control data - SRT_ATTR_EXCLUDES(m_BufLock) - void addBuffer(const char* data, int len, SRT_MSGCTRL& w_mctrl); - - /// Read a block of data from file and insert it into the sending list. - /// @param [in] ifs input file stream. - /// @param [in] len size of the block. - /// @return actual size of data added from the file. - SRT_ATTR_EXCLUDES(m_BufLock) - int addBufferFromFile(std::fstream& ifs, int len); - - /// Find data position to pack a DATA packet from the furthest reading point. - /// @param [out] packet the packet to read. - /// @param [out] origintime origin time stamp of the message - /// @param [in] kflags Odd|Even crypto key flag - /// @param [out] seqnoinc the number of packets skipped due to TTL, so that seqno should be incremented. - /// @return Actual length of data read. - SRT_ATTR_EXCLUDES(m_BufLock) - int readData(CPacket& w_packet, time_point& w_origintime, int kflgs, int& w_seqnoinc); - - /// Peek an information on the next original data packet to send. - /// @return origin time stamp of the next packet; epoch start time otherwise. - SRT_ATTR_EXCLUDES(m_BufLock) - time_point peekNextOriginal() const; - - /// Find data position to pack a DATA packet for a retransmission. - /// @param [in] offset offset from the last ACK point (backward sequence number difference) - /// @param [out] packet the packet to read. - /// @param [out] origintime origin time stamp of the message - /// @param [out] msglen length of the message - /// @return Actual length of data read (return 0 if offset too large, -1 if TTL exceeded). - SRT_ATTR_EXCLUDES(m_BufLock) - int readData(const int offset, CPacket& w_packet, time_point& w_origintime, int& w_msglen); - - /// Get the time of the last retransmission (if any) of the DATA packet. - /// @param [in] offset offset from the last ACK point (backward sequence number difference) - /// - /// @return Last time of the last retransmission event for the corresponding DATA packet. - SRT_ATTR_EXCLUDES(m_BufLock) - time_point getPacketRexmitTime(const int offset); - - /// Update the ACK point and may release/unmap/return the user data according to the flag. - /// @param [in] offset number of packets acknowledged. - int32_t getMsgNoAt(const int offset); - - void ackData(int offset); - - /// Read size of data still in the sending list. - /// @return Current size of the data in the sending list. - int getCurrBufSize() const; - - SRT_ATTR_EXCLUDES(m_BufLock) - int dropLateData(int& bytes, int32_t& w_first_msgno, const time_point& too_late_time); - - void updAvgBufSize(const time_point& time); - int getAvgBufSize(int& bytes, int& timespan); - int getCurrBufSize(int& bytes, int& timespan); - - /// @brief Get the buffering delay of the oldest message in the buffer. - /// @return the delay value. - SRT_ATTR_EXCLUDES(m_BufLock) - duration getBufferingDelay(const time_point& tnow) const; - - uint64_t getInRatePeriod() const { return m_rateEstimator.getInRatePeriod(); } - - /// Retrieve input bitrate in bytes per second - int getInputRate() const { return m_rateEstimator.getInputRate(); } - - void resetInputRateSmpPeriod(bool disable = false) { m_rateEstimator.resetInputRateSmpPeriod(disable); } - - const CRateEstimator& getRateEstimator() const { return m_rateEstimator; } - - void setRateEstimator(const CRateEstimator& other) { m_rateEstimator = other; } - -private: - void increase(); - -private: - mutable sync::Mutex m_BufLock; // used to synchronize buffer operation - - struct Block - { - char* m_pcData; // pointer to the data block - int m_iLength; // payload length of the block. - - int32_t m_iMsgNoBitset; // message number - int32_t m_iSeqNo; // sequence number for scheduling - time_point m_tsOriginTime; // block origin time (either provided from above or equals the time a message was submitted for sending. - time_point m_tsRexmitTime; // packet retransmission time - int m_iTTL; // time to live (milliseconds) - - Block* m_pNext; // next block - - int32_t getMsgSeq() - { - // NOTE: this extracts message ID with regard to REXMIT flag. - // This is valid only for message ID that IS GENERATED in this instance, - // not provided by the peer. This can be otherwise sent to the peer - it doesn't matter - // for the peer that it uses LESS bits to represent the message. - return m_iMsgNoBitset & MSGNO_SEQ::mask; - } - - } * m_pBlock, *m_pFirstBlock, *m_pCurrBlock, *m_pLastBlock; - - // m_pBlock: The head pointer - // m_pFirstBlock: The first block - // m_pCurrBlock: The current block - // m_pLastBlock: The last block (if first == last, buffer is empty) - - struct Buffer - { - char* m_pcData; // buffer - int m_iSize; // size - Buffer* m_pNext; // next buffer - } * m_pBuffer; // physical buffer - - int32_t m_iNextMsgNo; // next message number - - int m_iSize; // buffer size (number of packets) - const int m_iBlockLen; // maximum length of a block holding packet payload (excluding packet header). - int m_iCount; // number of used blocks - - int m_iBytesCount; // number of payload bytes in queue - time_point m_tsLastOriginTime; - - AvgBufSize m_mavg; - CRateEstimator m_rateEstimator; - -private: - CSndBuffer(const CSndBuffer&); - CSndBuffer& operator=(const CSndBuffer&); -}; - -//////////////////////////////////////////////////////////////////////////////// - -#if (!ENABLE_NEW_RCVBUFFER) - -class CRcvBuffer -{ - typedef sync::steady_clock::time_point time_point; - typedef sync::steady_clock::duration duration; - -public: - // XXX There's currently no way to access the socket ID set for - // whatever the queue is currently working for. Required to find - // some way to do this, possibly by having a "reverse pointer". - // Currently just "unimplemented". - std::string CONID() const { return ""; } - - static const int DEFAULT_SIZE = 65536; - /// Construct the buffer. - /// @param [in] queue CUnitQueue that actually holds the units (packets) - /// @param [in] bufsize_pkts in units (packets) - CRcvBuffer(CUnitQueue* queue, int bufsize_pkts = DEFAULT_SIZE); - ~CRcvBuffer(); - -public: - /// Write data into the buffer. - /// @param [in] unit pointer to a data unit containing new packet - /// @param [in] offset offset from last ACK point. - /// @return 0 is success, -1 if data is repeated. - int addData(CUnit* unit, int offset); - - /// Read data into a user buffer. - /// @param [in] data pointer to user buffer. - /// @param [in] len length of user buffer. - /// @return size of data read. - int readBuffer(char* data, int len); - - /// Read data directly into file. - /// @param [in] file C++ file stream. - /// @param [in] len expected length of data to write into the file. - /// @return size of data read. - int readBufferToFile(std::fstream& ofs, int len); - - /// Update the ACK point of the buffer. - /// @param [in] len number of units to be acknowledged. - /// @return 1 if a user buffer is fulfilled, otherwise 0. - int ackData(int len); - - /// Query how many buffer space left for data receiving. - /// Actually only acknowledged packets, that are still in the buffer, - /// are considered to take buffer space. - /// - /// @return size of available buffer space (including user buffer) for data receiving. - /// Not counting unacknowledged packets. - int getAvailBufSize() const; - - /// Query how many data has been continuously received (for reading) and ready to play (tsbpdtime < now). - /// @return size of valid (continous) data for reading. - int getRcvDataSize() const; - - /// Query how many data was received and acknowledged. - /// @param [out] bytes bytes - /// @param [out] spantime spantime - /// @return size in pkts of acked data. - int getRcvDataSize(int& bytes, int& spantime); - - /// Query a 1 sec moving average of how many data was received and acknowledged. - /// @param [out] bytes bytes - /// @param [out] spantime spantime - /// @return size in pkts of acked data. - int getRcvAvgDataSize(int& bytes, int& spantime); - - /// Query how many data of the receive buffer is acknowledged. - /// @param [in] now current time in us. - /// @return none. - void updRcvAvgDataSize(const time_point& now); - - /// Query the received average payload size. - /// @return size (bytes) of payload size - unsigned getRcvAvgPayloadSize() const; - - struct ReadingState - { - time_point tsStart; - time_point tsLastAck; - time_point tsEnd; - int iNumAcknowledged; - int iNumUnacknowledged; - }; - - ReadingState debugGetReadingState() const; - - /// Form a string of the current buffer fullness state. - /// number of packets acknowledged, TSBPD readiness, etc. - std::string strFullnessState(const time_point& tsNow) const; - - /// Mark the message to be dropped from the message list. - /// @param [in] msgno message number. - /// @param [in] using_rexmit_flag whether the MSGNO field uses rexmit flag (if not, one more bit is part of the - /// msgno value) - void dropMsg(int32_t msgno, bool using_rexmit_flag); - - /// read a message. - /// @param [out] data buffer to write the message into. - /// @param [in] len size of the buffer. - /// @return actuall size of data read. - int readMsg(char* data, int len); - -#if ENABLE_HEAVY_LOGGING - void readMsgHeavyLogging(int p); -#endif - - /// read a message. - /// @param [out] data buffer to write the message into. - /// @param [in] len size of the buffer. - /// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay - /// @return actuall size of data read. - int readMsg(char* data, int len, SRT_MSGCTRL& w_mctrl, int upto); - - /// Query if data is ready to read (tsbpdtime <= now if TsbPD is active). - /// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay - /// of next packet in recv buffer, ready or not. - /// @param [out] curpktseq Sequence number of the packet if there is one ready to play - /// @return true if ready to play, false otherwise (tsbpdtime may be !0 in - /// both cases). - bool isRcvDataReady(time_point& w_tsbpdtime, int32_t& w_curpktseq, int32_t seqdistance); - -#ifdef SRT_DEBUG_TSBPD_OUTJITTER - void debugTraceJitter(time_point t); -#else - void debugTraceJitter(time_point) {} -#endif /* SRT_DEBUG_TSBPD_OUTJITTER */ - - bool isRcvDataReady(); - bool isRcvDataAvailable() { return m_iLastAckPos != m_iStartPos; } - CPacket* getRcvReadyPacket(int32_t seqdistance); - - /// Set TimeStamp-Based Packet Delivery Rx Mode - /// @param [in] timebase localtime base (uSec) of packet time stamps including buffering delay - /// @param [in] delay aggreed TsbPD delay - void setRcvTsbPdMode(const time_point& timebase, const duration& delay); - - /// Add packet timestamp for drift caclculation and compensation - /// @param [in] timestamp packet time stamp - /// @param [in] tsPktArrival arrival time of the packet used to extract the drift sample. - /// @param [in] rtt RTT sample - bool addRcvTsbPdDriftSample(uint32_t timestamp, const time_point& tsPktArrival, int rtt); - -#ifdef SRT_DEBUG_TSBPD_DRIFT - void printDriftHistogram(int64_t iDrift); - void printDriftOffset(int tsbPdOffset, int tsbPdDriftAvg); -#endif - - /// Get information on the 1st message in queue. - // Parameters (of the 1st packet queue, ready to play or not): - /// @param [out] w_tsbpdtime localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 - /// if none - /// @param [out] w_passack true if 1st ready packet is not yet acknowleged (allowed to be delivered to the app) - /// @param [out] w_skipseqno SRT_SEQNO_NONE or seq number of 1st unacknowledged pkt ready to play preceeded by - /// missing packets. - /// @param base_seq SRT_SEQNO_NONE or desired, ignore seq smaller than base if exist packet ready-to-play - /// and larger than base - /// @retval true 1st packet ready to play (tsbpdtime <= now). Not yet acknowledged if passack == true - /// @retval false IF tsbpdtime = 0: rcv buffer empty; ELSE: - /// IF skipseqno != SRT_SEQNO_NONE, packet ready to play preceeded by missing packets.; - /// IF skipseqno == SRT_SEQNO_NONE, no missing packet but 1st not ready to play. - bool getRcvFirstMsg(time_point& w_tsbpdtime, - bool& w_passack, - int32_t& w_skipseqno, - int32_t& w_curpktseq, - int32_t base_seq = SRT_SEQNO_NONE); - - /// Update the ACK point of the buffer. - /// @param [in] len size of data to be skip & acknowledged. - void skipData(int len); - -#if ENABLE_HEAVY_LOGGING - void reportBufferStats() const; // Heavy logging Debug only -#endif - bool empty() const - { - // This will not always return the intended value, - // that is, it may return false when the buffer really is - // empty - but it will return true then in one of next calls. - // This function will be always called again at some point - // if it returned false, and on true the connection - // is going to be broken - so this behavior is acceptable. - return m_iStartPos == m_iLastAckPos; - } - bool full() const { return m_iStartPos == (m_iLastAckPos + 1) % m_iSize; } - int capacity() const { return m_iSize; } - -private: - /// This gives up unit at index p. The unit is given back to the - /// free unit storage for further assignment for the new incoming - /// data. - size_t freeUnitAt(size_t p) - { - CUnit* u = m_pUnit[p]; - m_pUnit[p] = NULL; - size_t rmbytes = u->m_Packet.getLength(); - m_pUnitQueue->makeUnitFree(u); - return rmbytes; - } - - /// Adjust receive queue to 1st ready to play message (tsbpdtime < now). - /// Parameters (of the 1st packet queue, ready to play or not): - /// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 if - /// none - /// @param base_seq SRT_SEQNO_NONE or desired, ignore seq smaller than base - /// @retval true 1st packet ready to play without discontinuity (no hole) - /// @retval false tsbpdtime = 0: no packet ready to play - bool getRcvReadyMsg(time_point& w_tsbpdtime, int32_t& w_curpktseq, int upto, int base_seq = SRT_SEQNO_NONE); - -public: - /// @brief Get clock drift in microseconds. - int64_t getDrift() const { return m_tsbpd.drift(); } - -public: - int32_t getTopMsgno() const; - - void getInternalTimeBase(time_point& w_tb, bool& w_wrp, duration& w_udrift); - - void applyGroupTime(const time_point& timebase, bool wrapcheck, uint32_t delay, const duration& udrift); - void applyGroupDrift(const time_point& timebase, bool wrapcheck, const duration& udrift); - time_point getPktTsbPdTime(uint32_t timestamp); - int debugGetSize() const; - time_point debugGetDeliveryTime(int offset); - - size_t dropData(int len); - -private: - int extractData(char* data, int len, int p, int q, bool passack); - bool accessMsg(int& w_p, int& w_q, bool& w_passack, int64_t& w_playtime, int upto); - - /// Describes the state of the first N packets - std::string debugTimeState(size_t first_n_pkts) const; - - /// thread safe bytes counter of the Recv & Ack buffer - /// @param [in] pkts acked or removed pkts from rcv buffer (used with acked = true) - /// @param [in] bytes number of bytes added/delete (if negative) to/from rcv buffer. - /// @param [in] acked true when adding new pkt in RcvBuffer; false when acking/removing pkts to/from buffer - void countBytes(int pkts, int bytes, bool acked = false); - -private: - bool scanMsg(int& w_start, int& w_end, bool& w_passack); - - int shift(int basepos, int shift) const { return (basepos + shift) % m_iSize; } - - /// Simplified versions with ++ and --; avoid using division instruction - int shiftFwd(int basepos) const - { - if (++basepos == m_iSize) - return 0; - return basepos; - } - - int shiftBack(int basepos) const - { - if (basepos == 0) - return m_iSize - 1; - return --basepos; - } - -private: - CUnit** m_pUnit; // Array of pointed units collected in the buffer - const int m_iSize; // Size of the internal array of CUnit* items - CUnitQueue* m_pUnitQueue; // the shared unit queue - - int m_iStartPos; // HEAD: first packet available for reading - int m_iLastAckPos; // the last ACKed position (exclusive), follows the last readable - // EMPTY: m_iStartPos = m_iLastAckPos FULL: m_iStartPos = m_iLastAckPos + 1 - int m_iMaxPos; // delta between acked-TAIL and reception-TAIL - - int m_iNotch; // the starting read point of the first unit - // (this is required for stream reading mode; it's - // the position in the first unit in the list - // up to which data are already retrieved; - // in message reading mode it's unused and always 0) - - sync::Mutex m_BytesCountLock; // used to protect counters operations - int m_iBytesCount; // Number of payload bytes in the buffer - int m_iAckedPktsCount; // Number of acknowledged pkts in the buffer - int m_iAckedBytesCount; // Number of acknowledged payload bytes in the buffer - unsigned m_uAvgPayloadSz; // Average payload size for dropped bytes estimation - - CTsbpdTime m_tsbpd; - - AvgBufSize m_mavg; - -private: - CRcvBuffer(); - CRcvBuffer(const CRcvBuffer&); - CRcvBuffer& operator=(const CRcvBuffer&); -}; - -#endif // !ENABLE_NEW_RCVBUFFER - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/buffer_rcv.h b/Vendor/SRT/Includes/buffer_rcv.h deleted file mode 100644 index d628c459f..000000000 --- a/Vendor/SRT/Includes/buffer_rcv.h +++ /dev/null @@ -1,367 +0,0 @@ -/* - * SRT - Secure, Reliable, Transport - * Copyright (c) 2020 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/. - * - */ - -#ifndef INC_SRT_BUFFER_RCV_H -#define INC_SRT_BUFFER_RCV_H - -#if ENABLE_NEW_RCVBUFFER - -#include "buffer.h" // AvgBufSize -#include "common.h" -#include "queue.h" -#include "sync.h" -#include "tsbpd_time.h" - -namespace srt -{ - -/* - * Circular receiver buffer. - * - * |<------------------- m_szSize ---------------------------->| - * | |<------------ m_iMaxPosInc ----------->| | - * | | | | - * +---+---+---+---+---+---+---+---+---+---+---+---+---+ +---+ - * | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 0 |...| 0 | m_pUnit[] - * +---+---+---+---+---+---+---+---+---+---+---+---+---+ +---+ - * | | - * | \__last pkt received - * | - * \___ m_iStartPos: first message to read - * - * m_pUnit[i]->status_: 0: free, 1: good, 2: read, 3: dropped (can be combined with read?) - * - * thread safety: - * start_pos_: CUDT::m_RecvLock - * first_unack_pos_: CUDT::m_AckLock - * max_pos_inc_: none? (modified on add and ack - * first_nonread_pos_: - */ - -class CRcvBufferNew -{ - typedef sync::steady_clock::time_point time_point; - typedef sync::steady_clock::duration duration; - -public: - CRcvBufferNew(int initSeqNo, size_t size, CUnitQueue* unitqueue, bool bMessageAPI); - - ~CRcvBufferNew(); - -public: - /// Insert a unit into the buffer. - /// Similar to CRcvBuffer::addData(CUnit* unit, int offset) - /// - /// @param [in] unit pointer to a data unit containing new packet - /// @param [in] offset offset from last ACK point. - /// - /// @return 0 on success, -1 if packet is already in buffer, -2 if packet is before m_iStartSeqNo. - /// -3 if a packet is offset is ahead the buffer capacity. - // TODO: Previously '-2' also meant 'already acknowledged'. Check usage of this value. - int insert(CUnit* unit); - - /// Drop packets in the receiver buffer from the current position up to the seqno (excluding seqno). - /// @param [in] seqno drop units up to this sequence number - /// @return number of dropped packets. - int dropUpTo(int32_t seqno); - - /// @brief Drop all the packets in the receiver buffer. - /// The starting position and seqno are shifted right after the last packet in the buffer. - /// @return the number of dropped packets. - int dropAll(); - - /// @brief Drop the whole message from the buffer. - /// If message number is 0, then use sequence numbers to locate sequence range to drop [seqnolo, seqnohi]. - /// When one packet of the message is in the range of dropping, the whole message is to be dropped. - /// @param seqnolo sequence number of the first packet in the dropping range. - /// @param seqnohi sequence number of the last packet in the dropping range. - /// @param msgno message number to drop (0 if unknown) - /// @return the number of packets actually dropped. - int dropMessage(int32_t seqnolo, int32_t seqnohi, int32_t msgno); - - /// Read the whole message from one or several packets. - /// - /// @param [in,out] data buffer to write the message into. - /// @param [in] len size of the buffer. - /// @param [in,out] message control data - /// - /// @return actual number of bytes extracted from the buffer. - /// 0 if nothing to read. - /// -1 on failure. - int readMessage(char* data, size_t len, SRT_MSGCTRL* msgctrl = NULL); - - /// Read acknowledged data into a user buffer. - /// @param [in, out] dst pointer to the target user buffer. - /// @param [in] len length of user buffer. - /// @return size of data read. -1 on error. - int readBuffer(char* dst, int len); - - /// Read acknowledged data directly into file. - /// @param [in] ofs C++ file stream. - /// @param [in] len expected length of data to write into the file. - /// @return size of data read. -1 on error. - int readBufferToFile(std::fstream& ofs, int len); - -public: - /// Get the starting position of the buffer as a packet sequence number. - int getStartSeqNo() const { return m_iStartSeqNo; } - - /// Sets the start seqno of the buffer. - /// Must be used with caution and only when the buffer is empty. - void setStartSeqNo(int seqno) { m_iStartSeqNo = seqno; } - - /// Given the sequence number of the first unacknowledged packet - /// tells the size of the buffer available for packets. - /// Effective returns capacity of the buffer minus acknowledged packet still kept in it. - // TODO: Maybe does not need to return minus one slot now to distinguish full and empty buffer. - size_t getAvailSize(int iFirstUnackSeqNo) const - { - // Receiver buffer allows reading unacknowledged packets. - // Therefore if the first packet in the buffer is ahead of the iFirstUnackSeqNo - // then it does not have acknowledged packets and its full capacity is available. - // Otherwise subtract the number of acknowledged but not yet read packets from its capacity. - const int iRBufSeqNo = getStartSeqNo(); - if (CSeqNo::seqcmp(iRBufSeqNo, iFirstUnackSeqNo) >= 0) // iRBufSeqNo >= iFirstUnackSeqNo - { - // Full capacity is available, still don't want to encourage extra packets to come. - // Note: CSeqNo::seqlen(n, n) returns 1. - return capacity() - CSeqNo::seqlen(iFirstUnackSeqNo, iRBufSeqNo) + 1; - } - - // Note: CSeqNo::seqlen(n, n) returns 1. - return capacity() - CSeqNo::seqlen(iRBufSeqNo, iFirstUnackSeqNo) + 1; - } - - /// @brief Checks if the buffer has packets available for reading regardless of the TSBPD. - /// @return true if there are packets available for reading, false otherwise. - bool hasAvailablePackets() const; - - /// Query how many data has been continuously received (for reading) and available for reading out - /// regardless of the TSBPD. - /// TODO: Rename to countAvailablePackets(). - /// @return size of valid (continous) data for reading. - int getRcvDataSize() const; - - /// Get the number of packets, bytes and buffer timespan. - /// Differs from getRcvDataSize() that it counts all packets in the buffer, not only continious. - int getRcvDataSize(int& bytes, int& timespan) const; - - struct PacketInfo - { - int seqno; - bool seq_gap; //< true if there are missing packets in the buffer, preceding current packet - time_point tsbpd_time; - }; - - /// Get information on the 1st message in queue. - /// Similar to CRcvBuffer::getRcvFirstMsg - /// Parameters (of the 1st packet queue, ready to play or not): - /// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 if - /// none - /// @param [out] passack true if 1st ready packet is not yet acknowleged (allowed to be delivered to the app) - /// @param [out] skipseqno -1 or seq number of 1st unacknowledged pkt ready to play preceeded by missing packets. - /// @retval true 1st packet ready to play (tsbpdtime <= now). Not yet acknowledged if passack == true - /// @retval false IF tsbpdtime = 0: rcv buffer empty; ELSE: - /// IF skipseqno != -1, packet ready to play preceeded by missing packets.; - /// IF skipseqno == -1, no missing packet but 1st not ready to play. - PacketInfo getFirstValidPacketInfo() const; - - PacketInfo getFirstReadablePacketInfo(time_point time_now) const; - - /// Get information on packets available to be read. - /// @returns a pair of sequence numbers (first available; first unavailable). - /// - /// @note CSeqNo::seqoff(first, second) is 0 if nothing to read. - std::pair getAvailablePacketsRange() const; - - size_t countReadable() const; - - bool empty() const - { - return (m_iMaxPosInc == 0); - } - - /// Return buffer capacity. - /// One slot had to be empty in order to tell the difference between "empty buffer" and "full buffer". - /// E.g. m_iFirstNonreadPos would again point to m_iStartPos if m_szSize entries are added continiously. - /// TODO: Old receiver buffer capacity returns the actual size. Check for conflicts. - size_t capacity() const - { - return m_szSize - 1; - } - - int64_t getDrift() const { return m_tsbpd.drift(); } - - // TODO: make thread safe? - int debugGetSize() const - { - return getRcvDataSize(); - } - - /// Zero time to include all available packets. - /// TODO: Rename to 'canRead`. - bool isRcvDataReady(time_point time_now = time_point()) const; - - int getRcvAvgDataSize(int& bytes, int& timespan); - void updRcvAvgDataSize(const time_point& now); - - unsigned getRcvAvgPayloadSize() const { return m_uAvgPayloadSz; } - - void getInternalTimeBase(time_point& w_timebase, bool& w_wrp, duration& w_udrift) - { - return m_tsbpd.getInternalTimeBase(w_timebase, w_wrp, w_udrift); - } - -public: // Used for testing - /// Peek unit in position of seqno - const CUnit* peek(int32_t seqno); - -private: - inline int incPos(int pos, int inc = 1) const { return (pos + inc) % m_szSize; } - inline int decPos(int pos) const { return (pos - 1) >= 0 ? (pos - 1) : int(m_szSize - 1); } - inline int offPos(int pos1, int pos2) const { return (pos2 >= pos1) ? (pos2 - pos1) : int(m_szSize + pos2 - pos1); } - -private: - void countBytes(int pkts, int bytes); - void updateNonreadPos(); - void releaseUnitInPos(int pos); - - /// @brief Drop a unit from the buffer. - /// @param pos position in the m_entries of the unit to drop. - /// @return false if nothing to drop, true if the unit was dropped successfully. - bool dropUnitInPos(int pos); - - /// Release entries following the current buffer position if they were already - /// read out of order (EntryState_Read) or dropped (EntryState_Drop). - void releaseNextFillerEntries(); - - bool hasReadableInorderPkts() const { return (m_iFirstNonreadPos != m_iStartPos); } - - /// Find position of the last packet of the message. - int findLastMessagePkt(); - - /// Scan for availability of out of order packets. - void onInsertNotInOrderPacket(int insertpos); - // Check if m_iFirstReadableOutOfOrder is still readable. - bool checkFirstReadableOutOfOrder(); - void updateFirstReadableOutOfOrder(); - int scanNotInOrderMessageRight(int startPos, int msgNo) const; - int scanNotInOrderMessageLeft(int startPos, int msgNo) const; - - typedef bool copy_to_dst_f(char* data, int len, int dst_offset, void* arg); - - /// Read acknowledged data directly into file. - /// @param [in] ofs C++ file stream. - /// @param [in] len expected length of data to write into the file. - /// @return size of data read. - int readBufferTo(int len, copy_to_dst_f funcCopyToDst, void* arg); - - /// @brief Estimate timespan of the stored packets (acknowledged and unacknowledged). - /// @return timespan in milliseconds - int getTimespan_ms() const; - -private: - // TODO: Call makeUnitGood upon assignment, and makeUnitFree upon clearing. - // TODO: CUnitPtr is not in use at the moment, but may be a smart pointer. - // class CUnitPtr - // { - // public: - // void operator=(CUnit* pUnit) - // { - // if (m_pUnit != NULL) - // { - // // m_pUnitQueue->makeUnitFree(m_entries[i].pUnit); - // } - // m_pUnit = pUnit; - // } - // private: - // CUnit* m_pUnit; - // }; - - enum EntryStatus - { - EntryState_Empty, //< No CUnit record. - EntryState_Avail, //< Entry is available for reading. - EntryState_Read, //< Entry has already been read (out of order). - EntryState_Drop //< Entry has been dropped. - }; - struct Entry - { - Entry() - : pUnit(NULL) - , status(EntryState_Empty) - {} - - CUnit* pUnit; - EntryStatus status; - }; - - //static Entry emptyEntry() { return Entry { NULL, EntryState_Empty }; } - - FixedArray m_entries; - - const size_t m_szSize; // size of the array of units (buffer) - CUnitQueue* m_pUnitQueue; // the shared unit queue - - int m_iStartSeqNo; - int m_iStartPos; // the head position for I/O (inclusive) - int m_iFirstNonreadPos; // First position that can't be read (<= m_iLastAckPos) - int m_iMaxPosInc; // the furthest data position - int m_iNotch; // the starting read point of the first unit - - size_t m_numOutOfOrderPackets; // The number of stored packets with "inorder" flag set to false - int m_iFirstReadableOutOfOrder; // In case of out ouf order packet, points to a position of the first such packet to - // read - bool m_bPeerRexmitFlag; // Needed to read message number correctly - const bool m_bMessageAPI; // Operation mode flag: message or stream. - -public: // TSBPD public functions - /// Set TimeStamp-Based Packet Delivery Rx Mode - /// @param [in] timebase localtime base (uSec) of packet time stamps including buffering delay - /// @param [in] wrap Is in wrapping period - /// @param [in] delay aggreed TsbPD delay - /// - /// @return 0 - void setTsbPdMode(const time_point& timebase, bool wrap, duration delay); - - void setPeerRexmitFlag(bool flag) { m_bPeerRexmitFlag = flag; } - - void applyGroupTime(const time_point& timebase, bool wrp, uint32_t delay, const duration& udrift); - - void applyGroupDrift(const time_point& timebase, bool wrp, const duration& udrift); - - bool addRcvTsbPdDriftSample(uint32_t usTimestamp, const time_point& tsPktArrival, int usRTTSample); - - time_point getPktTsbPdTime(uint32_t usPktTimestamp) const; - - time_point getTsbPdTimeBase(uint32_t usPktTimestamp) const; - void updateTsbPdTimeBase(uint32_t usPktTimestamp); - - /// Form a string of the current buffer fullness state. - /// number of packets acknowledged, TSBPD readiness, etc. - std::string strFullnessState(int iFirstUnackSeqNo, const time_point& tsNow) const; - -private: - CTsbpdTime m_tsbpd; - -private: // Statistics - AvgBufSize m_mavg; - - // TODO: m_BytesCountLock is probably not needed as the buffer has to be protected from simultaneous access. - mutable sync::Mutex m_BytesCountLock; // used to protect counters operations - int m_iBytesCount; // Number of payload bytes in the buffer - int m_iPktsCount; // Number of payload bytes in the buffer - unsigned m_uAvgPayloadSz; // Average payload size for dropped bytes estimation -}; - -} // namespace srt - -#endif // ENABLE_NEW_RCVBUFFER -#endif // INC_SRT_BUFFER_RCV_H diff --git a/Vendor/SRT/Includes/cache.h b/Vendor/SRT/Includes/cache.h deleted file mode 100644 index 0dd57ba01..000000000 --- a/Vendor/SRT/Includes/cache.h +++ /dev/null @@ -1,273 +0,0 @@ -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/27/2011 -*****************************************************************************/ - -#ifndef INC_SRT_CACHE_H -#define INC_SRT_CACHE_H - -#include -#include - -#include "sync.h" -#include "netinet_any.h" -#include "udt.h" - -namespace srt -{ - -class CCacheItem -{ -public: - virtual ~CCacheItem() {} - -public: - virtual CCacheItem& operator=(const CCacheItem&) = 0; - - // The "==" operator SHOULD only compare key values. - virtual bool operator==(const CCacheItem&) = 0; - - /// get a deep copy clone of the current item - /// @return Pointer to the new item, or NULL if failed. - - virtual CCacheItem* clone() = 0; - - /// get a random key value between 0 and MAX_INT to be used for the hash in cache - /// @return A random hash key. - - virtual int getKey() = 0; - - // If there is any shared resources between the cache item and its clone, - // the shared resource should be released by this function. - virtual void release() {} -}; - -template class CCache -{ -public: - CCache(int size = 1024): - m_iMaxSize(size), - m_iHashSize(size * 3), - m_iCurrSize(0) - { - m_vHashPtr.resize(m_iHashSize); - // Exception: -> CUDTUnited ctor - srt::sync::setupMutex(m_Lock, "Cache"); - } - - ~CCache() - { - clear(); - } - -public: - /// find the matching item in the cache. - /// @param [in,out] data storage for the retrieved item; initially it must carry the key information - /// @return 0 if found a match, otherwise -1. - - int lookup(T* data) - { - srt::sync::ScopedLock cacheguard(m_Lock); - - int key = data->getKey(); - if (key < 0) - return -1; - if (key >= m_iMaxSize) - key %= m_iHashSize; - - const ItemPtrList& item_list = m_vHashPtr[key]; - for (typename ItemPtrList::const_iterator i = item_list.begin(); i != item_list.end(); ++ i) - { - if (*data == ***i) - { - // copy the cached info - *data = ***i; - return 0; - } - } - - return -1; - } - - /// update an item in the cache, or insert one if it doesn't exist; oldest item may be removed - /// @param [in] data the new item to updated/inserted to the cache - /// @return 0 if success, otherwise -1. - - int update(T* data) - { - srt::sync::ScopedLock cacheguard(m_Lock); - - int key = data->getKey(); - if (key < 0) - return -1; - if (key >= m_iMaxSize) - key %= m_iHashSize; - - T* curr = NULL; - - ItemPtrList& item_list = m_vHashPtr[key]; - for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i) - { - if (*data == ***i) - { - // update the existing entry with the new value - ***i = *data; - curr = **i; - - // remove the current entry - m_StorageList.erase(*i); - item_list.erase(i); - - // re-insert to the front - m_StorageList.push_front(curr); - item_list.push_front(m_StorageList.begin()); - - return 0; - } - } - - // create new entry and insert to front - curr = data->clone(); - m_StorageList.push_front(curr); - item_list.push_front(m_StorageList.begin()); - - ++ m_iCurrSize; - if (m_iCurrSize >= m_iMaxSize) - { - // Cache overflow, remove oldest entry. - T* last_data = m_StorageList.back(); - int last_key = last_data->getKey() % m_iHashSize; - - ItemPtrList& last_item_list = m_vHashPtr[last_key]; - for (typename ItemPtrList::iterator i = last_item_list.begin(); i != last_item_list.end(); ++ i) - { - if (*last_data == ***i) - { - last_item_list.erase(i); - break; - } - } - - last_data->release(); - delete last_data; - m_StorageList.pop_back(); - -- m_iCurrSize; - } - - return 0; - } - - /// Specify the cache size (i.e., max number of items). - /// @param [in] size max cache size. - - void setSizeLimit(int size) - { - m_iMaxSize = size; - m_iHashSize = size * 3; - m_vHashPtr.resize(m_iHashSize); - } - - /// Clear all entries in the cache, restore to initialization state. - - void clear() - { - for (typename std::list::iterator i = m_StorageList.begin(); i != m_StorageList.end(); ++ i) - { - (*i)->release(); - delete *i; - } - m_StorageList.clear(); - for (typename std::vector::iterator i = m_vHashPtr.begin(); i != m_vHashPtr.end(); ++ i) - i->clear(); - m_iCurrSize = 0; - } - -private: - std::list m_StorageList; - typedef typename std::list::iterator ItemPtr; - typedef std::list ItemPtrList; - std::vector m_vHashPtr; - - int m_iMaxSize; - int m_iHashSize; - int m_iCurrSize; - - srt::sync::Mutex m_Lock; - -private: - CCache(const CCache&); - CCache& operator=(const CCache&); -}; - - -class CInfoBlock -{ -public: - uint32_t m_piIP[4]; // IP address, machine read only, not human readable format. - int m_iIPversion; // Address family: AF_INET or AF_INET6. - uint64_t m_ullTimeStamp; // Last update time. - int m_iSRTT; // Smoothed RTT. - int m_iBandwidth; // Estimated link bandwidth. - int m_iLossRate; // Average loss rate. - int m_iReorderDistance; // Packet reordering distance. - double m_dInterval; // Inter-packet time (Congestion Control). - double m_dCWnd; // Congestion window size (Congestion Control). - -public: - CInfoBlock() {} // NOTE: leaves uninitialized - CInfoBlock& copyFrom(const CInfoBlock& obj); - CInfoBlock(const CInfoBlock& src) { copyFrom(src); } - CInfoBlock& operator=(const CInfoBlock& src) { return copyFrom(src); } - bool operator==(const CInfoBlock& obj); - CInfoBlock* clone(); - int getKey(); - void release() {} - -public: - - /// convert sockaddr structure to an integer array - /// @param [in] addr network address - /// @param [in] ver IP version - /// @param [out] ip the result machine readable IP address in integer array - - static void convert(const sockaddr_any& addr, uint32_t ip[4]); -}; - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/channel.h b/Vendor/SRT/Includes/channel.h deleted file mode 100644 index 0255102fe..000000000 --- a/Vendor/SRT/Includes/channel.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/27/2011 -modified by - Haivision Systems Inc. -*****************************************************************************/ - -#ifndef INC_SRT_CHANNEL_H -#define INC_SRT_CHANNEL_H - -#include "platform_sys.h" -#include "udt.h" -#include "packet.h" -#include "socketconfig.h" -#include "netinet_any.h" - -namespace srt -{ - -class CChannel -{ - void createSocket(int family); - -public: - // XXX There's currently no way to access the socket ID set for - // whatever the channel is currently working for. Required to find - // some way to do this, possibly by having a "reverse pointer". - // Currently just "unimplemented". - std::string CONID() const { return ""; } - - CChannel(); - ~CChannel(); - - /// Open a UDP channel. - /// @param [in] addr The local address that UDP will use. - - void open(const sockaddr_any& addr); - - void open(int family); - - /// Open a UDP channel based on an existing UDP socket. - /// @param [in] udpsock UDP socket descriptor. - - void attach(UDPSOCKET udpsock, const sockaddr_any& adr); - - /// Disconnect and close the UDP entity. - - void close() const; - - /// Get the UDP sending buffer size. - /// @return Current UDP sending buffer size. - - int getSndBufSize(); - - /// Get the UDP receiving buffer size. - /// @return Current UDP receiving buffer size. - - int getRcvBufSize(); - - /// Query the socket address that the channel is using. - /// @param [out] addr pointer to store the returned socket address. - - void getSockAddr(sockaddr_any& addr) const; - - /// Query the peer side socket address that the channel is connect to. - /// @param [out] addr pointer to store the returned socket address. - - void getPeerAddr(sockaddr_any& addr) const; - - /// Send a packet to the given address. - /// @param [in] addr pointer to the destination address. - /// @param [in] packet reference to a CPacket entity. - /// @return Actual size of data sent. - - int sendto(const sockaddr_any& addr, srt::CPacket& packet) const; - - /// Receive a packet from the channel and record the source address. - /// @param [in] addr pointer to the source address. - /// @param [in] packet reference to a CPacket entity. - /// @return Actual size of data received. - - EReadStatus recvfrom(sockaddr_any& addr, srt::CPacket& packet) const; - - void setConfig(const CSrtMuxerConfig& config); - - /// Get the IP TTL. - /// @param [in] ttl IP Time To Live. - /// @return TTL. - - int getIpTTL() const; - - /// Get the IP Type of Service. - /// @return ToS. - - int getIpToS() const; - -#ifdef SRT_ENABLE_BINDTODEVICE - bool getBind(char* dst, size_t len); -#endif - - int ioctlQuery(int type) const; - int sockoptQuery(int level, int option) const; - - const sockaddr* bindAddress() { return m_BindAddr.get(); } - const sockaddr_any& bindAddressAny() { return m_BindAddr; } - -private: - void setUDPSockOpt(); - -private: - UDPSOCKET m_iSocket; // socket descriptor - - // Mutable because when querying original settings - // this comprises the cache for extracted values, - // although the object itself isn't considered modified. - mutable CSrtMuxerConfig m_mcfg; // Note: ReuseAddr is unused and ineffective. - sockaddr_any m_BindAddr; -}; - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/common.h b/Vendor/SRT/Includes/common.h deleted file mode 100644 index 227a91861..000000000 --- a/Vendor/SRT/Includes/common.h +++ /dev/null @@ -1,1421 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 08/01/2009 -modified by - Haivision Systems Inc. -*****************************************************************************/ - -#ifndef INC_SRT_COMMON_H -#define INC_SRT_COMMON_H - -#define _CRT_SECURE_NO_WARNINGS 1 // silences windows complaints for sscanf -#include -#include -#include -#ifndef _WIN32 - #include - #include -#else - // #include - //#include -#endif - -#include "srt.h" -#include "utilities.h" -#include "sync.h" -#include "netinet_any.h" -#include "packetfilter_api.h" - -// System-independent errno -#ifndef _WIN32 - #define NET_ERROR errno -#else - #define NET_ERROR WSAGetLastError() -#endif - -#ifdef _DEBUG -#include -#define SRT_ASSERT(cond) assert(cond) -#else -#define SRT_ASSERT(cond) -#endif - -#if HAVE_FULL_CXX11 -#define SRT_STATIC_ASSERT(cond, msg) static_assert(cond, msg) -#else -#define SRT_STATIC_ASSERT(cond, msg) -#endif - -#include - -namespace srt_logging -{ - std::string SockStatusStr(SRT_SOCKSTATUS s); -#if ENABLE_BONDING - std::string MemberStatusStr(SRT_MEMBERSTATUS s); -#endif -} - -namespace srt -{ - -// Class CUDTException exposed for C++ API. -// This is actually useless, unless you'd use a DIRECT C++ API, -// however there's no such API so far. The current C++ API for UDT/SRT -// is predicted to NEVER LET ANY EXCEPTION out of implementation, -// so it's useless to catch this exception anyway. - -class CUDTException: public std::exception -{ -public: - - CUDTException(CodeMajor major = MJ_SUCCESS, CodeMinor minor = MN_NONE, int err = -1); - virtual ~CUDTException() ATR_NOTHROW {} - - /// Get the description of the exception. - /// @return Text message for the exception description. - const char* getErrorMessage() const ATR_NOTHROW; - - virtual const char* what() const ATR_NOTHROW ATR_OVERRIDE - { - return getErrorMessage(); - } - - std::string getErrorString() const; - - /// Get the system errno for the exception. - /// @return errno. - int getErrorCode() const; - - /// Get the system network errno for the exception. - /// @return errno. - int getErrno() const; - - /// Clear the error code. - void clear(); - -private: - CodeMajor m_iMajor; // major exception categories - CodeMinor m_iMinor; // for specific error reasons - int m_iErrno; // errno returned by the system if there is any - mutable std::string m_strMsg; // text error message (cache) - - std::string m_strAPI; // the name of UDT function that returns the error - std::string m_strDebug; // debug information, set to the original place that causes the error - -public: // Legacy Error Code - - static const int EUNKNOWN = SRT_EUNKNOWN; - static const int SUCCESS = SRT_SUCCESS; - static const int ECONNSETUP = SRT_ECONNSETUP; - static const int ENOSERVER = SRT_ENOSERVER; - static const int ECONNREJ = SRT_ECONNREJ; - static const int ESOCKFAIL = SRT_ESOCKFAIL; - static const int ESECFAIL = SRT_ESECFAIL; - static const int ECONNFAIL = SRT_ECONNFAIL; - static const int ECONNLOST = SRT_ECONNLOST; - static const int ENOCONN = SRT_ENOCONN; - static const int ERESOURCE = SRT_ERESOURCE; - static const int ETHREAD = SRT_ETHREAD; - static const int ENOBUF = SRT_ENOBUF; - static const int EFILE = SRT_EFILE; - static const int EINVRDOFF = SRT_EINVRDOFF; - static const int ERDPERM = SRT_ERDPERM; - static const int EINVWROFF = SRT_EINVWROFF; - static const int EWRPERM = SRT_EWRPERM; - static const int EINVOP = SRT_EINVOP; - static const int EBOUNDSOCK = SRT_EBOUNDSOCK; - static const int ECONNSOCK = SRT_ECONNSOCK; - static const int EINVPARAM = SRT_EINVPARAM; - static const int EINVSOCK = SRT_EINVSOCK; - static const int EUNBOUNDSOCK = SRT_EUNBOUNDSOCK; - static const int ESTREAMILL = SRT_EINVALMSGAPI; - static const int EDGRAMILL = SRT_EINVALBUFFERAPI; - static const int ENOLISTEN = SRT_ENOLISTEN; - static const int ERDVNOSERV = SRT_ERDVNOSERV; - static const int ERDVUNBOUND = SRT_ERDVUNBOUND; - static const int EINVALMSGAPI = SRT_EINVALMSGAPI; - static const int EINVALBUFFERAPI = SRT_EINVALBUFFERAPI; - static const int EDUPLISTEN = SRT_EDUPLISTEN; - static const int ELARGEMSG = SRT_ELARGEMSG; - static const int EINVPOLLID = SRT_EINVPOLLID; - static const int EASYNCFAIL = SRT_EASYNCFAIL; - static const int EASYNCSND = SRT_EASYNCSND; - static const int EASYNCRCV = SRT_EASYNCRCV; - static const int ETIMEOUT = SRT_ETIMEOUT; - static const int ECONGEST = SRT_ECONGEST; - static const int EPEERERR = SRT_EPEERERR; -}; - - - -enum UDTSockType -{ - UDT_UNDEFINED = 0, // initial trap representation - UDT_STREAM = 1, - UDT_DGRAM -}; - - -/// The message types used by UDT protocol. This is a part of UDT -/// protocol and should never be changed. -enum UDTMessageType -{ - UMSG_HANDSHAKE = 0, //< Connection Handshake. Control: see @a CHandShake. - UMSG_KEEPALIVE = 1, //< Keep-alive. - UMSG_ACK = 2, //< Acknowledgement. Control: past-the-end sequence number up to which packets have been received. - UMSG_LOSSREPORT = 3, //< Negative Acknowledgement (NAK). Control: Loss list. - UMSG_CGWARNING = 4, //< Congestion warning. - UMSG_SHUTDOWN = 5, //< Shutdown. - UMSG_ACKACK = 6, //< Acknowledgement of Acknowledgement. Add info: The ACK sequence number - UMSG_DROPREQ = 7, //< Message Drop Request. Add info: Message ID. Control Info: (first, last) number of the message. - UMSG_PEERERROR = 8, //< Signal from the Peer side. Add info: Error code. - // ... add extra code types here - UMSG_END_OF_TYPES, - UMSG_EXT = 0x7FFF //< For the use of user-defined control packets. -}; - -// This side's role is: INITIATOR prepares the environment first, and sends -// appropriate information to the peer. The peer must be RESPONDER and be ready -// to receive it. It's important for the encryption: the INITIATOR side generates -// the KM, and sends it to RESPONDER. RESPONDER awaits KM received from the -// INITIATOR. Note that in bidirectional mode - that is always with HSv5 - the -// INITIATOR creates both sending and receiving contexts, then sends the key to -// RESPONDER, which creates both sending and receiving contexts, using the same -// key received from INITIATOR. -// -// The method of selection: -// -// In HSv4, it's always data sender (the party that sets SRTO_SENDER flag on the -// socket) INITIATOR, and receiver - RESPONDER. The HSREQ and KMREQ are done -// AFTER the UDT connection is done using UMSG_EXT extension messages. As this -// is unidirectional, the INITIATOR prepares the sending context only, the -// RESPONDER - receiving context only. -// -// In HSv5, for caller-listener configuration, it's simple: caller is INITIATOR, -// listener is RESPONDER. In case of rendezvous the parties are equivalent, -// so the role is resolved by "cookie contest". Rendezvous sockets both know -// each other's cookie generated during the URQ_WAVEAHAND handshake phase. -// The cookies are simply compared as integer numbers; the party which's cookie -// is a greater number becomes an INITIATOR, and the other party becomes a -// RESPONDER. -// -// The case of a draw - that both occasionally have baked identical cookies - -// is treated as an extremely rare and virtually impossible case, so this -// results in connection rejected. -enum HandshakeSide -{ - HSD_DRAW, - HSD_INITIATOR, //< Side that initiates HSREQ/KMREQ. HSv4: data sender, HSv5: connecting socket or winner rendezvous socket - HSD_RESPONDER //< Side that expects HSREQ/KMREQ from the peer. HSv4: data receiver, HSv5: accepted socket or loser rendezvous socket -}; - -// For debug -std::string MessageTypeStr(UDTMessageType mt, uint32_t extt = 0); - -//////////////////////////////////////////////////////////////////////////////// - -// Commonly used by various reading facilities -enum EReadStatus -{ - RST_OK = 0, //< A new portion of data has been received - RST_AGAIN, //< Nothing has been received, try again - RST_ERROR = -1 //< Irrecoverable error, please close descriptor and stop reading. -}; - -enum EConnectStatus -{ - CONN_ACCEPT = 0, //< Received final handshake that confirms connection established - CONN_REJECT = -1, //< Error during processing handshake. - CONN_CONTINUE = 1, //< induction->conclusion phase - CONN_RENDEZVOUS = 2, //< pass to a separate rendezvous processing (HSv5 only) - CONN_CONFUSED = 3, //< listener thinks it's connected, but caller missed conclusion - CONN_RUNNING = 10, //< no connection in progress, already connected - CONN_AGAIN = -2 //< No data was read, don't change any state. -}; - -enum EConnectMethod -{ - COM_ASYNCHRO, - COM_SYNCHRO -}; - -std::string ConnectStatusStr(EConnectStatus est); - - -const int64_t BW_INFINITE = 1000000000/8; //Infinite=> 1 Gbps - - -enum ETransmissionEvent -{ - TEV_INIT, // --> After creation, and after any parameters were updated. - TEV_ACK, // --> When handling UMSG_ACK - older CCC:onAck() - TEV_ACKACK, // --> UDT does only RTT sync, can be read from CUDT::SRTT(). - TEV_LOSSREPORT, // --> When handling UMSG_LOSSREPORT - older CCC::onLoss() - TEV_CHECKTIMER, // --> See TEV_CHT_REXMIT - TEV_SEND, // --> When the packet is scheduled for sending - older CCC::onPktSent - TEV_RECEIVE, // --> When a data packet was received - older CCC::onPktReceived - TEV_CUSTOM, // --> probably dead call - older CCC::processCustomMsg - TEV_SYNC, // --> Backup group. When rate estimation is derived from an active member, and update is needed. - - TEV_E_SIZE -}; - -std::string TransmissionEventStr(ETransmissionEvent ev); - -// Special parameter for TEV_CHECKTIMER -enum ECheckTimerStage -{ - TEV_CHT_INIT, // --> UDT: just update parameters, don't call any CCC::* - TEV_CHT_FASTREXMIT, // --> not available on UDT - TEV_CHT_REXMIT // --> CCC::onTimeout() in UDT -}; - -enum EInitEvent -{ - TEV_INIT_RESET = 0, - TEV_INIT_INPUTBW, - TEV_INIT_OHEADBW -}; - -class CPacket; - -// XXX Use some more standard less hand-crafted solution, if possible -// XXX Consider creating a mapping between TEV_* values and associated types, -// so that the type is compiler-enforced when calling updateCC() and when -// connecting signals to slots. -struct EventVariant -{ - enum Type {UNDEFINED, PACKET, ARRAY, ACK, STAGE, INIT} type; - union U - { - const srt::CPacket* packet; - int32_t ack; - struct - { - const int32_t* ptr; - size_t len; - } array; - ECheckTimerStage stage; - EInitEvent init; - } u; - - - template - struct VariantFor; - - - // Note: UNDEFINED and ARRAY don't have assignment operator. - // For ARRAY you'll use 'set' function. For UNDEFINED there's nothing. - - explicit EventVariant(const srt::CPacket* arg) - { - type = PACKET; - u.packet = arg; - } - - explicit EventVariant(int32_t arg) - { - type = ACK; - u.ack = arg; - } - - explicit EventVariant(ECheckTimerStage arg) - { - type = STAGE; - u.stage = arg; - } - - explicit EventVariant(EInitEvent arg) - { - type = INIT; - u.init = arg; - } - - const int32_t* get_ptr() const - { - return u.array.ptr; - } - - size_t get_len() const - { - return u.array.len; - } - - void set(const int32_t* ptr, size_t len) - { - type = ARRAY; - u.array.ptr = ptr; - u.array.len = len; - } - - EventVariant(const int32_t* ptr, size_t len) - { - set(ptr, len); - } - - template - typename VariantFor::type get() const - { - return u.*(VariantFor::field()); - } -}; - -/* - Maybe later. - This had to be a solution for automatic extraction of the - type hidden in particular EventArg for particular event so - that it's not runtime-mistaken. - - In order that this make sense there would be required an array - indexed by event id (just like a slot array m_Slots in CUDT), - where the "type distiller" function would be extracted and then - combined with the user-connected slot function this would call - it already with correct type. Note that also the ConnectSignal - function would have to get the signal id by template parameter, - not function parameter. For example: - - m_parent->ConnectSignal(SSLOT(updateOnSent)); - - in which updateOnSent would have to receive an appropriate type. - This has a disadvantage that you can't connect multiple signals - with different argument types to the same slot, you'd have to - make slot wrappers to translate arguments. - - It seems that a better idea would be to create binders that would - translate the argument from EventArg to the correct type according - to the rules imposed by particular event id. But I'd not make it - until there's a green light on C++11 for SRT, so maybe in a far future. - -template -class EventArgType; -#define MAP_EVENT_TYPE(tev, tp) template<> class EventArgType { typedef tp type; } -*/ - - -// The 'type' field wouldn't be even necessary if we -// use a full-templated version. TBD. -template<> struct EventVariant::VariantFor -{ - typedef const srt::CPacket* type; - static type U::*field() {return &U::packet;} -}; - -template<> struct EventVariant::VariantFor -{ - typedef int32_t type; - static type U::*field() { return &U::ack; } -}; - -template<> struct EventVariant::VariantFor -{ - typedef ECheckTimerStage type; - static type U::*field() { return &U::stage; } -}; - -template<> struct EventVariant::VariantFor -{ - typedef EInitEvent type; - static type U::*field() { return &U::init; } -}; - -// Using a hand-crafted solution because there's a non-backward-compatible -// change between C++03 and others on the way up to C++17 (and we want this -// code to be compliant with all C++ standards): -// -// - there's std::mem_fun in C++03 - deprecated in C++11, removed in C++17 -// - std::function in C++11 would be perfect, but not in C++03 - -// This can be changed in future to use C++11 way, but only after C++03 -// compatibility is finally abaondoned. Until then, this stays with a custom -// class. - -class EventSlotBase -{ -public: - virtual void emit(ETransmissionEvent tev, EventVariant var) = 0; - typedef void dispatcher_t(void* opaque, ETransmissionEvent tev, EventVariant var); - - virtual ~EventSlotBase() {} -}; - -class SimpleEventSlot: public EventSlotBase -{ -public: - void* opaque; - dispatcher_t* dispatcher; - - SimpleEventSlot(void* op, dispatcher_t* disp): opaque(op), dispatcher(disp) {} - - void emit(ETransmissionEvent tev, EventVariant var) ATR_OVERRIDE - { - (*dispatcher)(opaque, tev, var); - } -}; - -template -class ObjectEventSlot: public EventSlotBase -{ -public: - typedef void (Class::*method_ptr_t)(ETransmissionEvent tev, EventVariant var); - - method_ptr_t pm; - Class* po; - - ObjectEventSlot(Class* o, method_ptr_t m): pm(m), po(o) {} - - void emit(ETransmissionEvent tev, EventVariant var) ATR_OVERRIDE - { - (po->*pm)(tev, var); - } -}; - - -struct EventSlot -{ - mutable EventSlotBase* slot; - // Create empty slot. Calls are ignored. - EventSlot(): slot(0) {} - - // "Stealing" copy constructor, following the auto_ptr method. - // This isn't very nice, but no other way to do it in C++03 - // without rvalue-reference and move. - void moveFrom(const EventSlot& victim) - { - slot = victim.slot; // Should MOVE. - victim.slot = 0; - } - - EventSlot(const EventSlot& victim) { moveFrom(victim); } - EventSlot& operator=(const EventSlot& victim) { moveFrom(victim); return *this; } - - EventSlot(void* op, EventSlotBase::dispatcher_t* disp) - { - slot = new SimpleEventSlot(op, disp); - } - - template - EventSlot(ObjectClass* obj, typename ObjectEventSlot::method_ptr_t method) - { - slot = new ObjectEventSlot(obj, method); - } - - void emit(ETransmissionEvent tev, EventVariant var) - { - if (!slot) - return; - slot->emit(tev, var); - } - - ~EventSlot() - { - delete slot; - } -}; - - -// UDT Sequence Number 0 - (2^31 - 1) - -// seqcmp: compare two seq#, considering the wraping -// seqlen: length from the 1st to the 2nd seq#, including both -// seqoff: offset from the 2nd to the 1st seq# -// incseq: increase the seq# by 1 -// decseq: decrease the seq# by 1 -// incseq: increase the seq# by a given offset - -class CSeqNo -{ - int32_t value; - -public: - - explicit CSeqNo(int32_t v): value(v) {} - - // Comparison - bool operator == (const CSeqNo& other) const { return other.value == value; } - bool operator < (const CSeqNo& other) const - { - return seqcmp(value, other.value) < 0; - } - - // The std::rel_ops namespace cannot be "imported" - // as a whole into the class - it can only be used - // in the application code. - bool operator != (const CSeqNo& other) const { return other.value != value; } - bool operator > (const CSeqNo& other) const { return other < *this; } - bool operator >= (const CSeqNo& other) const - { - return seqcmp(value, other.value) >= 0; - } - bool operator <=(const CSeqNo& other) const - { - return seqcmp(value, other.value) <= 0; - } - - // circular arithmetics - friend int operator-(const CSeqNo& c1, const CSeqNo& c2) - { - return seqoff(c2.value, c1.value); - } - - friend CSeqNo operator-(const CSeqNo& c1, int off) - { - return CSeqNo(decseq(c1.value, off)); - } - - friend CSeqNo operator+(const CSeqNo& c1, int off) - { - return CSeqNo(incseq(c1.value, off)); - } - - friend CSeqNo operator+(int off, const CSeqNo& c1) - { - return CSeqNo(incseq(c1.value, off)); - } - - CSeqNo& operator++() - { - value = incseq(value); - return *this; - } - - /// This behaves like seq1 - seq2, in comparison to numbers, - /// and with the statement that only the sign of the result matters. - /// Returns a negative value if seq1 < seq2, - /// positive if seq1 > seq2, and zero if they are equal. - /// The only correct application of this function is when you - /// compare two values and it works faster than seqoff. However - /// the result's meaning is only in its sign. DO NOT USE THE - /// VALUE for any other purpose. It is not meant to be the - /// distance between two sequence numbers. - /// - /// Example: to check if (seq1 %> seq2): seqcmp(seq1, seq2) > 0. - /// Note: %> stands for "later than". - inline static int seqcmp(int32_t seq1, int32_t seq2) - {return (abs(seq1 - seq2) < m_iSeqNoTH) ? (seq1 - seq2) : (seq2 - seq1);} - - /// This function measures a length of the range from seq1 to seq2, - /// including endpoints (seqlen(a, a) = 1; seqlen(a, a + 1) = 2), - /// WITH A PRECONDITION that certainly @a seq1 is earlier than @a seq2. - /// This can also include an enormously large distance between them, - /// that is, exceeding the m_iSeqNoTH value (can be also used to test - /// if this distance is larger). - /// Prior to calling this function the caller must be certain that - /// @a seq2 is a sequence coming from a later time than @a seq1, - /// and that the distance does not exceed m_iMaxSeqNo. - inline static int seqlen(int32_t seq1, int32_t seq2) - { - SRT_ASSERT(seq1 >= 0 && seq1 <= m_iMaxSeqNo); - SRT_ASSERT(seq2 >= 0 && seq2 <= m_iMaxSeqNo); - return (seq1 <= seq2) ? (seq2 - seq1 + 1) : (seq2 - seq1 + m_iMaxSeqNo + 2); - } - - /// This behaves like seq2 - seq1, with the precondition that the true - /// distance between two sequence numbers never exceeds m_iSeqNoTH. - /// That is, if the difference in numeric values of these two arguments - /// exceeds m_iSeqNoTH, it is treated as if the later of these two - /// sequence numbers has overflown and actually a segment of the - /// MAX+1 value should be added to it to get the proper result. - /// - /// Note: this function does more calculations than seqcmp, so it should - /// be used if you need the exact distance between two sequences. If - /// you are only interested with their relationship, use seqcmp. - inline static int seqoff(int32_t seq1, int32_t seq2) - { - if (abs(seq1 - seq2) < m_iSeqNoTH) - return seq2 - seq1; - - if (seq1 < seq2) - return seq2 - seq1 - m_iMaxSeqNo - 1; - - return seq2 - seq1 + m_iMaxSeqNo + 1; - } - - inline static int32_t incseq(int32_t seq) - {return (seq == m_iMaxSeqNo) ? 0 : seq + 1;} - - inline static int32_t decseq(int32_t seq) - {return (seq == 0) ? m_iMaxSeqNo : seq - 1;} - - inline static int32_t incseq(int32_t seq, int32_t inc) - {return (m_iMaxSeqNo - seq >= inc) ? seq + inc : seq - m_iMaxSeqNo + inc - 1;} - // m_iMaxSeqNo >= inc + sec --- inc + sec <= m_iMaxSeqNo - // if inc + sec > m_iMaxSeqNo then return seq + inc - (m_iMaxSeqNo+1) - - inline static int32_t decseq(int32_t seq, int32_t dec) - { - // Check if seq - dec < 0, but before it would have happened - if ( seq < dec ) - { - int32_t left = dec - seq; // This is so many that is left after dragging dec to 0 - // So now decrement the (m_iMaxSeqNo+1) by "left" - return m_iMaxSeqNo - left + 1; - } - return seq - dec; - } - - static int32_t maxseq(int32_t seq1, int32_t seq2) - { - if (seqcmp(seq1, seq2) < 0) - return seq2; - return seq1; - } - -public: - static const int32_t m_iSeqNoTH = 0x3FFFFFFF; // threshold for comparing seq. no. - static const int32_t m_iMaxSeqNo = 0x7FFFFFFF; // maximum sequence number used in UDT -}; - -//////////////////////////////////////////////////////////////////////////////// - -// UDT ACK Sub-sequence Number: 0 - (2^31 - 1) - -class CAckNo -{ -public: - inline static int32_t incack(int32_t ackno) - {return (ackno == m_iMaxAckSeqNo) ? 0 : ackno + 1;} - -public: - static const int32_t m_iMaxAckSeqNo = 0x7FFFFFFF; // maximum ACK sub-sequence number used in UDT -}; - -template -class RollNumber -{ - typedef RollNumber this_t; - typedef Bits number_t; - uint32_t number; - -public: - - static const size_t OVER = number_t::mask+1; - static const size_t HALF = (OVER-MIN)/2; - -private: - static int Diff(uint32_t left, uint32_t right) - { - // UNExpected order, diff is negative - if ( left < right ) - { - int32_t diff = right - left; - if ( diff >= int32_t(HALF) ) // over barrier - { - // It means that left is less than right because it was overflown - // For example: left = 0x0005, right = 0xFFF0; diff = 0xFFEB > HALF - left += OVER - MIN; // left was really 0x00010005, just narrowed. - // Now the difference is 0x0015, not 0xFFFF0015 - } - } - else - { - int32_t diff = left - right; - if ( diff >= int32_t(HALF) ) - { - right += OVER - MIN; - } - } - - return left - right; - } - -public: - explicit RollNumber(uint32_t val): number(val) - { - } - - bool operator<(const this_t& right) const - { - int32_t ndiff = number - right.number; - if (ndiff < -int32_t(HALF)) - { - // it' like ndiff > 0 - return false; - } - - if (ndiff > int32_t(HALF)) - { - // it's like ndiff < 0 - return true; - } - - return ndiff < 0; - } - - bool operator>(const this_t& right) const - { - return right < *this; - } - - bool operator==(const this_t& right) const - { - return number == right.number; - } - - bool operator<=(const this_t& right) const - { - return !(*this > right); - } - - bool operator>=(const this_t& right) const - { - return !(*this < right); - } - - void operator++(int) - { - ++number; - if (number > number_t::mask) - number = MIN; - } - - this_t& operator++() { (*this)++; return *this; } - - void operator--(int) - { - if (number == MIN) - number = number_t::mask; - else - --number; - } - this_t& operator--() { (*this)--; return *this; } - - int32_t operator-(this_t right) - { - return Diff(this->number, right.number); - } - - void operator+=(int32_t delta) - { - // NOTE: this condition in practice tests if delta is negative. - // That's because `number` is always positive, so negated delta - // can't be ever greater than this, unless it's negative. - if (-delta > int64_t(number)) - { - number = OVER - MIN + number + delta; // NOTE: delta is negative - } - else - { - number += delta; - if (number >= OVER) - number -= OVER - MIN; - } - } - - operator uint32_t() const { return number; } -}; - -//////////////////////////////////////////////////////////////////////////////// - -struct CIPAddress -{ - static bool ipcmp(const struct sockaddr* addr1, const struct sockaddr* addr2, int ver = AF_INET); - static void ntop(const struct sockaddr_any& addr, uint32_t ip[4]); - static void pton(sockaddr_any& addr, const uint32_t ip[4], const sockaddr_any& peer); - static std::string show(const struct sockaddr* adr); -}; - -//////////////////////////////////////////////////////////////////////////////// - -struct CMD5 -{ - static void compute(const char* input, unsigned char result[16]); -}; - -// Debug stats -template -class StatsLossRecords -{ - int32_t initseq; - std::bitset array; - -public: - StatsLossRecords(): initseq(SRT_SEQNO_NONE) {} - - // To check if this structure still keeps record of that sequence. - // This is to check if the information about this not being found - // is still reliable. - bool exists(int32_t seq) - { - return initseq != SRT_SEQNO_NONE && CSeqNo::seqcmp(seq, initseq) >= 0; - } - - int32_t base() { return initseq; } - - void clear() - { - initseq = SRT_SEQNO_NONE; - array.reset(); - } - - void add(int32_t lo, int32_t hi) - { - int32_t end = CSeqNo::incseq(hi); - for (int32_t i = lo; i != end; i = CSeqNo::incseq(i)) - add(i); - } - - void add(int32_t seq) - { - if ( array.none() ) - { - // May happen it wasn't initialized. Set it as initial loss sequence. - initseq = seq; - array[0] = true; - return; - } - - // Calculate the distance between this seq and the oldest one. - int seqdiff = CSeqNo::seqoff(initseq, seq); - if ( seqdiff > int(SIZE) ) - { - // Size exceeded. Drop the oldest sequences. - // First calculate how many must be removed. - size_t toremove = seqdiff - SIZE; - // Now, since that position, find the nearest 1 - while ( !array[toremove] && toremove <= SIZE ) - ++toremove; - - // All have to be dropped, so simply reset the array - if ( toremove == SIZE ) - { - initseq = seq; - array[0] = true; - return; - } - - // Now do the shift of the first found 1 to position 0 - // and its index add to initseq - initseq += toremove; - seqdiff -= toremove; - array >>= toremove; - } - - // Now set appropriate bit that represents this seq - array[seqdiff] = true; - } - - StatsLossRecords& operator << (int32_t seq) - { - add(seq); - return *this; - } - - void remove(int32_t seq) - { - // Check if is in range. If not, ignore. - int seqdiff = CSeqNo::seqoff(initseq, seq); - if ( seqdiff < 0 ) - return; // already out of array - if ( seqdiff > SIZE ) - return; // never was added! - - array[seqdiff] = true; - } - - bool find(int32_t seq) const - { - int seqdiff = CSeqNo::seqoff(initseq, seq); - if ( seqdiff < 0 ) - return false; // already out of array - if ( size_t(seqdiff) > SIZE ) - return false; // never was added! - - return array[seqdiff]; - } - -#if HAVE_CXX11 - - std::string to_string() const - { - std::string out; - for (size_t i = 0; i < SIZE; ++i) - { - if ( array[i] ) - out += std::to_string(initseq+i) + " "; - } - - return out; - } -#endif -}; - - -// There are some better or worse things you can find outside, -// there's also boost::circular_buffer, but it's too overspoken -// to be included here. We also can't rely on boost. Maybe in future -// when it's added to the standard and SRT can heighten C++ standard -// requirements; until then it needs this replacement. -template -class CircularBuffer -{ -#ifdef SRT_TEST_CIRCULAR_BUFFER -public: -#endif - int m_iSize; - Value* m_aStorage; - int m_xBegin; - int m_xEnd; - - static void destr(Value& v) - { - v.~Value(); - } - - static void constr(Value& v) - { - new ((void*)&v) Value(); - } - - template - static void constr(Value& v, const V& source) - { - new ((void*)&v) Value(source); - } - - // Wipe the copy constructor - CircularBuffer(const CircularBuffer&); - -public: - typedef Value value_type; - - CircularBuffer(int size) - :m_iSize(size+1), - m_xBegin(0), - m_xEnd(0) - { - // We reserve one spare element just for a case. - if (size == 0) - m_aStorage = 0; - else - m_aStorage = (Value*)::operator new (sizeof(Value) * m_iSize); - } - - void set_capacity(int size) - { - reset(); - - // This isn't called resize (the size is 0 after the operation) - // nor reserve (the existing elements are removed). - if (size != m_iSize) - { - if (m_aStorage) - ::operator delete (m_aStorage); - m_iSize = size+1; - m_aStorage = (Value*)::operator new (sizeof(Value) * m_iSize); - } - } - - void reset() - { - if (m_xEnd < m_xBegin) - { - for (int i = m_xBegin; i < m_iSize; ++i) - destr(m_aStorage[i]); - for (int i = 0; i < m_xEnd; ++i) - destr(m_aStorage[i]); - } - else - { - for (int i = m_xBegin; i < m_xEnd; ++i) - destr(m_aStorage[i]); - } - - m_xBegin = 0; - m_xEnd = 0; - } - - ~CircularBuffer() - { - reset(); - ::operator delete (m_aStorage); - } - - // In the beginning, m_xBegin == m_xEnd, which - // means that the container is empty. Adding can - // be done exactly at the place pointed to by m_xEnd, - // and m_xEnd must be then shifted to the next unused one. - // When (m_xEnd + 1) % m_zSize == m_xBegin, the container - // is considered full and the element adding is rejected. - // - // This container is not designed to be STL-compatible - // because it doesn't make much sense. It's not a typical - // container, even treated as random-access container. - - int shift(int basepos, int shift) const - { - return (basepos + shift) % m_iSize; - } - - // Simplified versions with ++ and --; avoid using division instruction - int shift_forward(int basepos) const - { - if (++basepos == m_iSize) - return 0; - return basepos; - } - - int shift_backward(int basepos) const - { - if (basepos == 0) - return m_iSize-1; - return --basepos; - } - - int size() const - { - // Count the distance between begin and end - if (m_xEnd < m_xBegin) - { - // Use "merge two slices" method. - // (BEGIN - END) is the distance of the unused - // space in the middle. Used space is left to END - // and right to BEGIN, the sum of the left and right - // slice and the free space is the size. - - // This includes also a case when begin and end - // are equal, which means that it's empty, so - // spaceleft() should simply return m_iSize. - return m_iSize - (m_xBegin - m_xEnd); - } - - return m_xEnd - m_xBegin; - } - - bool empty() const { return m_xEnd == m_xBegin; } - - size_t capacity() const { return m_iSize-1; } - - int spaceleft() const - { - // It's kinda tautology, but this will be more efficient. - if (m_xEnd < m_xBegin) - { - return m_xBegin - m_xEnd; - } - - return m_iSize - (m_xEnd - m_xBegin); - } - - // This is rather written for testing and rather won't - // be used in the real code. - template - int push(const V& v) - { - // Check if you can add - int nend = shift_forward(m_xEnd); - if ( nend == m_xBegin) - return -1; - - constr(m_aStorage[m_xEnd], v); - m_xEnd = nend; - return size() - 1; - } - - Value* push() - { - int nend = shift_forward(m_xEnd); - if ( nend == m_xBegin) - return NULL; - - Value* pos = &m_aStorage[m_xEnd]; - constr(*pos); - m_xEnd = nend; - return pos; - } - - bool access(int position, Value*& w_v) - { - // This version doesn't require the boolean value to report - // whether the element is newly added because it never adds - // a new element. - int ipos, vend; - - if (!INT_checkAccess(position, ipos, vend)) - return false; - if (ipos >= vend) // exceeds - return false; - - INT_access(ipos, false, (w_v)); // never exceeds - return true; - } - - // Ok, now it's the real deal. - bool access(int position, Value*& w_v, bool& w_isnew) - { - int ipos, vend; - - if (!INT_checkAccess(position, ipos, vend)) - return false; - bool exceeds = (ipos >= vend); - w_isnew = exceeds; - - INT_access(ipos, exceeds, (w_v)); - return true; - } - -private: - bool INT_checkAccess(int position, int& ipos, int& vend) - { - // Reject if no space left. - // Also INVAL if negative position. - if (position >= (m_iSize-1) || position < 0) - return false; // That's way to far, we can't even calculate - - ipos = m_xBegin + position; - - vend = m_xEnd; - if (m_xEnd < m_xBegin) - vend += m_iSize; - - return true; - } - - void INT_access(int ipos, bool exceeds, Value*& w_v) - { - if (ipos >= m_iSize) - ipos -= m_iSize; // wrap around - - // Update the end position. - if (exceeds) - { - int nend = ipos+1; - if (m_xEnd > nend) - { - // Here we know that the current index exceeds the size. - // So, if this happens, it's m_xEnd wrapped around. - // Clear out elements in two slices: - // - from m_xEnd to m_iSize-1 - // - from 0 to nend - for (int i = m_xEnd; i < m_iSize; ++i) - constr(m_aStorage[i]); - for (int i = 0; i < nend; ++i) - constr(m_aStorage[i]); - } - else - { - for (int i = m_xEnd; i < nend; ++i) - constr(m_aStorage[i]); - } - - if (nend == m_iSize) - nend = 0; - - m_xEnd = nend; - } - - w_v = &m_aStorage[ipos]; - } - -public: - bool set(int position, const Value& newval, bool overwrite = true) - { - Value* pval = 0; - bool isnew = false; - if (!access(position, (pval), (isnew))) - return false; - - if (isnew || overwrite) - *pval = newval; - return true; - } - - template - bool update(int position, Updater updater) - { - Value* pval = 0; - bool isnew = false; - if (!access(position, (pval), (isnew))) - return false; - - updater(*pval, isnew); - return true; - } - - int getIndexFor(int position) const - { - int ipos = m_xBegin + position; - - int vend = m_xEnd; - if (vend < m_xBegin) - vend += m_iSize; - - if (ipos >= vend) - return -1; - - if (ipos >= m_iSize) - ipos -= m_iSize; - - return ipos; - } - - bool get(int position, Value& w_out) const - { - // Check if that position is occupied - if (position > m_iSize || position < 0) - return false; - - int ipos = getIndexFor(position); - if (ipos == -1) - return false; - - w_out = m_aStorage[ipos]; - return true; - } - - bool drop(int position) - { - // This function "deletes" items by shifting the - // given position to position 0. That is, - // elements from the beginning are being deleted - // up to (including) the given position. - if (position > m_iSize || position < 1) - return false; - - int ipos = m_xBegin + position; - int vend = m_xEnd; - if (vend < m_xBegin) - vend += m_iSize; - - // Destroy the elements in the removed range - - if (ipos >= vend) - { - // There was a request to drop; the position - // is higher than the number of items. Allow this - // and simply make the container empty. - reset(); - return true; - } - - // Otherwise we have a new beginning. - int nbegin = ipos; - - // Destroy the old elements - if (nbegin >= m_iSize) - { - nbegin -= m_iSize; - - for (int i = m_xBegin; i < m_iSize; ++i) - destr(m_aStorage[i]); - for (int i = 0; i < nbegin; ++i) - destr(m_aStorage[i]); - } - else - { - for (int i = m_xBegin; i < nbegin; ++i) - destr(m_aStorage[i]); - } - - m_xBegin = nbegin; - - return true; - } - - // This function searches for an element that satisfies - // the given predicate. If none found, returns -1. - template - int find_if(Predicate pred) - { - if (m_xEnd < m_xBegin) - { - // Loop in two slices - for (int i = m_xBegin; i < m_iSize; ++i) - if (pred(m_aStorage[i])) - return i - m_xBegin; - - for (int i = 0; i < m_xEnd; ++i) - if (pred(m_aStorage[i])) - return i + m_iSize - m_xBegin; - } - else - { - for (int i = m_xBegin; i < m_xEnd; ++i) - if (pred(m_aStorage[i])) - return i - m_xBegin; - } - - return -1; - } -}; - -// Version parsing -inline ATR_CONSTEXPR uint32_t SrtVersion(int major, int minor, int patch) -{ - return patch + minor*0x100 + major*0x10000; -} - -inline int32_t SrtParseVersion(const char* v) -{ - int major, minor, patch; - int result = sscanf(v, "%d.%d.%d", &major, &minor, &patch); - - if (result != 3) - { - return 0; - } - - return SrtVersion(major, minor, patch); -} - -inline std::string SrtVersionString(int version) -{ - int patch = version % 0x100; - int minor = (version/0x100)%0x100; - int major = version/0x10000; - - char buf[20]; - sprintf(buf, "%d.%d.%d", major, minor, patch); - return buf; -} - -bool SrtParseConfig(std::string s, SrtConfig& w_config); - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/congctl.h b/Vendor/SRT/Includes/congctl.h deleted file mode 100644 index b957dbdd0..000000000 --- a/Vendor/SRT/Includes/congctl.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * 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/. - * - */ - -#ifndef INC_SRT_CONGCTL_H -#define INC_SRT_CONGCTL_H - -#include -#include -#include -#include - -namespace srt { - -class CUDT; -class SrtCongestionControlBase; -typedef SrtCongestionControlBase* srtcc_create_t(srt::CUDT* parent); - -class SrtCongestion -{ - // Temporarily changed to linear searching, until this is exposed - // for a user-defined controller. - // Note that this is a pointer to function :) - - static const size_t N_CONTROLLERS = 2; - // The first/second is to mimic the map. - typedef struct { const char* first; srtcc_create_t* second; } NamePtr; - static NamePtr congctls[N_CONTROLLERS]; - - // This is a congctl container. - SrtCongestionControlBase* congctl; - size_t selector; - - void Check(); - -public: - - // If you predict to allow something to be done on controller also - // before it is configured, call this first. If you need it configured, - // you can rely on Check(). - bool ready() { return congctl; } - SrtCongestionControlBase* operator->() { Check(); return congctl; } - - // In the beginning it's uninitialized - SrtCongestion(): congctl(), selector(N_CONTROLLERS) {} - - struct IsName - { - std::string n; - IsName(std::string nn): n(nn) {} - bool operator()(NamePtr np) { return n == np.first; } - }; - - static NamePtr* find(const std::string& name) - { - NamePtr* end = congctls+N_CONTROLLERS; - NamePtr* try_selector = std::find_if(congctls, end, IsName(name)); - return try_selector != end ? try_selector : NULL; - } - - static bool exists(const std::string& name) - { - return find(name); - } - - // You can call select() multiple times, until finally - // the 'configure' method is called. - bool select(const std::string& name) - { - NamePtr* try_selector = find(name); - if (!try_selector) - return false; - selector = try_selector - congctls; - return true; - } - - std::string selected_name() - { - if (selector == N_CONTROLLERS) - return ""; - return congctls[selector].first; - } - - // Copy constructor - important when listener-spawning - // Things being done: - // 1. The congctl is individual, so don't copy it. Set NULL. - // 2. The selected name is copied so that it's configured correctly. - SrtCongestion(const SrtCongestion& source): congctl(), selector(source.selector) {} - void operator=(const SrtCongestion& source) { congctl = 0; selector = source.selector; } - - // This function will be called by the parent CUDT - // in appropriate time. It should select appropriate - // congctl basing on the value in selector, then - // pin oneself in into CUDT for receiving event signals. - bool configure(srt::CUDT* parent); - - // This function will intentionally delete the contained object. - // This makes future calls to ready() return false. Calling - // configure on it again will create it again. - void dispose(); - - // Will delete the pinned in congctl object. - // This must be defined in *.cpp file due to virtual - // destruction. - ~SrtCongestion(); - - enum RexmitMethod - { - SRM_LATEREXMIT, - SRM_FASTREXMIT - }; - - enum TransAPI - { - STA_MESSAGE = 0x1, // sendmsg/recvmsg functions - STA_BUFFER = 0x2, // send/recv functions - STA_FILE = 0x3, // sendfile/recvfile functions - }; - - enum TransDir - { - STAD_RECV = 0, - STAD_SEND = 1 - }; -}; - -class CPacket; - -class SrtCongestionControlBase -{ -protected: - // Here can be some common fields - srt::CUDT* m_parent; - - double m_dPktSndPeriod; - double m_dCWndSize; - - //int m_iBandwidth; // NOT REQUIRED. Use m_parent->bandwidth() instead. - double m_dMaxCWndSize; - - //int m_iMSS; // NOT REQUIRED. Use m_parent->MSS() instead. - //int32_t m_iSndCurrSeqNo; // NOT REQUIRED. Use m_parent->sndSeqNo(). - //int m_iRcvRate; // NOT REQUIRED. Use m_parent->deliveryRate() instead. - //int m_RTT; // NOT REQUIRED. Use m_parent->SRTT() instead. - //char* m_pcParam; // Used to access m_llMaxBw. Use m_parent->maxBandwidth() instead. - - // Constructor in protected section so that this class is semi-abstract. - SrtCongestionControlBase(srt::CUDT* parent); -public: - - // This could be also made abstract, but this causes a linkage - // problem in C++: this would constitute the first virtual method, - // and C++ compiler uses the location of the first virtual method as the - // file to which it also emits the virtual call table. When this is - // abstract, there would have to be simultaneously either defined - // an empty method in congctl.cpp file (obviously never called), - // or simply left empty body here. - virtual ~SrtCongestionControlBase() { } - - // All these functions that return values interesting for processing - // by CUDT can be overridden. Normally they should refer to the fields - // and these fields should keep the values as a state. - virtual double pktSndPeriod_us() { return m_dPktSndPeriod; } - virtual double cgWindowSize() { return m_dCWndSize; } - virtual double cgWindowMaxSize() { return m_dMaxCWndSize; } - - virtual int64_t sndBandwidth() { return 0; } - - // If user-defined, will return nonzero value. - // If not, it will be internally calculated. - virtual int RTO() { return 0; } - - // Maximum number of packets to trigger ACK sending. - // Specifies the number of packets to receive before sending the ACK. - // Used by CUDT together with ACKTimeout_us() to trigger ACK packet sending. - virtual int ACKMaxPackets() const { return 0; } - - // Periodical interval to send an ACK, in microseconds. - // If user-defined, this value will be used to calculate - // the next ACK time every time ACK is considered to be sent (see CUDT::checkTimers). - // Otherwise this will be calculated internally in CUDT, normally taken - // from CUDT::COMM_SYN_INTERVAL_US. - virtual int ACKTimeout_us() const { return 0; } - - // Called when the settings concerning m_llMaxBW were changed. - // Arg 1: value of CUDT's m_config.m_llMaxBW - // Arg 2: value calculated out of CUDT's m_config.llInputBW and m_config.iOverheadBW. - virtual void updateBandwidth(int64_t, int64_t) {} - - virtual bool needsQuickACK(const srt::CPacket&) - { - return false; - } - - // Particular controller is allowed to agree or disagree on the use of particular API. - virtual bool checkTransArgs(SrtCongestion::TransAPI , SrtCongestion::TransDir , const char* /*buffer*/, size_t /*size*/, int /*ttl*/, bool /*inorder*/) - { - return true; - } - - virtual SrtCongestion::RexmitMethod rexmitMethod() = 0; // Implementation enforced. - - virtual int64_t updateNAKInterval(int64_t nakint_us, int rcv_speed, size_t loss_length) - { - if (rcv_speed > 0) - nakint_us += (loss_length * int64_t(1000000) / rcv_speed); - - return nakint_us; - } - - virtual int64_t minNAKInterval() - { - return 0; // Leave default - } -}; - - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/core.h b/Vendor/SRT/Includes/core.h deleted file mode 100644 index fa58ca7c2..000000000 --- a/Vendor/SRT/Includes/core.h +++ /dev/null @@ -1,1162 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 02/28/2012 -modified by - Haivision Systems Inc. -*****************************************************************************/ - - -#ifndef INC_SRT_CORE_H -#define INC_SRT_CORE_H - -#include -#include -#include "srt.h" -#include "common.h" -#include "list.h" -#include "buffer.h" -#include "buffer_rcv.h" -#include "window.h" -#include "packet.h" -#include "channel.h" -#include "cache.h" -#include "queue.h" -#include "handshake.h" -#include "congctl.h" -#include "packetfilter.h" -#include "socketconfig.h" -#include "utilities.h" -#include "logger_defs.h" - -#include "stats.h" - -#include - - -// TODO: Utility function - to be moved to utilities.h? -template -inline T CountIIR(T base, T newval, double factor) -{ - if ( base == 0.0 ) - return newval; - - T diff = newval - base; - return base+T(diff*factor); -} - -// TODO: Probably a better rework for that can be done - this can be -// turned into a serializable structure, just like it's done for CHandShake. -enum AckDataItem -{ - ACKD_RCVLASTACK = 0, - ACKD_RTT = 1, - ACKD_RTTVAR = 2, - ACKD_BUFFERLEFT = 3, - ACKD_TOTAL_SIZE_SMALL = 4, // Size of the Small ACK, packet length = 16. - - // Extra fields for Full ACK. - ACKD_RCVSPEED = 4, - ACKD_BANDWIDTH = 5, - ACKD_TOTAL_SIZE_UDTBASE = 6, // Packet length = 24. - - // Extra stats since SRT v1.0.1. - ACKD_RCVRATE = 6, - ACKD_TOTAL_SIZE_VER101 = 7, // Packet length = 28. - - // Only in SRT v1.0.2. - ACKD_XMRATE_VER102_ONLY = 7, - ACKD_TOTAL_SIZE_VER102_ONLY = 8, // Packet length = 32. - - ACKD_TOTAL_SIZE = ACKD_TOTAL_SIZE_VER102_ONLY // The maximum known ACK length is 32 bytes. -}; -const size_t ACKD_FIELD_SIZE = sizeof(int32_t); - -static const size_t SRT_SOCKOPT_NPOST = 12; -extern const SRT_SOCKOPT srt_post_opt_list []; - -enum GroupDataItem -{ - GRPD_GROUPID, - GRPD_GROUPDATA, - - GRPD_E_SIZE -}; - -const size_t GRPD_MIN_SIZE = 2; // ID and GROUPTYPE as backward compat - -const size_t GRPD_FIELD_SIZE = sizeof(int32_t); - -// For HSv4 legacy handshake -#define SRT_MAX_HSRETRY 10 /* Maximum SRT handshake retry */ - -enum SeqPairItems -{ - SEQ_BEGIN = 0, SEQ_END = 1, SEQ_SIZE = 2 -}; - - -// Extended SRT Congestion control class - only an incomplete definition required -class CCryptoControl; - -namespace srt { -class CUDTUnited; -class CUDTSocket; -#if ENABLE_BONDING -class CUDTGroup; -#endif - -// XXX REFACTOR: The 'CUDT' class is to be merged with 'CUDTSocket'. -// There's no reason for separating them, there's no case of having them -// anyhow managed separately. After this is done, with a small help with -// separating the internal abnormal path management (exceptions) from the -// API (return values), through CUDTUnited, this class may become in future -// an officially exposed C++ API. -class CUDT -{ - friend class CUDTSocket; - friend class CUDTUnited; - friend class CCC; - friend struct CUDTComp; - friend class CCache; - friend class CRendezvousQueue; - friend class CSndQueue; - friend class CRcvQueue; - friend class CSndUList; - friend class CRcvUList; - friend class PacketFilter; - friend class CUDTGroup; - friend class TestMockCUDT; // unit tests - - typedef sync::steady_clock::time_point time_point; - typedef sync::steady_clock::duration duration; - typedef sync::AtomicClock atomic_time_point; - typedef sync::AtomicDuration atomic_duration; - -private: // constructor and desctructor - void construct(); - void clearData(); - CUDT(CUDTSocket* parent); - CUDT(CUDTSocket* parent, const CUDT& ancestor); - const CUDT& operator=(const CUDT&) {return *this;} // = delete ? - ~CUDT(); - -public: //API - static int startup(); - static int cleanup(); - static SRTSOCKET socket(); -#if ENABLE_BONDING - static SRTSOCKET createGroup(SRT_GROUP_TYPE); - static SRTSOCKET getGroupOfSocket(SRTSOCKET socket); - static int getGroupData(SRTSOCKET groupid, SRT_SOCKGROUPDATA* pdata, size_t* psize); - static bool isgroup(SRTSOCKET sock) { return (sock & SRTGROUP_MASK) != 0; } -#endif - static int bind(SRTSOCKET u, const sockaddr* name, int namelen); - static int bind(SRTSOCKET u, UDPSOCKET udpsock); - static int listen(SRTSOCKET u, int backlog); - static SRTSOCKET accept(SRTSOCKET u, sockaddr* addr, int* addrlen); - static SRTSOCKET accept_bond(const SRTSOCKET listeners [], int lsize, int64_t msTimeOut); - static int connect(SRTSOCKET u, const sockaddr* name, int namelen, int32_t forced_isn); - static int connect(SRTSOCKET u, const sockaddr* name, const sockaddr* tname, int namelen); -#if ENABLE_BONDING - static int connectLinks(SRTSOCKET grp, SRT_SOCKGROUPCONFIG links [], int arraysize); -#endif - static int close(SRTSOCKET u); - static int getpeername(SRTSOCKET u, sockaddr* name, int* namelen); - static int getsockname(SRTSOCKET u, sockaddr* name, int* namelen); - static int getsockopt(SRTSOCKET u, int level, SRT_SOCKOPT optname, void* optval, int* optlen); - static int setsockopt(SRTSOCKET u, int level, SRT_SOCKOPT optname, const void* optval, int optlen); - static int send(SRTSOCKET u, const char* buf, int len, int flags); - static int recv(SRTSOCKET u, char* buf, int len, int flags); - static int sendmsg(SRTSOCKET u, const char* buf, int len, int ttl = SRT_MSGTTL_INF, bool inorder = false, int64_t srctime = 0); - static int recvmsg(SRTSOCKET u, char* buf, int len, int64_t& srctime); - static int sendmsg2(SRTSOCKET u, const char* buf, int len, SRT_MSGCTRL& mctrl); - static int recvmsg2(SRTSOCKET u, char* buf, int len, SRT_MSGCTRL& w_mctrl); - static int64_t sendfile(SRTSOCKET u, std::fstream& ifs, int64_t& offset, int64_t size, int block = SRT_DEFAULT_SENDFILE_BLOCK); - static int64_t recvfile(SRTSOCKET u, std::fstream& ofs, int64_t& offset, int64_t size, int block = SRT_DEFAULT_RECVFILE_BLOCK); - static int select(int nfds, UDT::UDSET* readfds, UDT::UDSET* writefds, UDT::UDSET* exceptfds, const timeval* timeout); - static int selectEx(const std::vector& fds, std::vector* readfds, std::vector* writefds, std::vector* exceptfds, int64_t msTimeOut); - static int epoll_create(); - static int epoll_clear_usocks(int eid); - static int epoll_add_usock(const int eid, const SRTSOCKET u, const int* events = NULL); - static int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events = NULL); - static int epoll_remove_usock(const int eid, const SRTSOCKET u); - static int epoll_remove_ssock(const int eid, const SYSSOCKET s); - static int epoll_update_usock(const int eid, const SRTSOCKET u, const int* events = NULL); - static int epoll_update_ssock(const int eid, const SYSSOCKET s, const int* events = NULL); - static int epoll_wait(const int eid, std::set* readfds, std::set* writefds, - int64_t msTimeOut, std::set* lrfds = NULL, std::set* wrfds = NULL); - static int epoll_uwait(const int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut); - static int32_t epoll_set(const int eid, int32_t flags); - static int epoll_release(const int eid); - static CUDTException& getlasterror(); - static int bstats(SRTSOCKET u, CBytePerfMon* perf, bool clear = true, bool instantaneous = false); -#if ENABLE_BONDING - static int groupsockbstats(SRTSOCKET u, CBytePerfMon* perf, bool clear = true); -#endif - static SRT_SOCKSTATUS getsockstate(SRTSOCKET u); - static bool setstreamid(SRTSOCKET u, const std::string& sid); - static std::string getstreamid(SRTSOCKET u); - static int getsndbuffer(SRTSOCKET u, size_t* blocks, size_t* bytes); - static int rejectReason(SRTSOCKET s); - static int rejectReason(SRTSOCKET s, int value); - static int64_t socketStartTime(SRTSOCKET s); - -public: // internal API - // This is public so that it can be used directly in API implementation functions. - struct APIError - { - APIError(const CUDTException&); - APIError(CodeMajor, CodeMinor, int = 0); - - operator int() const - { - return SRT_ERROR; - } - }; - - static const SRTSOCKET INVALID_SOCK = -1; // Invalid socket descriptor - static const int ERROR = -1; // Socket api error returned value - - static const int HS_VERSION_UDT4 = 4; - static const int HS_VERSION_SRT1 = 5; - - // Parameters - // - // NOTE: Use notation with X*1000*1000*... instead of - // million zeros in a row. - static const int COMM_RESPONSE_MAX_EXP = 16; - static const int SRT_TLPKTDROP_MINTHRESHOLD_MS = 1000; - static const uint64_t COMM_KEEPALIVE_PERIOD_US = 1*1000*1000; - static const int32_t COMM_SYN_INTERVAL_US = 10*1000; - static const int COMM_CLOSE_BROKEN_LISTENER_TIMEOUT_MS = 3000; - static const uint16_t MAX_WEIGHT = 32767; - static const size_t ACK_WND_SIZE = 1024; - static const int INITIAL_RTT = 10 * COMM_SYN_INTERVAL_US; - static const int INITIAL_RTTVAR = INITIAL_RTT / 2; - - int handshakeVersion() - { - return m_ConnRes.m_iVersion; - } - - std::string CONID() const - { -#if ENABLE_LOGGING - std::ostringstream os; - os << "@" << m_SocketID << ":"; - return os.str(); -#else - return ""; -#endif - } - - SRTSOCKET socketID() const { return m_SocketID; } - - static CUDT* getUDTHandle(SRTSOCKET u); - static std::vector existingSockets(); - - void addressAndSend(CPacket& pkt); - - SRT_ATTR_REQUIRES(m_ConnectionLock) - void sendSrtMsg(int cmd, uint32_t *srtdata_in = NULL, size_t srtlen_in = 0); - - bool isOPT_TsbPd() const { return m_config.bTSBPD; } - int SRTT() const { return m_iSRTT; } - int RTTVar() const { return m_iRTTVar; } - int32_t sndSeqNo() const { return m_iSndCurrSeqNo; } - int32_t schedSeqNo() const { return m_iSndNextSeqNo; } - bool overrideSndSeqNo(int32_t seq); - - sync::steady_clock::time_point lastRspTime() const { return m_tsLastRspTime.load(); } - sync::steady_clock::time_point freshActivationStart() const { return m_tsFreshActivation; } - - int32_t rcvSeqNo() const { return m_iRcvCurrSeqNo; } - int flowWindowSize() const { return m_iFlowWindowSize; } - int32_t deliveryRate() const { return m_iDeliveryRate; } - int bandwidth() const { return m_iBandwidth; } - int64_t maxBandwidth() const { return m_config.llMaxBW; } - int MSS() const { return m_config.iMSS; } - - uint32_t peerLatency_us() const { return m_iPeerTsbPdDelay_ms * 1000; } - int peerIdleTimeout_ms() const { return m_config.iPeerIdleTimeout_ms; } - size_t maxPayloadSize() const { return m_iMaxSRTPayloadSize; } - size_t OPT_PayloadSize() const { return m_config.zExpPayloadSize; } - int sndLossLength() { return m_pSndLossList->getLossLength(); } - int32_t ISN() const { return m_iISN; } - int32_t peerISN() const { return m_iPeerISN; } - duration minNAKInterval() const { return m_tdMinNakInterval; } - sockaddr_any peerAddr() const { return m_PeerAddr; } - - /// Returns the number of packets in flight (sent, but not yet acknowledged). - /// @param lastack is the sequence number of the first unacknowledged packet. - /// @param curseq is the sequence number of the latest original packet sent - /// - /// @note When there are no packets in flight, lastack = incseq(curseq). - /// - /// @returns The number of packets in flight belonging to the interval [0; ...) - static int32_t getFlightSpan(int32_t lastack, int32_t curseq) - { - // Packets sent: - // | 1 | 2 | 3 | 4 | 5 | - // ^ ^ - // | | - // lastack | - // curseq - // - // In Flight: [lastack; curseq] - // - // Normally 'lastack' should be PAST the 'curseq', - // however in a case when the sending stopped and all packets were - // ACKed, the 'lastack' is one sequence ahead of 'curseq'. - // Therefore we increase 'curseq' by 1 forward and then - // get the distance towards the last ACK. This way this value may - // be only positive as seqlen() includes endpoints. - // Finally, we subtract 1 to exclude the increment added earlier. - - return CSeqNo::seqlen(lastack, CSeqNo::incseq(curseq)) - 1; - } - - /// Returns the number of packets in flight (sent, but not yet acknowledged). - /// @returns The number of packets in flight belonging to the interval [0; ...) - int32_t getFlightSpan() const - { - return getFlightSpan(m_iSndLastAck, m_iSndCurrSeqNo); - } - - int minSndSize(int len = 0) const - { - const int ps = (int) maxPayloadSize(); - if (len == 0) // wierd, can't use non-static data member as default argument! - len = ps; - return m_config.bMessageAPI ? (len+ps-1)/ps : 1; - } - - int32_t makeTS(const time_point& from_time) const - { - // NOTE: - // - This calculates first the time difference towards start time. - // - This difference value is also CUT OFF THE SEGMENT information - // (a multiple of MAX_TIMESTAMP+1) - // So, this can be simply defined as: TS = (RTS - STS) % (MAX_TIMESTAMP+1) - // XXX Would be nice to check if local_time > m_tsStartTime, - // otherwise it may go unnoticed with clock skew. - return (int32_t) sync::count_microseconds(from_time - m_stats.tsStartTime); - } - - void setPacketTS(CPacket& p, const time_point& local_time) - { - p.m_iTimeStamp = makeTS(local_time); - } - - // Utility used for closing a listening socket - // immediately to free the socket - void notListening() - { - sync::ScopedLock cg(m_ConnectionLock); - m_bListening = false; - m_pRcvQueue->removeListener(this); - } - - static int32_t generateISN() - { - using namespace sync; - return genRandomInt(0, CSeqNo::m_iMaxSeqNo); - } - - static CUDTUnited& uglobal(); // UDT global management base - - std::set& pollset() { return m_sPollID; } - - CSrtConfig m_config; - - SRTU_PROPERTY_RO(SRTSOCKET, id, m_SocketID); - SRTU_PROPERTY_RO(bool, isClosing, m_bClosing); -#if ENABLE_NEW_RCVBUFFER - SRTU_PROPERTY_RO(srt::CRcvBufferNew*, rcvBuffer, m_pRcvBuffer); -#else - SRTU_PROPERTY_RO(CRcvBuffer*, rcvBuffer, m_pRcvBuffer); -#endif - SRTU_PROPERTY_RO(bool, isTLPktDrop, m_bTLPktDrop); - SRTU_PROPERTY_RO(bool, isSynReceiving, m_config.bSynRecving); - SRTU_PROPERTY_RR(sync::Condition*, recvDataCond, &m_RecvDataCond); - SRTU_PROPERTY_RR(sync::Condition*, recvTsbPdCond, &m_RcvTsbPdCond); - - /// @brief Request a socket to be broken due to too long instability (normally by a group). - void breakAsUnstable() { m_bBreakAsUnstable = true; } - - void ConnectSignal(ETransmissionEvent tev, EventSlot sl); - void DisconnectSignal(ETransmissionEvent tev); - - // This is in public section so prospective overriding it can be - // done by directly assigning to a field. - - typedef std::vector< std::pair > loss_seqs_t; - typedef loss_seqs_t packetArrival_cb(void*, CPacket&); - CallbackHolder m_cbPacketArrival; - -private: - /// initialize a UDT entity and bind to a local address. - - void open(); - - /// Start listening to any connection request. - - void setListenState(); - - /// Connect to a UDT entity listening at address "peer". - /// @param peer [in] The address of the listening UDT entity. - - void startConnect(const sockaddr_any& peer, int32_t forced_isn); - - /// Process the response handshake packet. Failure reasons can be: - /// * Socket is not in connecting state - /// * Response @a pkt is not a handshake control message - /// * Rendezvous socket has once processed a regular handshake - /// @param pkt [in] handshake packet. - /// @retval 0 Connection successful - /// @retval 1 Connection in progress (m_ConnReq turned into RESPONSE) - /// @retval -1 Connection failed - - SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock) - EConnectStatus processConnectResponse(const CPacket& pkt, CUDTException* eout) ATR_NOEXCEPT; - - // This function works in case of HSv5 rendezvous. It changes the state - // according to the present state and received message type, as well as the - // INITIATOR/RESPONDER side resolved through cookieContest(). - // The resulting data are: - // - rsptype: handshake message type that should be sent back to the peer (nothing if URQ_DONE) - // - needs_extension: the HSREQ/KMREQ or HSRSP/KMRSP extensions should be attached to the handshake message. - // - RETURNED VALUE: if true, it means a URQ_CONCLUSION message was received with HSRSP/KMRSP extensions and needs HSRSP/KMRSP. - void rendezvousSwitchState(UDTRequestType& rsptype, bool& needs_extension, bool& needs_hsrsp); - void cookieContest(); - - /// Interpret the incoming handshake packet in order to perform appropriate - /// rendezvous FSM state transition if needed, and craft the response, serialized - /// into the packet to be next sent. - /// @param reqpkt Packet to be written with handshake data - /// @param response incoming handshake response packet to be interpreted - /// @param serv_addr incoming packet's address - /// @param rst Current read status to know if the HS packet was freshly received from the peer, or this is only a periodic update (RST_AGAIN) - SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock) - EConnectStatus processRendezvous(const CPacket* response, const sockaddr_any& serv_addr, EReadStatus, CPacket& reqpkt); - - /// Create the CryptoControl object based on the HS packet. Allocates sender and receiver buffers and loss lists. - SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock) - bool prepareConnectionObjects(const CHandShake &hs, HandshakeSide hsd, CUDTException *eout); - - SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock) - EConnectStatus postConnect(const CPacket* response, bool rendezvous, CUDTException* eout) ATR_NOEXCEPT; - - SRT_ATR_NODISCARD bool applyResponseSettings() ATR_NOEXCEPT; - SRT_ATR_NODISCARD EConnectStatus processAsyncConnectResponse(const CPacket& pkt) ATR_NOEXCEPT; - SRT_ATR_NODISCARD bool processAsyncConnectRequest(EReadStatus rst, EConnectStatus cst, const CPacket* response, const sockaddr_any& serv_addr); - SRT_ATR_NODISCARD EConnectStatus craftKmResponse(uint32_t* aw_kmdata, size_t& w_kmdatasize); - - void checkUpdateCryptoKeyLen(const char* loghdr, int32_t typefield); - - SRT_ATR_NODISCARD size_t fillSrtHandshake_HSREQ(uint32_t* srtdata, size_t srtlen, int hs_version); - SRT_ATR_NODISCARD size_t fillSrtHandshake_HSRSP(uint32_t* srtdata, size_t srtlen, int hs_version); - SRT_ATR_NODISCARD size_t fillSrtHandshake(uint32_t* srtdata, size_t srtlen, int msgtype, int hs_version); - - SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock) - bool createSrtHandshake(int srths_cmd, int srtkm_cmd, const uint32_t* data, size_t datalen, - CPacket& w_reqpkt, CHandShake& w_hs); - - SRT_ATR_NODISCARD size_t fillHsExtConfigString(uint32_t *pcmdspec, int cmd, const std::string &str); -#if ENABLE_BONDING - SRT_ATR_NODISCARD size_t fillHsExtGroup(uint32_t *pcmdspec); -#endif - SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock) - size_t fillHsExtKMREQ(uint32_t *pcmdspec, size_t ki); - - SRT_ATR_NODISCARD size_t fillHsExtKMRSP(uint32_t *pcmdspec, const uint32_t *kmdata, size_t kmdata_wordsize); - - SRT_ATR_NODISCARD size_t prepareSrtHsMsg(int cmd, uint32_t* srtdata, size_t size); - - SRT_ATR_NODISCARD bool processSrtMsg(const CPacket *ctrlpkt); - SRT_ATR_NODISCARD int processSrtMsg_HSREQ(const uint32_t* srtdata, size_t bytelen, uint32_t ts, int hsv); - SRT_ATR_NODISCARD int processSrtMsg_HSRSP(const uint32_t* srtdata, size_t bytelen, uint32_t ts, int hsv); - SRT_ATR_NODISCARD bool interpretSrtHandshake(const CHandShake& hs, const CPacket& hspkt, uint32_t* out_data, size_t* out_len); - SRT_ATR_NODISCARD bool checkApplyFilterConfig(const std::string& cs); - -#if ENABLE_BONDING - static CUDTGroup& newGroup(const int); // defined EXCEPTIONALLY in api.cpp for convenience reasons - // Note: This is an "interpret" function, which should treat the tp as - // "possibly group type" that might be out of the existing values. - SRT_ATR_NODISCARD bool interpretGroup(const int32_t grpdata[], size_t data_size, int hsreq_type_cmd); - SRT_ATR_NODISCARD SRTSOCKET makeMePeerOf(SRTSOCKET peergroup, SRT_GROUP_TYPE tp, uint32_t link_flags); - void synchronizeWithGroup(CUDTGroup* grp); -#endif - - void updateAfterSrtHandshake(int hsv); - - void updateSrtRcvSettings(); - void updateSrtSndSettings(); - - void updateIdleLinkFrom(CUDT* source); - - /// @brief Drop packets too late to be delivered if any. - /// @returns the number of packets actually dropped. - SRT_ATTR_REQUIRES2(m_RecvAckLock, m_StatsLock) - int sndDropTooLate(); - - /// @bried Allow packet retransmission. - /// Depending on the configuration mode (live / file), retransmission - /// can be blocked if e.g. there are original packets pending to be sent. - /// @return true if retransmission is allowed; false otherwise. - bool isRetransmissionAllowed(const time_point& tnow); - - /// Connect to a UDT entity as per hs request. This will update - /// required data in the entity, then update them also in the hs structure, - /// and then send the response back to the caller. - /// @param agent [in] The address to which the UDT entity is bound. - /// @param peer [in] The address of the listening UDT entity. - /// @param hspkt [in] The original packet that brought the handshake. - /// @param hs [in/out] The handshake information sent by the peer side (in), negotiated value (out). - void acceptAndRespond(const sockaddr_any& agent, const sockaddr_any& peer, const CPacket& hspkt, CHandShake& hs); - - /// Write back to the hs structure the data after they have been - /// negotiated by acceptAndRespond. - void rewriteHandshakeData(const sockaddr_any& peer, CHandShake& w_hs); - bool runAcceptHook(CUDT* acore, const sockaddr* peer, const CHandShake& hs, const CPacket& hspkt); - - /// Close the opened UDT entity. - - bool closeInternal(); - void updateBrokenConnection(); - void completeBrokenConnectionDependencies(int errorcode); - - /// Request UDT to send out a data block "data" with size of "len". - /// @param data [in] The address of the application data to be sent. - /// @param len [in] The size of the data block. - /// @return Actual size of data sent. - - SRT_ATR_NODISCARD int send(const char* data, int len) - { - return sendmsg(data, len, SRT_MSGTTL_INF, false, 0); - } - - /// Request UDT to receive data to a memory block "data" with size of "len". - /// @param data [out] data received. - /// @param len [in] The desired size of data to be received. - /// @return Actual size of data received. - - SRT_ATR_NODISCARD int recv(char* data, int len); - - /// send a message of a memory block "data" with size of "len". - /// @param data [out] data received. - /// @param len [in] The desired size of data to be received. - /// @param ttl [in] the time-to-live of the message. - /// @param inorder [in] if the message should be delivered in order. - /// @param srctime [in] Time when the data were ready to send. - /// @return Actual size of data sent. - - SRT_ATR_NODISCARD int sendmsg(const char* data, int len, int ttl, bool inorder, int64_t srctime); - /// Receive a message to buffer "data". - /// @param data [out] data received. - /// @param len [in] size of the buffer. - /// @return Actual size of data received. - - SRT_ATR_NODISCARD int sendmsg2(const char* data, int len, SRT_MSGCTRL& w_m); - - SRT_ATR_NODISCARD int recvmsg(char* data, int len, int64_t& srctime); - SRT_ATR_NODISCARD int recvmsg2(char* data, int len, SRT_MSGCTRL& w_m); - SRT_ATR_NODISCARD int receiveMessage(char* data, int len, SRT_MSGCTRL& w_m, int erh = 1 /*throw exception*/); - SRT_ATR_NODISCARD int receiveBuffer(char* data, int len); - - size_t dropMessage(int32_t seqtoskip); - - /// Request UDT to send out a file described as "fd", starting from "offset", with size of "size". - /// @param ifs [in] The input file stream. - /// @param offset [in, out] From where to read and send data; output is the new offset when the call returns. - /// @param size [in] How many data to be sent. - /// @param block [in] size of block per read from disk - /// @return Actual size of data sent. - - SRT_ATR_NODISCARD int64_t sendfile(std::fstream& ifs, int64_t& offset, int64_t size, int block = 366000); - - /// Request UDT to receive data into a file described as "fd", starting from "offset", with expected size of "size". - /// @param ofs [out] The output file stream. - /// @param offset [in, out] From where to write data; output is the new offset when the call returns. - /// @param size [in] How many data to be received. - /// @param block [in] size of block per write to disk - /// @return Actual size of data received. - - SRT_ATR_NODISCARD int64_t recvfile(std::fstream& ofs, int64_t& offset, int64_t size, int block = 7320000); - - /// Configure UDT options. - /// @param optName [in] The enum name of a UDT option. - /// @param optval [in] The value to be set. - /// @param optlen [in] size of "optval". - - void setOpt(SRT_SOCKOPT optName, const void* optval, int optlen); - - /// Read UDT options. - /// @param optName [in] The enum name of a UDT option. - /// @param optval [in] The value to be returned. - /// @param optlen [out] size of "optval". - - void getOpt(SRT_SOCKOPT optName, void* optval, int& w_optlen); - -#if ENABLE_BONDING - /// Applies the configuration set on the socket. - /// Any errors in this process are reported by exception. - SRT_ERRNO applyMemberConfigObject(const SRT_SocketOptionObject& opt); -#endif - - /// read the performance data with bytes counters since bstats() - /// - /// @param perf [in, out] pointer to a CPerfMon structure to record the performance data. - /// @param clear [in] flag to decide if the local performance trace should be cleared. - /// @param instantaneous [in] flag to request instantaneous data - /// instead of moving averages. - void bstats(CBytePerfMon* perf, bool clear = true, bool instantaneous = false); - - /// Mark sequence contained in the given packet as not lost. This - /// removes the loss record from both current receiver loss list and - /// the receiver fresh loss list. - void unlose(const CPacket& oldpacket); - void dropFromLossLists(int32_t from, int32_t to); - - void checkSndTimers(Whether2RegenKm regen = DONT_REGEN_KM); - void handshakeDone() - { - m_iSndHsRetryCnt = 0; - } - - int64_t withOverhead(int64_t basebw) - { - return (basebw * (100 + m_config.iOverheadBW))/100; - } - - static double Bps2Mbps(int64_t basebw) - { - return double(basebw) * 8.0/1000000.0; - } - - bool stillConnected() - { - // Still connected is when: - // - no "broken" condition appeared (security, protocol error, response timeout) - return !m_bBroken - // - still connected (no one called srt_close()) - && m_bConnected - // - isn't currently closing (srt_close() called, response timeout, shutdown) - && !m_bClosing; - } - - int sndSpaceLeft() - { - return static_cast(sndBuffersLeft() * maxPayloadSize()); - } - - int sndBuffersLeft() - { - return m_config.iSndBufSize - m_pSndBuffer->getCurrBufSize(); - } - - time_point socketStartTime() - { - return m_stats.tsStartTime; - } - - SRT_ATTR_EXCLUDES(m_RcvBufferLock) - bool isRcvBufferReady() const; - - // TSBPD thread main function. - static void* tsbpd(void* param); - -#if ENABLE_NEW_RCVBUFFER - /// Drop too late packets (receiver side). Updaet loss lists and ACK positions. - /// The @a seqno packet itself is not dropped. - /// @param seqno [in] The sequence number of the first packets following those to be dropped. - /// @return The number of packets dropped. - int rcvDropTooLateUpTo(int seqno); -#endif - - void updateForgotten(int seqlen, int32_t lastack, int32_t skiptoseqno); - - static loss_seqs_t defaultPacketArrival(void* vself, CPacket& pkt); - static loss_seqs_t groupPacketArrival(void* vself, CPacket& pkt); - - CRateEstimator getRateEstimator() const - { - if (!m_pSndBuffer) - return CRateEstimator(); - return m_pSndBuffer->getRateEstimator(); - } - - void setRateEstimator(const CRateEstimator& rate) - { - if (!m_pSndBuffer) - return; - - m_pSndBuffer->setRateEstimator(rate); - updateCC(TEV_SYNC, EventVariant(0)); - } - - -private: // Identification - CUDTSocket* const m_parent; // Temporary, until the CUDTSocket class is merged with CUDT - SRTSOCKET m_SocketID; // UDT socket number - SRTSOCKET m_PeerID; // Peer ID, for multiplexer - - // HSv4 (legacy handshake) support) - time_point m_tsSndHsLastTime; // Last SRT handshake request time - int m_iSndHsRetryCnt; // SRT handshake retries left - -#if ENABLE_BONDING - SRT_GROUP_TYPE m_HSGroupType; // Group type about-to-be-set in the handshake -#endif - -private: - int m_iMaxSRTPayloadSize; // Maximum/regular payload size, in bytes - int m_iTsbPdDelay_ms; // Rx delay to absorb burst, in milliseconds - int m_iPeerTsbPdDelay_ms; // Tx delay that the peer uses to absorb burst, in milliseconds - bool m_bTLPktDrop; // Enable Too-late Packet Drop - SRT_ATTR_PT_GUARDED_BY(m_ConnectionLock) - UniquePtr m_pCryptoControl; // Crypto control module - CCache* m_pCache; // Network information cache - - // Congestion control - std::vector m_Slots[TEV_E_SIZE]; - SrtCongestion m_CongCtl; - - // Packet filtering - PacketFilter m_PacketFilter; - SRT_ARQLevel m_PktFilterRexmitLevel; - std::string m_sPeerPktFilterConfigString; - - // Attached tool function - void EmitSignal(ETransmissionEvent tev, EventVariant var); - - // Internal state - sync::atomic m_bListening; // If the UDT entity is listening to connection - sync::atomic m_bConnecting; // The short phase when connect() is called but not yet completed - sync::atomic m_bConnected; // Whether the connection is on or off - sync::atomic m_bClosing; // If the UDT entity is closing - sync::atomic m_bShutdown; // If the peer side has shutdown the connection - sync::atomic m_bBroken; // If the connection has been broken - sync::atomic m_bBreakAsUnstable; // A flag indicating that the socket should become broken because it has been unstable for too long. - sync::atomic m_bPeerHealth; // If the peer status is normal - sync::atomic m_RejectReason; - bool m_bOpened; // If the UDT entity has been opened - // A counter (number of GC checks happening every 1s) to let the GC tag this socket as closed. - sync::atomic m_iBrokenCounter; // If a broken socket still has data in the receiver buffer, it is not marked closed until the counter is 0. - - int m_iEXPCount; // Expiration counter - sync::atomic m_iBandwidth; // Estimated bandwidth, number of packets per second - sync::atomic m_iSRTT; // Smoothed RTT (an exponentially-weighted moving average (EWMA) - // of an endpoint's RTT samples), in microseconds - sync::atomic m_iRTTVar; // The variation in the RTT samples (RTT variance), in microseconds - sync::atomic m_bIsFirstRTTReceived; // True if the first RTT sample was obtained from the ACK/ACKACK pair - // at the receiver side or received by the sender from an ACK packet. - // It's used to reset the initial value of smoothed RTT (m_iSRTT) - // at the beginning of transmission (including the one taken from - // cache). False by default. - sync::atomic m_iDeliveryRate; // Packet arrival rate at the receiver side - sync::atomic m_iByteDeliveryRate; // Byte arrival rate at the receiver side - - CHandShake m_ConnReq; // Connection request - CHandShake m_ConnRes; // Connection response - CHandShake::RendezvousState m_RdvState; // HSv5 rendezvous state - HandshakeSide m_SrtHsSide; // HSv5 rendezvous handshake side resolved from cookie contest (DRAW if not yet resolved) - -private: // Sending related data - CSndBuffer* m_pSndBuffer; // Sender buffer - CSndLossList* m_pSndLossList; // Sender loss list - CPktTimeWindow<16, 16> m_SndTimeWindow; // Packet sending time window - - atomic_duration m_tdSendInterval; // Inter-packet time, in CPU clock cycles - - atomic_duration m_tdSendTimeDiff; // Aggregate difference in inter-packet sending time - - SRT_ATTR_GUARDED_BY(m_RecvAckLock) - sync::atomic m_iFlowWindowSize; // Flow control window size - double m_dCongestionWindow; // Congestion window size - -private: // Timers - atomic_time_point m_tsNextACKTime; // Next ACK time, in CPU clock cycles, same below - atomic_time_point m_tsNextNAKTime; // Next NAK time - - duration m_tdACKInterval; // ACK interval - duration m_tdNAKInterval; // NAK interval - SRT_ATTR_GUARDED_BY(m_RecvAckLock) - atomic_time_point m_tsLastRspTime; // Timestamp of last response from the peer - time_point m_tsLastRspAckTime; // (SND) Timestamp of last ACK from the peer - atomic_time_point m_tsLastSndTime; // Timestamp of last data/ctrl sent (in system ticks) - time_point m_tsLastWarningTime; // Last time that a warning message is sent - atomic_time_point m_tsLastReqTime; // last time when a connection request is sent - time_point m_tsRcvPeerStartTime; - time_point m_tsLingerExpiration; // Linger expiration time (for GC to close a socket with data in sending buffer) - time_point m_tsLastAckTime; // (RCV) Timestamp of last ACK - duration m_tdMinNakInterval; // NAK timeout lower bound; too small value can cause unnecessary retransmission - duration m_tdMinExpInterval; // Timeout lower bound threshold: too small timeout can cause problem - - int m_iPktCount; // Packet counter for ACK - int m_iLightACKCount; // Light ACK counter - - time_point m_tsNextSendTime; // Scheduled time of next packet sending - - sync::atomic m_iSndLastFullAck; // Last full ACK received - SRT_ATTR_GUARDED_BY(m_RecvAckLock) - sync::atomic m_iSndLastAck; // Last ACK received - - // NOTE: m_iSndLastDataAck is the value strictly bound to the CSndBufer object (m_pSndBuffer) - // and this is the sequence number that refers to the block at position [0]. Upon acknowledgement, - // this value is shifted to the acknowledged position, and the blocks are removed from the - // m_pSndBuffer buffer up to excluding this sequence number. - // XXX CONSIDER removing this field and give up the maintenance of this sequence number - // to the sending buffer. This way, extraction of an old packet for retransmission should - // require only the lost sequence number, and how to find the packet with this sequence - // will be up to the sending buffer. - sync::atomic m_iSndLastDataAck; // The real last ACK that updates the sender buffer and loss list - sync::atomic m_iSndCurrSeqNo; // The largest sequence number that HAS BEEN SENT - sync::atomic m_iSndNextSeqNo; // The sequence number predicted to be placed at the currently scheduled packet - - // Note important differences between Curr and Next fields: - // - m_iSndCurrSeqNo: this is used by SRT:SndQ:worker thread and it's operated from CUDT::packData - // function only. This value represents the sequence number that has been stamped on a packet directly - // before it is sent over the network. - // - m_iSndNextSeqNo: this is used by the user's thread and it's operated from CUDT::sendmsg2 - // function only. This value represents the sequence number that is PREDICTED to be stamped on the - // first block out of the block series that will be scheduled for later sending over the network - // out of the data passed in this function. For a special case when the length of the data is - // short enough to be passed in one UDP packet (always the case for live mode), this value is - // always increased by one in this call, otherwise it will be increased by the number of blocks - // scheduled for sending. - - int32_t m_iSndLastAck2; // Last ACK2 sent back - time_point m_SndLastAck2Time; // The time when last ACK2 was sent back - void setInitialSndSeq(int32_t isn) - { - m_iSndLastAck = isn; - m_iSndLastDataAck = isn; - m_iSndLastFullAck = isn; - m_iSndCurrSeqNo = CSeqNo::decseq(isn); - m_iSndNextSeqNo = isn; - m_iSndLastAck2 = isn; - } - - void setInitialRcvSeq(int32_t isn); - - int32_t m_iISN; // Initial Sequence Number - bool m_bPeerTsbPd; // Peer accept TimeStamp-Based Rx mode - bool m_bPeerTLPktDrop; // Enable sender late packet dropping - bool m_bPeerNakReport; // Sender's peer (receiver) issues Periodic NAK Reports - bool m_bPeerRexmitFlag; // Receiver supports rexmit flag in payload packets - - SRT_ATTR_GUARDED_BY(m_RecvAckLock) - int32_t m_iReXmitCount; // Re-Transmit Count since last ACK - -private: // Receiving related data -#if ENABLE_NEW_RCVBUFFER - CRcvBufferNew* m_pRcvBuffer; //< Receiver buffer -#else - CRcvBuffer* m_pRcvBuffer; //< Receiver buffer -#endif - CRcvLossList* m_pRcvLossList; //< Receiver loss list - std::deque m_FreshLoss; //< Lost sequence already added to m_pRcvLossList, but not yet sent UMSG_LOSSREPORT for. - int m_iReorderTolerance; //< Current value of dynamic reorder tolerance - int m_iConsecEarlyDelivery; //< Increases with every OOO packet that came m_ACKWindow; // ACK history window - CPktTimeWindow<16, 64> m_RcvTimeWindow; // Packet arrival time window - - int32_t m_iRcvLastAck; // First unacknowledged packet seqno sent in the latest ACK. -#ifdef ENABLE_LOGGING - int32_t m_iDebugPrevLastAck; -#endif - int32_t m_iRcvLastSkipAck; // Last dropped sequence ACK - int32_t m_iRcvLastAckAck; // (RCV) Latest packet seqno in a sent ACK acknowledged by ACKACK. RcvQTh (sendCtrlAck {r}, processCtrlAckAck {r}, processCtrlAck {r}, connection {w}). - int32_t m_iAckSeqNo; // Last ACK sequence number - sync::atomic m_iRcvCurrSeqNo; // (RCV) Largest received sequence number. RcvQTh, TSBPDTh. - int32_t m_iRcvCurrPhySeqNo; // Same as m_iRcvCurrSeqNo, but physical only (disregarding a filter) - - int32_t m_iPeerISN; // Initial Sequence Number of the peer side - - uint32_t m_uPeerSrtVersion; - uint32_t m_uPeerSrtFlags; - - bool m_bTsbPd; // Peer sends TimeStamp-Based Packet Delivery Packets - bool m_bGroupTsbPd; // TSBPD should be used for GROUP RECEIVER instead - - sync::CThread m_RcvTsbPdThread; // Rcv TsbPD Thread handle - sync::Condition m_RcvTsbPdCond; // TSBPD signals if reading is ready. Use together with m_RecvLock - bool m_bTsbPdAckWakeup; // Signal TsbPd thread on Ack sent - sync::Mutex m_RcvTsbPdStartupLock; // Protects TSBPD thread creating and joining - - CallbackHolder m_cbAcceptHook; - CallbackHolder m_cbConnectHook; - - // FORWARDER -public: - static int installAcceptHook(SRTSOCKET lsn, srt_listen_callback_fn* hook, void* opaq); - static int installConnectHook(SRTSOCKET lsn, srt_connect_callback_fn* hook, void* opaq); -private: - void installAcceptHook(srt_listen_callback_fn* hook, void* opaq) - { - m_cbAcceptHook.set(opaq, hook); - } - - void installConnectHook(srt_connect_callback_fn* hook, void* opaq) - { - m_cbConnectHook.set(opaq, hook); - } - - -private: // synchronization: mutexes and conditions - sync::Mutex m_ConnectionLock; // used to synchronize connection operation - - sync::Condition m_SendBlockCond; // used to block "send" call - sync::Mutex m_SendBlockLock; // lock associated to m_SendBlockCond - - mutable sync::Mutex m_RcvBufferLock; // Protects the state of the m_pRcvBuffer - // Protects access to m_iSndCurrSeqNo, m_iSndLastAck - sync::Mutex m_RecvAckLock; // Protects the state changes while processing incomming ACK (SRT_EPOLL_OUT) - - sync::Condition m_RecvDataCond; // used to block "srt_recv*" when there is no data. Use together with m_RecvLock - sync::Mutex m_RecvLock; // used to synchronize "srt_recv*" call, protects TSBPD drift updates (CRcvBuffer::isRcvDataReady()) - - sync::Mutex m_SendLock; // used to synchronize "send" call - sync::Mutex m_RcvLossLock; // Protects the receiver loss list (access: CRcvQueue::worker, CUDT::tsbpd) - mutable sync::Mutex m_StatsLock; // used to synchronize access to trace statistics - - void initSynch(); - void destroySynch(); - void releaseSynch(); - -private: // Common connection Congestion Control setup - // This can fail only when it failed to create a congctl - // which only may happen when the congctl list is extended - // with user-supplied congctl modules, not a case so far. - SRT_ATR_NODISCARD - SRT_REJECT_REASON setupCC(); - - // for updateCC it's ok to discard the value. This returns false only if - // the congctl isn't created, and this can be prevented from. - bool updateCC(ETransmissionEvent, const EventVariant arg); - - // Failure to create the crypter means that an encrypted - // connection should be rejected if ENFORCEDENCRYPTION is on. - SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock) - bool createCrypter(HandshakeSide side, bool bidi); - -private: // Generation and processing of packets - void sendCtrl(UDTMessageType pkttype, const int32_t* lparam = NULL, void* rparam = NULL, int size = 0); - - /// Forms and sends ACK packet - /// @note Assumes @ctrlpkt already has a timestamp. - /// - /// @param ctrlpkt A control packet structure to fill. It must have a timestemp already set. - /// @param size Sends lite ACK if size is SEND_LITE_ACK, Full ACK otherwise - /// - /// @returns the nmber of packets sent. - int sendCtrlAck(CPacket& ctrlpkt, int size); - void sendLossReport(const std::vector< std::pair >& losslist); - - void processCtrl(const CPacket& ctrlpkt); - - /// @brief Process incoming control ACK packet. - /// @param ctrlpkt incoming ACK packet - /// @param currtime current clock time - void processCtrlAck(const CPacket& ctrlpkt, const time_point& currtime); - - /// @brief Process incoming control ACKACK packet. - /// @param ctrlpkt incoming ACKACK packet - /// @param tsArrival time when packet has arrived (used to calculate RTT) - void processCtrlAckAck(const CPacket& ctrlpkt, const time_point& tsArrival); - - /// @brief Process incoming loss report (NAK) packet. - /// @param ctrlpkt incoming NAK packet - void processCtrlLossReport(const CPacket& ctrlpkt); - - /// @brief Process incoming handshake control packet - /// @param ctrlpkt incoming HS packet - void processCtrlHS(const CPacket& ctrlpkt); - - /// @brief Process incoming drop request control packet - /// @param ctrlpkt incoming drop request packet - void processCtrlDropReq(const CPacket& ctrlpkt); - - /// @brief Process incoming shutdown control packet - void processCtrlShutdown(); - /// @brief Process incoming user defined control packet - /// @param ctrlpkt incoming user defined packet - void processCtrlUserDefined(const CPacket& ctrlpkt); - - /// @brief Update sender's loss list on an incoming acknowledgement. - /// @param ackdata_seqno sequence number of a data packet being acknowledged - void updateSndLossListOnACK(int32_t ackdata_seqno); - - /// Pack a packet from a list of lost packets. - /// - /// @param packet [in, out] a packet structure to fill - /// @param origintime [in, out] origin timestamp of the packet - /// - /// @return payload size on success, <=0 on failure - int packLostData(CPacket &packet, time_point &origintime); - - /// Pack a unique data packet (never sent so far) in CPacket for sending. - /// - /// @param packet [in, out] a CPacket structure to fill. - /// @param origintime [in, out] origin timestamp of the packet. - /// - /// @return true if a packet has been packets; false otherwise. - bool packUniqueData(CPacket& packet, time_point& origintime); - - /// Pack in CPacket the next data to be send. - /// - /// @param packet [in, out] a CPacket structure to fill - /// - /// @return A pair of values is returned (is_payload_valid, timestamp). - /// If is_payload_valid is false, there was nothing packed for sending, - /// and the timestamp value should be ignored. - /// The timestamp is the full source/origin timestamp of the data. - std::pair packData(CPacket& packet); - - int processData(CUnit* unit); - void processClose(); - - /// Process the request after receiving the handshake from caller. - /// The @a packet param is passed here as non-const because this function - /// will need to make a temporary back-and-forth endian swap; it doesn't intend to - /// modify the object permanently. - /// @param addr source address from where the request came - /// @param packet contents of the packet - /// @return URQ code, possibly containing reject reason - int processConnectRequest(const sockaddr_any& addr, CPacket& packet); - static void addLossRecord(std::vector& lossrecord, int32_t lo, int32_t hi); - int32_t bake(const sockaddr_any& addr, int32_t previous_cookie = 0, int correction = 0); - - /// @brief Acknowledge reading position up to the @p seq. - /// Updates m_iRcvLastAck and m_iRcvLastSkipAck to @p seq. - /// @param seq first unacknowledged packet sequence number. - void ackDataUpTo(int32_t seq); - -#if ENABLE_BONDING && ENABLE_NEW_RCVBUFFER - /// @brief Drop packets in the recv buffer behind group_recv_base. - /// Updates m_iRcvLastSkipAck if it's behind group_recv_base. - void dropToGroupRecvBase(); -#endif - - void processKeepalive(const CPacket& ctrlpkt, const time_point& tsArrival); - - /// Locks m_RcvBufferLock and retrieves the available size of the receiver buffer. - SRT_ATTR_EXCLUDES(m_RcvBufferLock) - size_t getAvailRcvBufferSizeLock() const; - - /// Retrieves the available size of the receiver buffer. - /// Expects that m_RcvBufferLock is locked. - SRT_ATTR_REQUIRES(m_RcvBufferLock) - size_t getAvailRcvBufferSizeNoLock() const; - -private: // Trace - struct CoreStats - { - time_point tsStartTime; // timestamp when the UDT entity is started - stats::Sender sndr; // sender statistics - stats::Receiver rcvr; // receiver statistics - - int64_t m_sndDurationTotal; // total real time for sending - - time_point tsLastSampleTime; // last performance sample time - int traceReorderDistance; - double traceBelatedTime; - - int64_t sndDuration; // real time for sending - time_point sndDurationCounter; // timers to record the sending Duration - } m_stats; - -public: - static const int SELF_CLOCK_INTERVAL = 64; // ACK interval for self-clocking - static const int SEND_LITE_ACK = sizeof(int32_t); // special size for ack containing only ack seq - static const int PACKETPAIR_MASK = 0xF; - -private: // Timers functions - time_point m_tsFreshActivation; // GROUPS: time of fresh activation of the link, or 0 if past the activation phase or idle - time_point m_tsUnstableSince; // GROUPS: time since unexpected ACK delay experienced, or 0 if link seems healthy - time_point m_tsWarySince; // GROUPS: time since an unstable link has first some response - - static const int BECAUSE_NO_REASON = 0, // NO BITS - BECAUSE_ACK = 1 << 0, - BECAUSE_LITEACK = 1 << 1, - BECAUSE_NAKREPORT = 1 << 2, - LAST_BECAUSE_BIT = 3; - - void checkTimers(); - void considerLegacySrtHandshake(const time_point &timebase); - int checkACKTimer (const time_point& currtime); - int checkNAKTimer(const time_point& currtime); - bool checkExpTimer (const time_point& currtime, int check_reason); // returns true if the connection is expired - void checkRexmitTimer(const time_point& currtime); - - -private: // for UDP multiplexer - CSndQueue* m_pSndQueue; // packet sending queue - CRcvQueue* m_pRcvQueue; // packet receiving queue - sockaddr_any m_PeerAddr; // peer address - uint32_t m_piSelfIP[4]; // local UDP IP address - CSNode* m_pSNode; // node information for UDT list used in snd queue - CRNode* m_pRNode; // node information for UDT list used in rcv queue - -public: // For SrtCongestion - const CSndQueue* sndQueue() { return m_pSndQueue; } - const CRcvQueue* rcvQueue() { return m_pRcvQueue; } - -private: // for epoll - std::set m_sPollID; // set of epoll ID to trigger - void addEPoll(const int eid); - void removeEPollEvents(const int eid); - void removeEPollID(const int eid); -}; - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/crypto.h b/Vendor/SRT/Includes/crypto.h deleted file mode 100644 index 2c2b35250..000000000 --- a/Vendor/SRT/Includes/crypto.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -written by - Haivision Systems Inc. - *****************************************************************************/ - -#ifndef INC_SRT_CRYPTO_H -#define INC_SRT_CRYPTO_H - -#include -#include - -// UDT -#include "udt.h" -#include "packet.h" -#include "utilities.h" -#include "logging.h" - -#include -#include - - - -namespace srt_logging -{ -std::string KmStateStr(SRT_KM_STATE state); -#if ENABLE_LOGGING -extern Logger cnlog; -#endif -} - -namespace srt -{ -class CUDT; -struct CSrtConfig; - - -// For KMREQ/KMRSP. Only one field is used. -const size_t SRT_KMR_KMSTATE = 0; - -#define SRT_CMD_MAXSZ HCRYPT_MSG_KM_MAX_SZ /* Maximum SRT custom messages payload size (bytes) */ -const size_t SRTDATA_MAXSIZE = SRT_CMD_MAXSZ/sizeof(uint32_t); - -enum Whether2RegenKm {DONT_REGEN_KM = 0, REGEN_KM = 1}; - -class CCryptoControl -{ - SRTSOCKET m_SocketID; - - size_t m_iSndKmKeyLen; //Key length - size_t m_iRcvKmKeyLen; //Key length from rx KM - - // Temporarily allow these to be accessed. -public: - SRT_KM_STATE m_SndKmState; //Sender Km State (imposed by agent) - SRT_KM_STATE m_RcvKmState; //Receiver Km State (informed by peer) - -private: - // Partial haicrypt configuration, consider - // putting the whole HaiCrypt_Cfg object here. - int m_KmRefreshRatePkt; - int m_KmPreAnnouncePkt; - - HaiCrypt_Secret m_KmSecret; //Key material shared secret - // Sender - sync::steady_clock::time_point m_SndKmLastTime; - struct { - unsigned char Msg[HCRYPT_MSG_KM_MAX_SZ]; - size_t MsgLen; - int iPeerRetry; - } m_SndKmMsg[2]; - HaiCrypt_Handle m_hSndCrypto; - // Receiver - HaiCrypt_Handle m_hRcvCrypto; - - bool m_bErrorReported; - -public: - static void globalInit(); - - bool sendingAllowed() - { - // This function is called to state as to whether the - // crypter allows the packet to be sent over the link. - // This is possible in two cases: - // - when Agent didn't set a password, no matter the crypto state - if (m_KmSecret.len == 0) - return true; - // - when Agent did set a password and the crypto state is SECURED. - if (m_KmSecret.len > 0 && m_SndKmState == SRT_KM_S_SECURED - // && m_iRcvPeerKmState == SRT_KM_S_SECURED ? - ) - return true; - - return false; - } - - bool hasPassphrase() const - { - return m_KmSecret.len > 0; - } - -private: -#ifdef SRT_ENABLE_ENCRYPTION - /// Regenerate cryptographic key material. - /// @param[in] sock If not null, the socket will be used to send the KM message to the peer (e.g. KM refresh). - /// @param[in] bidirectional If true, the key material will be regenerated for both directions (receiver and sender). - void regenCryptoKm(CUDT* sock, bool bidirectional); -#endif - -public: - - size_t KeyLen() { return m_iSndKmKeyLen; } - - // Needed for CUDT - void updateKmState(int cmd, size_t srtlen); - - // Detailed processing - int processSrtMsg_KMREQ(const uint32_t* srtdata, size_t len, int hsv, - uint32_t srtdata_out[], size_t&); - - // This returns: - // 1 - the given payload is the same as the currently used key - // 0 - there's no key in agent or the payload is error message with agent NOSECRET. - // -1 - the payload is error message with other state or it doesn't match the key - int processSrtMsg_KMRSP(const uint32_t* srtdata, size_t len, int hsv); - void createFakeSndContext(); - - const unsigned char* getKmMsg_data(size_t ki) const { return m_SndKmMsg[ki].Msg; } - size_t getKmMsg_size(size_t ki) const { return m_SndKmMsg[ki].MsgLen; } - - /// Check if the key stored at @c ki shall be sent. When during the handshake, - /// it only matters if the KM message for that index is recorded at all. - /// Otherwise returns true only if also the retry counter didn't expire. - /// - /// @param ki Key index (0 or 1) - /// @param runtime True, if this happens as a key update - /// during transmission (otherwise it's during the handshake) - /// @return Whether the KM message at given index needs to be sent. - bool getKmMsg_needSend(size_t ki, bool runtime) const - { - if (runtime) - return (m_SndKmMsg[ki].iPeerRetry > 0 && m_SndKmMsg[ki].MsgLen > 0); - else - return m_SndKmMsg[ki].MsgLen > 0; - } - - /// Mark the key as already sent. When no 'runtime' (during the handshake) - /// it actually does nothing so that this will be retried as long as the handshake - /// itself is being retried. Otherwise this is during transmission and will expire - /// after several retries. - /// - /// @param ki Key index (0 or 1) - /// @param runtime True, if this happens as a key update - /// during transmission (otherwise it's during the handshake) - void getKmMsg_markSent(size_t ki, bool runtime) - { -#if ENABLE_LOGGING - using srt_logging::cnlog; -#endif - - m_SndKmLastTime = sync::steady_clock::now(); - if (runtime) - { - m_SndKmMsg[ki].iPeerRetry--; - HLOGC(cnlog.Debug, log << "getKmMsg_markSent: key[" << ki << "]: len=" << m_SndKmMsg[ki].MsgLen << " retry=" << m_SndKmMsg[ki].iPeerRetry); - } - else - { - HLOGC(cnlog.Debug, log << "getKmMsg_markSent: key[" << ki << "]: len=" << m_SndKmMsg[ki].MsgLen << " STILL IN USE."); - } - } - - /// Check if the response returned by KMRSP matches the recorded KM message. - /// When it is, set also the retry counter to 0 to prevent further retries. - /// - /// @param ki KM message index (0 or 1) - /// @param srtmsg Message received through KMRSP - /// @param bytesize Size of the message - /// @return True if the message is identical to the recorded KM message at given index. - bool getKmMsg_acceptResponse(size_t ki, const uint32_t* srtmsg, size_t bytesize) - { - if ( m_SndKmMsg[ki].MsgLen == bytesize - && 0 == memcmp(m_SndKmMsg[ki].Msg, srtmsg, m_SndKmMsg[ki].MsgLen)) - { - m_SndKmMsg[ki].iPeerRetry = 0; - return true; - } - return false; - } - - CCryptoControl(SRTSOCKET id); - - // DEBUG PURPOSES: - std::string CONID() const; - std::string FormatKmMessage(std::string hdr, int cmd, size_t srtlen); - - bool init(HandshakeSide, const CSrtConfig&, bool); - void close(); - - /// @return True if the handshake is in progress. - /// This function is used in: - /// - HSv4 (initial key material exchange - in HSv5 it's attached to handshake) - /// - case of key regeneration, which should be then exchanged again. - void sendKeysToPeer(CUDT* sock, int iSRTT, Whether2RegenKm regen); - - void setCryptoSecret(const HaiCrypt_Secret& secret) - { - m_KmSecret = secret; - } - - void setCryptoKeylen(size_t keylen) - { - m_iSndKmKeyLen = keylen; - m_iRcvKmKeyLen = keylen; - } - - bool createCryptoCtx(size_t keylen, HaiCrypt_CryptoDir tx, HaiCrypt_Handle& rh); - - int getSndCryptoFlags() const - { -#ifdef SRT_ENABLE_ENCRYPTION - return(m_hSndCrypto ? - HaiCrypt_Tx_GetKeyFlags(m_hSndCrypto) : - // When encryption isn't on, check if it was required - // If it was, return -1 as flags, which means that - // encryption was requested and not possible. - hasPassphrase() ? -1 : - 0); -#else - return 0; -#endif - } - - bool isSndEncryptionOK() const - { - // Similar to this above, just quickly check if the encryption - // is required and possible, or not possible - if (!hasPassphrase()) - return true; // no encryption required - - if (m_hSndCrypto) - return true; // encryption is required and possible - - return false; - } - - /// Encrypts the packet. If encryption is not turned on, it - /// does nothing. If the encryption is not correctly configured, - /// the encryption will fail. - /// XXX Encryption flags in the PH_MSGNO - /// field in the header must be correctly set before calling. - EncryptionStatus encrypt(CPacket& w_packet); - - /// Decrypts the packet. If the packet has ENCKEYSPEC part - /// in PH_MSGNO set to EK_NOENC, it does nothing. It decrypts - /// only if the encryption correctly configured, otherwise it - /// fails. After successful decryption, the ENCKEYSPEC part - // in PH_MSGNO is set to EK_NOENC. - EncryptionStatus decrypt(CPacket& w_packet); - - ~CCryptoControl(); -}; - -} // namespace srt - -#endif // SRT_CONGESTION_CONTROL_H diff --git a/Vendor/SRT/Includes/epoll.h b/Vendor/SRT/Includes/epoll.h deleted file mode 100644 index 7b0d941c8..000000000 --- a/Vendor/SRT/Includes/epoll.h +++ /dev/null @@ -1,506 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 08/20/2010 -modified by - Haivision Systems Inc. -*****************************************************************************/ - -#ifndef INC_SRT_EPOLL_H -#define INC_SRT_EPOLL_H - - -#include -#include -#include -#include "udt.h" - -namespace srt -{ - -class CUDT; -class CRendezvousQueue; -class CUDTGroup; - - -class CEPollDesc -{ - const int m_iID; // epoll ID - - struct Wait; - - struct Notice: public SRT_EPOLL_EVENT - { - Wait* parent; - - Notice(Wait* p, SRTSOCKET sock, int ev): parent(p) - { - fd = sock; - events = ev; - } - }; - - /// The type for `m_USockEventNotice`, the pair contains: - /// * The back-pointer to the subscriber object for which this event notice serves - /// * The events currently being on - typedef std::list enotice_t; - - struct Wait - { - /// Events the subscriber is interested with. Only those will be - /// regarded when updating event flags. - int32_t watch; - - /// Which events should be edge-triggered. When the event isn't - /// mentioned in `watch`, this bit flag is disregarded. Otherwise - /// it means that the event is to be waited for persistent state - /// if this flag is not present here, and for edge trigger, if - /// the flag is present here. - int32_t edge; - - /// The current persistent state. This is usually duplicated in - /// a dedicated state object in `m_USockEventNotice`, however the state - /// here will stay forever as is, regardless of the edge/persistent - /// subscription mode for the event. - int32_t state; - - /// The iterator to `m_USockEventNotice` container that contains the - /// event notice object for this subscription, or the value from - /// `nullNotice()` if there is no such object. - enotice_t::iterator notit; - - Wait(explicit_t sub, explicit_t etr, enotice_t::iterator i) - :watch(sub) - ,edge(etr) - ,state(0) - ,notit(i) - { - } - - int edgeOnly() { return edge & watch; } - - /// Clear all flags for given direction from the notices - /// and subscriptions, and checks if this made the event list - /// for this watch completely empty. - /// @param direction event type that has to be cleared - /// @return true, if this cleared the last event (the caller - /// want to remove the subscription for this socket) - bool clear(int32_t direction) - { - if (watch & direction) - { - watch &= ~direction; - edge &= ~direction; - state &= ~direction; - - return watch == 0; - } - - return false; - } - }; - - typedef std::map ewatch_t; - -#if ENABLE_HEAVY_LOGGING -std::string DisplayEpollWatch(); -#endif - - /// Sockets that are subscribed for events in this eid. - ewatch_t m_USockWatchState; - - /// Objects representing changes in SRT sockets. - /// Objects are removed from here when an event is registerred as edge-triggered. - /// Otherwise it is removed only when all events as per subscription - /// are no longer on. - enotice_t m_USockEventNotice; - - // Special behavior - int32_t m_Flags; - - enotice_t::iterator nullNotice() { return m_USockEventNotice.end(); } - - // Only CEPoll class should have access to it. - // Guarding private access to the class is not necessary - // within the epoll module. - friend class CEPoll; - - CEPollDesc(int id, int localID) - : m_iID(id) - , m_Flags(0) - , m_iLocalID(localID) - { - } - - static const int32_t EF_NOCHECK_EMPTY = 1 << 0; - static const int32_t EF_CHECK_REP = 1 << 1; - - int32_t flags() const { return m_Flags; } - bool flags(int32_t f) const { return (m_Flags & f) != 0; } - void set_flags(int32_t flg) { m_Flags |= flg; } - void clr_flags(int32_t flg) { m_Flags &= ~flg; } - - // Container accessors for ewatch_t. - bool watch_empty() const { return m_USockWatchState.empty(); } - Wait* watch_find(SRTSOCKET sock) - { - ewatch_t::iterator i = m_USockWatchState.find(sock); - if (i == m_USockWatchState.end()) - return NULL; - return &i->second; - } - - // Container accessors for enotice_t. - enotice_t::iterator enotice_begin() { return m_USockEventNotice.begin(); } - enotice_t::iterator enotice_end() { return m_USockEventNotice.end(); } - enotice_t::const_iterator enotice_begin() const { return m_USockEventNotice.begin(); } - enotice_t::const_iterator enotice_end() const { return m_USockEventNotice.end(); } - bool enotice_empty() const { return m_USockEventNotice.empty(); } - - const int m_iLocalID; // local system epoll ID - std::set m_sLocals; // set of local (non-UDT) descriptors - - std::pair addWatch(SRTSOCKET sock, explicit_t events, explicit_t et_events) - { - return m_USockWatchState.insert(std::make_pair(sock, Wait(events, et_events, nullNotice()))); - } - - void addEventNotice(Wait& wait, SRTSOCKET sock, int events) - { - // `events` contains bits to be set, so: - // - // 1. If no notice object exists, add it exactly with `events`. - // 2. If it exists, only set the bits from `events`. - // ASSUME: 'events' is not 0, that is, we have some readiness - - if (wait.notit == nullNotice()) // No notice object - { - // Add new event notice and bind to the wait object. - m_USockEventNotice.push_back(Notice(&wait, sock, events)); - wait.notit = --m_USockEventNotice.end(); - - return; - } - - // We have an existing event notice, so update it - wait.notit->events |= events; - } - - // This function only updates the corresponding event notice object - // according to the change in the events. - void updateEventNotice(Wait& wait, SRTSOCKET sock, int events, bool enable) - { - if (enable) - { - addEventNotice(wait, sock, events); - } - else - { - removeExcessEvents(wait, ~events); - } - } - - void removeSubscription(SRTSOCKET u) - { - std::map::iterator i = m_USockWatchState.find(u); - if (i == m_USockWatchState.end()) - return; - - if (i->second.notit != nullNotice()) - { - m_USockEventNotice.erase(i->second.notit); - // NOTE: no need to update the Wait::notit field - // because the Wait object is about to be removed anyway. - } - m_USockWatchState.erase(i); - } - - void clearAll() - { - m_USockEventNotice.clear(); - m_USockWatchState.clear(); - } - - void removeExistingNotices(Wait& wait) - { - m_USockEventNotice.erase(wait.notit); - wait.notit = nullNotice(); - } - - void removeEvents(Wait& wait) - { - if (wait.notit == nullNotice()) - return; - removeExistingNotices(wait); - } - - // This function removes notices referring to - // events that are NOT present in @a nevts, but - // may be among subscriptions and therefore potentially - // have an associated notice. - void removeExcessEvents(Wait& wait, int nevts) - { - // Update the event notice, should it exist - // If the watch points to a null notice, there's simply - // no notice there, so nothing to update or prospectively - // remove - but may be something to add. - if (wait.notit == nullNotice()) - return; - - // `events` contains bits to be cleared. - // 1. If there is no notice event, do nothing - clear already. - // 2. If there is a notice event, update by clearing the bits - // 2.1. If this made resulting state to be 0, also remove the notice. - - const int newstate = wait.notit->events & nevts; - if (newstate) - { - wait.notit->events = newstate; - } - else - { - // If the new state is full 0 (no events), - // then remove the corresponding notice object - removeExistingNotices(wait); - } - } - - bool checkEdge(enotice_t::iterator i) - { - // This function should check if this event was subscribed - // as edge-triggered, and if so, clear the event from the notice. - // Update events and check edge mode at the subscriber - i->events &= ~i->parent->edgeOnly(); - if(!i->events) - { - removeExistingNotices(*i->parent); - return true; - } - return false; - } - - /// This should work in a loop around the notice container of - /// the given eid container and clear out the notice for - /// particular event type. If this has cleared effectively the - /// last existing event, it should return the socket id - /// so that the caller knows to remove it also from subscribers. - /// - /// @param i iterator in the notice container - /// @param event event type to be cleared - /// @retval (socket) Socket to be removed from subscriptions - /// @retval SRT_INVALID_SOCK Nothing to be done (associated socket - /// still has other subscriptions) - SRTSOCKET clearEventSub(enotice_t::iterator i, int event) - { - // We need to remove the notice and subscription - // for this event. The 'i' iterator is safe to - // delete, even indirectly. - - // This works merely like checkEdge, just on request to clear the - // identified event, if found. - if (i->events & event) - { - // The notice has a readiness flag on this event. - // This means that there exists also a subscription. - Wait* w = i->parent; - if (w->clear(event)) - return i->fd; - } - - return SRT_INVALID_SOCK; - } -}; - -class CEPoll -{ -friend class srt::CUDT; -friend class srt::CUDTGroup; -friend class srt::CRendezvousQueue; - -public: - CEPoll(); - ~CEPoll(); - -public: // for CUDTUnited API - - /// create a new EPoll. - /// @return new EPoll ID if success, otherwise an error number. - int create(CEPollDesc** ppd = 0); - - - /// delete all user sockets (SRT sockets) from an EPoll - /// @param [in] eid EPoll ID. - /// @return 0 - int clear_usocks(int eid); - - /// add a system socket to an EPoll. - /// @param [in] eid EPoll ID. - /// @param [in] s system Socket ID. - /// @param [in] events events to watch. - /// @return 0 if success, otherwise an error number. - - int add_ssock(const int eid, const SYSSOCKET& s, const int* events = NULL); - - /// remove a system socket event from an EPoll; socket will be removed if no events to watch. - /// @param [in] eid EPoll ID. - /// @param [in] s system socket ID. - /// @return 0 if success, otherwise an error number. - - int remove_ssock(const int eid, const SYSSOCKET& s); - /// update a UDT socket events from an EPoll. - /// @param [in] eid EPoll ID. - /// @param [in] u UDT socket ID. - /// @param [in] events events to watch. - /// @return 0 if success, otherwise an error number. - - int update_usock(const int eid, const SRTSOCKET& u, const int* events); - - /// update a system socket events from an EPoll. - /// @param [in] eid EPoll ID. - /// @param [in] u UDT socket ID. - /// @param [in] events events to watch. - /// @return 0 if success, otherwise an error number. - - int update_ssock(const int eid, const SYSSOCKET& s, const int* events = NULL); - - /// wait for EPoll events or timeout. - /// @param [in] eid EPoll ID. - /// @param [out] readfds UDT sockets available for reading. - /// @param [out] writefds UDT sockets available for writing. - /// @param [in] msTimeOut timeout threshold, in milliseconds. - /// @param [out] lrfds system file descriptors for reading. - /// @param [out] lwfds system file descriptors for writing. - /// @return number of sockets available for IO. - - int wait(const int eid, std::set* readfds, std::set* writefds, int64_t msTimeOut, std::set* lrfds, std::set* lwfds); - - typedef std::map fmap_t; - - /// Lightweit and more internal-reaching version of `uwait` for internal use only. - /// This function wait for sockets to be ready and reports them in `st` map. - /// - /// @param d the internal structure of the epoll container - /// @param st output container for the results: { socket_type, event } - /// @param msTimeOut timeout after which return with empty output is allowed - /// @param report_by_exception if true, errors will result in exception intead of returning -1 - /// @retval -1 error occurred - /// @retval >=0 number of ready sockets (actually size of `st`) - int swait(CEPollDesc& d, fmap_t& st, int64_t msTimeOut, bool report_by_exception = true); - - /// Empty subscription check - for internal use only. - bool empty(const CEPollDesc& d) const; - - /// Reports which events are ready on the given socket. - /// @param mp socket event map retirned by `swait` - /// @param sock which socket to ask - /// @return event flags for given socket, or 0 if none - static int ready(const fmap_t& mp, SRTSOCKET sock) - { - fmap_t::const_iterator y = mp.find(sock); - if (y == mp.end()) - return 0; - return y->second; - } - - /// Reports whether socket is ready for given event. - /// @param mp socket event map retirned by `swait` - /// @param sock which socket to ask - /// @param event which events it should be ready for - /// @return true if the given socket is ready for given event - static bool isready(const fmap_t& mp, SRTSOCKET sock, SRT_EPOLL_OPT event) - { - return (ready(mp, sock) & event) != 0; - } - - // Could be a template directly, but it's now hidden in the imp file. - void clear_ready_usocks(CEPollDesc& d, int direction); - - /// wait for EPoll events or timeout optimized with explicit EPOLL_ERR event and the edge mode option. - /// @param [in] eid EPoll ID. - /// @param [out] fdsSet array of user socket events (SRT_EPOLL_IN | SRT_EPOLL_OUT | SRT_EPOLL_ERR). - /// @param [int] fdsSize of fds array - /// @param [in] msTimeOut timeout threshold, in milliseconds. - /// @return total of available events in the epoll system (can be greater than fdsSize) - - int uwait(const int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut); - - /// close and release an EPoll. - /// @param [in] eid EPoll ID. - /// @return 0 if success, otherwise an error number. - - int release(const int eid); - -public: // for CUDT to acknowledge IO status - - /// Update events available for a UDT socket. At the end this function - /// counts the number of updated EIDs with given events. - /// @param [in] uid UDT socket ID. - /// @param [in] eids EPoll IDs to be set - /// @param [in] events Combination of events to update - /// @param [in] enable true -> enable, otherwise disable - /// @return -1 if invalid events, otherwise the number of changes - - int update_events(const SRTSOCKET& uid, std::set& eids, int events, bool enable); - - int setflags(const int eid, int32_t flags); - -private: - int m_iIDSeed; // seed to generate a new ID - srt::sync::Mutex m_SeedLock; - - std::map m_mPolls; // all epolls - mutable srt::sync::Mutex m_EPollLock; -}; - -#if ENABLE_HEAVY_LOGGING -std::string DisplayEpollResults(const std::map& sockset); -#endif - -} // namespace srt - - -#endif diff --git a/Vendor/SRT/Includes/fec.h b/Vendor/SRT/Includes/fec.h deleted file mode 100644 index 71a6adfa7..000000000 --- a/Vendor/SRT/Includes/fec.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * SRT - Secure, Reliable, Transport - * Copyright (c) 2019 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/. - * - */ - - -#ifndef INC_SRT_FEC_H -#define INC_SRT_FEC_H - -#include -#include -#include -#include - -#include "packetfilter_api.h" - -namespace srt { - -class FECFilterBuiltin: public SrtPacketFilterBase -{ - SrtFilterConfig cfg; - size_t m_number_cols; - size_t m_number_rows; - - // Configuration - SRT_ARQLevel m_fallback_level; - bool m_cols_only; - bool m_arrangement_staircase; - -public: - - size_t numberCols() const { return m_number_cols; } - size_t numberRows() const { return m_number_rows; } - - size_t sizeCol() const { return m_number_rows; } - size_t sizeRow() const { return m_number_cols; } - - struct Group - { - int32_t base; //< Sequence of the first packet in the group - size_t step; //< by how many packets the sequence should increase to get the next packet - size_t drop; //< by how much the sequence should increase to get to the next series - size_t collected; //< how many packets were taken to collect the clip - - Group(): base(CSeqNo::m_iMaxSeqNo), step(0), drop(0), collected(0) - { - } - - uint16_t length_clip; - uint8_t flag_clip; - uint32_t timestamp_clip; - std::vector payload_clip; - - // This is mutable because it's an intermediate buffer for - // the purpose of output. - //mutable vector output_buffer; - - enum Type - { - HORIZ, // Horizontal, recursive - VERT, // Vertical, recursive - - // NOTE: HORIZ/VERT are defined as 0/1 so that not-inversion - // can flip between them. - SINGLE // Horizontal-only with no recursion - }; - - static Type FlipType(Type t) - { - SRT_ASSERT(t != SINGLE); - return (t == HORIZ) ? VERT : HORIZ; - } - - }; - - struct RcvGroup: Group - { - bool fec; - bool dismissed; - RcvGroup(): fec(false), dismissed(false) {} - -#if ENABLE_HEAVY_LOGGING - std::string DisplayStats() - { - if (base == CSeqNo::m_iMaxSeqNo) - return "UNINITIALIZED!!!"; - - std::ostringstream os; - os << "base=" << base << " step=" << step << " drop=" << drop << " collected=" << collected - << " " << (fec ? "+" : "-") << "FEC " << (dismissed ? "DISMISSED" : "active"); - return os.str(); - } -#endif - }; - -private: - - // Row Groups: every item represents a single row group and collects clips for one row. - // Col Groups: every item represents a signel column group and collect clips for packets represented in one column - - struct Send - { - // We need only ONE horizontal group. Simply after the group - // is closed (last packet supplied), and the FEC packet extracted, - // the group is no longer in use. - Group row; - std::vector cols; - } snd; - - struct Receive - { - SRTSOCKET id; - bool order_required; - - Receive(std::vector& provided): id(SRT_INVALID_SOCK), order_required(false), rebuilt(provided) - { - } - - // In reception we need to keep as many horizontal groups as required - // for possible later tracking. A horizontal group should be dismissed - // when the size of this container exceeds the `m_number_rows` (size of the column). - // - // The 'std::deque' type is used here for a trial implementation. A desired solution - // would be a kind of a ring buffer where new groups are added and old (exceeding - // the size) automatically dismissed. - std::deque rowq; - - // Base index at the oldest column platform determines - // the base index of the queue. Meaning, first you need - // to determnine the column index, where the index 0 is - // the fistmost element of this queue. After determining - // the column index, there must be also a second factor - // deteremined - which column series it is. So, this can - // start by extracting the base sequence of the element - // at the index column. This is the series 0. Now, the - // distance between these two sequences, divided by - // rowsize*colsize should return %index-in-column, - // /number-series. The latter multiplied by the row size - // is the offset between the firstmost column and the - // searched column. - std::deque colq; - - // This keeps the value of "packet received or not". - // The sequence number of the first cell is rowq[0].base. - // When dropping a row, - // - the firstmost element of rowq is removed - // - the length of one row is removed from this std::vector - int32_t cell_base; - std::deque cells; - - // Note this function will automatically extend the container - // with empty cells if the index exceeds the size, HOWEVER - // the caller must make sure that this index isn't any "crazy", - // that is, it fits somehow in reasonable ranges. - bool CellAt(size_t index) - { - if (index >= cells.size()) - { - // Cells not prepared for this sequence yet, - // so extend in advance. - cells.resize(index+1, false); - return false; // It wasn't marked, anyway. - } - - return cells[index]; - } - - typedef SrtPacket PrivPacket; - std::vector& rebuilt; - } rcv; - - void ConfigureGroup(Group& g, int32_t seqno, size_t gstep, size_t drop); - template - void ConfigureColumns(Container& which, int32_t isn); - - void ResetGroup(Group& g); - - // Universal - void ClipData(Group& g, uint16_t length_net, uint8_t kflg, - uint32_t timestamp_hw, const char* payload, size_t payload_size); - void ClipPacket(Group& g, const CPacket& pkt); - - // Sending - bool CheckGroupClose(Group& g, size_t pos, size_t size); - void PackControl(const Group& g, signed char groupix, SrtPacket& pkt, int32_t seqno); - - // Receiving - void CheckLargeDrop(int32_t seqno); - size_t ExtendRows(size_t rowx); - size_t ExtendColumns(size_t colgx); - - enum ECellReceived - { - CELL_RECEIVED, //< mark cell for a received packet (no matter current value) - CELL_EXTEND, //< just make sure there's a place for a packet, set false if not - CELL_REMOVE //< even if a packet was marked true, remove the cell existence confirmation - }; - void MarkCellReceived(int32_t seq, ECellReceived recv = CELL_RECEIVED); - - enum EHangStatus - { - HANG_NOTDONE, - HANG_SUCCESS, - HANG_PAST, - HANG_CRAZY - }; - - friend bool operator <(FECFilterBuiltin::EHangStatus a, FECFilterBuiltin::EHangStatus b) - { - return int(a) < int(b); - } - - EHangStatus HangHorizontal(const CPacket& pkt, bool fec_ctl, loss_seqs_t& irrecover); - EHangStatus HangVertical(const CPacket& pkt, signed char fec_colx, loss_seqs_t& irrecover); - void ClipControlPacket(Group& g, const CPacket& pkt); - void ClipRebuiltPacket(Group& g, Receive::PrivPacket& pkt); - void RcvRebuild(Group& g, int32_t seqno, Group::Type tp); - int32_t RcvGetLossSeqHoriz(Group& g); - int32_t RcvGetLossSeqVert(Group& g); - void EmergencyShrink(size_t n_series); - - static void TranslateLossRecords(const std::set& loss, loss_seqs_t& irrecover); - void RcvCheckDismissColumn(int32_t seqno, int colgx, loss_seqs_t& irrecover); - int RcvGetRowGroupIndex(int32_t seq, EHangStatus& w_status); - int RcvGetColumnGroupIndex(int32_t seqno, EHangStatus& w_status); - void CollectIrrecoverRow(RcvGroup& g, loss_seqs_t& irrecover) const; - bool IsLost(int32_t seq) const; - -public: - - FECFilterBuiltin(const SrtFilterInitializer& init, std::vector& provided, const std::string& confstr); - - // Sender side - - // This function creates and stores the FEC control packet with - // a prediction to be immediately sent. This is called in the function - // that normally is prepared for extracting a data packet from the sender - // buffer and send it over the channel. - virtual bool packControlPacket(SrtPacket& r_packet, int32_t seq) ATR_OVERRIDE; - - // This is called at the moment when the sender queue decided to pick up - // a new packet from the scheduled packets. This should be then used to - // continue filling the group, possibly followed by final calculating the - // FEC control packet ready to send. - virtual void feedSource(CPacket& r_packet) ATR_OVERRIDE; - - // Receiver side - - // This function is called at the moment when a new data packet has - // arrived (no matter if subsequent or recovered). The 'state' value - // defines the configured level of loss state required to send the - // loss report. - virtual bool receive(const CPacket& pkt, loss_seqs_t& loss_seqs) ATR_OVERRIDE; - - // Configuration - - // This is the size that is needed extra by packets operated by this corrector. - // It should be subtracted from a current maximum value for SRTO_PAYLOADSIZE - - // The default FEC uses extra space only for FEC/CTL packet. - // The timestamp clip is placed in the timestamp field in the header. - // The payload contains: - // - the length clip - // - the flag spec - // - the payload clip - // The payload clip takes simply the current length of SRTO_PAYLOADSIZE. - // So extra 4 bytes are needed, 2 for flags, 2 for length clip. - static const size_t EXTRA_SIZE = 4; - - virtual SRT_ARQLevel arqLevel() ATR_OVERRIDE { return m_fallback_level; } - - static const char defaultConfig []; - static bool verifyConfig(const SrtFilterConfig& config, std::string& w_errormsg); -}; - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/group.h b/Vendor/SRT/Includes/group.h deleted file mode 100644 index 1bd84aeda..000000000 --- a/Vendor/SRT/Includes/group.h +++ /dev/null @@ -1,822 +0,0 @@ -/* - * SRT - Secure, Reliable, Transport - * Copyright (c) 2020 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/. - * - */ - -/***************************************************************************** -Written by - Haivision Systems Inc. -*****************************************************************************/ - -#ifndef INC_SRT_GROUP_H -#define INC_SRT_GROUP_H - -#include "srt.h" -#include "common.h" -#include "packet.h" -#include "group_common.h" -#include "group_backup.h" - -namespace srt -{ - -#if ENABLE_HEAVY_LOGGING -const char* const srt_log_grp_state[] = {"PENDING", "IDLE", "RUNNING", "BROKEN"}; -#endif - - -class CUDTGroup -{ - friend class CUDTUnited; - - typedef sync::steady_clock::time_point time_point; - typedef sync::steady_clock::duration duration; - typedef sync::steady_clock steady_clock; - typedef groups::SocketData SocketData; - typedef groups::SendBackupCtx SendBackupCtx; - typedef groups::BackupMemberState BackupMemberState; - -public: - typedef SRT_MEMBERSTATUS GroupState; - - // Note that the use of states may differ in particular group types: - // - // Broadcast: links that are freshly connected become PENDING and then IDLE only - // for a short moment to be activated immediately at the nearest sending operation. - // - // Balancing: like with broadcast, just that the link activation gets its shared percentage - // of traffic balancing - // - // Multicast: The link is never idle. The data are always sent over the UDP multicast link - // and the receiver simply gets subscribed and reads packets once it's ready. - // - // Backup: The link stays idle until it's activated, and the activation can only happen - // at the moment when the currently active link is "suspected of being likely broken" - // (the current active link fails to receive ACK in a time when two ACKs should already - // be received). After a while when the current active link is confirmed broken, it turns - // into broken state. - - static const char* StateStr(GroupState); - - static int32_t s_tokenGen; - static int32_t genToken() { ++s_tokenGen; if (s_tokenGen < 0) s_tokenGen = 0; return s_tokenGen;} - - struct ConfigItem - { - SRT_SOCKOPT so; - std::vector value; - - template - bool get(T& refr) - { - if (sizeof(T) > value.size()) - return false; - refr = *(T*)&value[0]; - return true; - } - - ConfigItem(SRT_SOCKOPT o, const void* val, int size) - : so(o) - { - value.resize(size); - unsigned char* begin = (unsigned char*)val; - std::copy(begin, begin + size, value.begin()); - } - - struct OfType - { - SRT_SOCKOPT so; - OfType(SRT_SOCKOPT soso) - : so(soso) - { - } - bool operator()(ConfigItem& ci) { return ci.so == so; } - }; - }; - - typedef std::list group_t; - typedef group_t::iterator gli_t; - typedef std::vector< std::pair > sendable_t; - - struct Sendstate - { - SRTSOCKET id; - SocketData* mb; - int stat; - int code; - }; - - CUDTGroup(SRT_GROUP_TYPE); - ~CUDTGroup(); - - SocketData* add(SocketData data); - - struct HaveID - { - SRTSOCKET id; - HaveID(SRTSOCKET sid) - : id(sid) - { - } - bool operator()(const SocketData& s) { return s.id == id; } - }; - - bool contains(SRTSOCKET id, SocketData*& w_f) - { - srt::sync::ScopedLock g(m_GroupLock); - gli_t f = std::find_if(m_Group.begin(), m_Group.end(), HaveID(id)); - if (f == m_Group.end()) - { - w_f = NULL; - return false; - } - w_f = &*f; - return true; - } - - // NEED LOCKING - gli_t begin() { return m_Group.begin(); } - gli_t end() { return m_Group.end(); } - - /// Remove the socket from the group container. - /// REMEMBER: the group spec should be taken from the socket - /// (set m_GroupOf and m_GroupMemberData to NULL - /// PRIOR TO calling this function. - /// @param id Socket ID to look for in the container to remove - /// @return true if the container still contains any sockets after the operation - bool remove(SRTSOCKET id) - { - using srt_logging::gmlog; - srt::sync::ScopedLock g(m_GroupLock); - - bool empty = false; - HLOGC(gmlog.Debug, log << "group/remove: going to remove @" << id << " from $" << m_GroupID); - - gli_t f = std::find_if(m_Group.begin(), m_Group.end(), HaveID(id)); - if (f != m_Group.end()) - { - m_Group.erase(f); - - // Reset sequence numbers on a dead group so that they are - // initialized anew with the new alive connection within - // the group. - // XXX The problem is that this should be done after the - // socket is considered DISCONNECTED, not when it's being - // closed. After being disconnected, the sequence numbers - // are no longer valid, and will be reinitialized when the - // socket is connected again. This may stay as is for now - // as in SRT it's not predicted to do anything with the socket - // that was disconnected other than immediately closing it. - if (m_Group.empty()) - { - // When the group is empty, there's no danger that this - // number will collide with any ISN provided by a socket. - // Also since now every socket will derive this ISN. - m_iLastSchedSeqNo = generateISN(); - resetInitialRxSequence(); - empty = true; - } - } - else - { - HLOGC(gmlog.Debug, log << "group/remove: IPE: id @" << id << " NOT FOUND"); - empty = true; // not exactly true, but this is to cause error on group in the APP - } - - if (m_Group.empty()) - { - m_bOpened = false; - m_bConnected = false; - } - - // XXX BUGFIX - m_Positions.erase(id); - - return !empty; - } - - bool groupEmpty() - { - srt::sync::ScopedLock g(m_GroupLock); - return m_Group.empty(); - } - - void setGroupConnected(); - - int send(const char* buf, int len, SRT_MSGCTRL& w_mc); - int sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc); - int sendBackup(const char* buf, int len, SRT_MSGCTRL& w_mc); - static int32_t generateISN(); - -private: - // For Backup, sending all previous packet - int sendBackupRexmit(srt::CUDT& core, SRT_MSGCTRL& w_mc); - - // Support functions for sendBackup and sendBroadcast - /// Check if group member is idle. - /// @param d group member - /// @param[in,out] w_wipeme array of sockets to remove from group - /// @param[in,out] w_pendingLinks array of sockets pending for connection - /// @returns true if d is idle (standby), false otherwise - bool send_CheckIdle(const gli_t d, std::vector& w_wipeme, std::vector& w_pendingLinks); - - - /// This function checks if the member has just become idle (check if sender buffer is empty) to send a KEEPALIVE immidiatelly. - /// @todo Check it is some abandoned logic. - void sendBackup_CheckIdleTime(gli_t w_d); - - /// Qualify states of member links. - /// [[using locked(this->m_GroupLock, m_pGlobal->m_GlobControlLock)]] - /// @param[out] w_sendBackupCtx the context will be updated with state qualifications - /// @param[in] currtime current timestamp - void sendBackup_QualifyMemberStates(SendBackupCtx& w_sendBackupCtx, const steady_clock::time_point& currtime); - - void sendBackup_AssignBackupState(srt::CUDT& socket, BackupMemberState state, const steady_clock::time_point& currtime); - - /// Qualify the state of the active link: fresh, stable, unstable, wary. - /// @retval active backup member state: fresh, stable, unstable, wary. - BackupMemberState sendBackup_QualifyActiveState(const gli_t d, const time_point currtime); - - BackupMemberState sendBackup_QualifyIfStandBy(const gli_t d); - - /// Sends the same payload over all active members. - /// @param[in] buf payload - /// @param[in] len payload length in bytes - /// @param[in,out] w_mc message control - /// @param[in] currtime current time - /// @param[in] currseq current packet sequence number - /// @param[out] w_nsuccessful number of members with successfull sending. - /// @param[in,out] maxActiveWeight - /// @param[in,out] sendBackupCtx context - /// @param[in,out] w_cx error - /// @return group send result: -1 if sending over all members has failed; number of bytes sent overwise. - int sendBackup_SendOverActive(const char* buf, int len, SRT_MSGCTRL& w_mc, const steady_clock::time_point& currtime, int32_t& w_curseq, - size_t& w_nsuccessful, uint16_t& w_maxActiveWeight, SendBackupCtx& w_sendBackupCtx, CUDTException& w_cx); - - /// Check link sending status - /// @param[in] currtime Current time (logging only) - /// @param[in] send_status Result of sending over the socket - /// @param[in] lastseq Last sent sequence number before the current sending operation - /// @param[in] pktseq Packet sequence number currently tried to be sent - /// @param[out] w_u CUDT unit of the current member (to allow calling overrideSndSeqNo) - /// @param[out] w_curseq Group's current sequence number (either -1 or the value used already for other links) - /// @param[out] w_final_stat w_final_stat = send_status if sending succeded. - /// - /// @returns true if the sending operation result (submitted in stat) is a success, false otherwise. - bool sendBackup_CheckSendStatus(const time_point& currtime, - const int send_status, - const int32_t lastseq, - const int32_t pktseq, - CUDT& w_u, - int32_t& w_curseq, - int& w_final_stat); - void sendBackup_Buffering(const char* buf, const int len, int32_t& curseq, SRT_MSGCTRL& w_mc); - - size_t sendBackup_TryActivateStandbyIfNeeded( - const char* buf, - const int len, - bool& w_none_succeeded, - SRT_MSGCTRL& w_mc, - int32_t& w_curseq, - int32_t& w_final_stat, - SendBackupCtx& w_sendBackupCtx, - CUDTException& w_cx, - const steady_clock::time_point& currtime); - - /// Check if pending sockets are to be qualified as broken. - /// This qualification later results in removing the socket from a group and closing it. - /// @param[in,out] a context with a list of member sockets, some pending might qualified broken - void sendBackup_CheckPendingSockets(SendBackupCtx& w_sendBackupCtx, const steady_clock::time_point& currtime); - - /// Check if unstable sockets are to be qualified as broken. - /// The main reason for such qualification is if a socket is unstable for too long. - /// This qualification later results in removing the socket from a group and closing it. - /// @param[in,out] a context with a list of member sockets, some pending might qualified broken - void sendBackup_CheckUnstableSockets(SendBackupCtx& w_sendBackupCtx, const steady_clock::time_point& currtime); - - /// @brief Marks broken sockets as closed. Used in broadcast sending. - /// @param w_wipeme a list of sockets to close - void send_CloseBrokenSockets(std::vector& w_wipeme); - - /// @brief Marks broken sockets as closed. Used in backup sending. - /// @param w_sendBackupCtx the context with a list of broken sockets - void sendBackup_CloseBrokenSockets(SendBackupCtx& w_sendBackupCtx); - - void sendBackup_RetryWaitBlocked(SendBackupCtx& w_sendBackupCtx, - int& w_final_stat, - bool& w_none_succeeded, - SRT_MSGCTRL& w_mc, - CUDTException& w_cx); - void sendBackup_SilenceRedundantLinks(SendBackupCtx& w_sendBackupCtx, const steady_clock::time_point& currtime); - - void send_CheckValidSockets(); - -public: - int recv(char* buf, int len, SRT_MSGCTRL& w_mc); - - void close(); - - void setOpt(SRT_SOCKOPT optname, const void* optval, int optlen); - void getOpt(SRT_SOCKOPT optName, void* optval, int& w_optlen); - void deriveSettings(srt::CUDT* source); - bool applyFlags(uint32_t flags, HandshakeSide); - - SRT_SOCKSTATUS getStatus(); - - void debugMasterData(SRTSOCKET slave); - - bool isGroupReceiver() - { - // XXX add here also other group types, which - // predict group receiving. - return m_type == SRT_GTYPE_BROADCAST; - } - - sync::Mutex* exp_groupLock() { return &m_GroupLock; } - void addEPoll(int eid); - void removeEPollEvents(const int eid); - void removeEPollID(const int eid); - - /// @brief Update read-ready state. - /// @param sock member socket ID (unused) - /// @param sequence the latest packet sequence number available for reading. - void updateReadState(SRTSOCKET sock, int32_t sequence); - - void updateWriteState(); - void updateFailedLink(); - void activateUpdateEvent(bool still_have_items); - int32_t getRcvBaseSeqNo(); - - /// Update the in-group array of packet providers per sequence number. - /// Also basing on the information already provided by possibly other sockets, - /// report the real status of packet loss, including packets maybe lost - /// by the caller provider, but already received from elsewhere. Note that - /// these packets are not ready for extraction until ACK-ed. - /// - /// @param exp_sequence The previously received sequence at this socket - /// @param sequence The sequence of this packet - /// @param provider The core of the socket for which the packet was dispatched - /// @param time TSBPD time of this packet - /// @return The bitmap that marks by 'false' packets lost since next to exp_sequence - std::vector providePacket(int32_t exp_sequence, int32_t sequence, srt::CUDT* provider, uint64_t time); - - /// This is called from the ACK action by particular socket, which - /// actually signs off the packet for extraction. - /// - /// @param core The socket core for which the ACK was sent - /// @param ack The past-the-last-received ACK sequence number - void readyPackets(srt::CUDT* core, int32_t ack); - - void syncWithSocket(const srt::CUDT& core, const HandshakeSide side); - int getGroupData(SRT_SOCKGROUPDATA* pdata, size_t* psize); - int getGroupData_LOCKED(SRT_SOCKGROUPDATA* pdata, size_t* psize); - - /// Predicted to be called from the reading function to fill - /// the group data array as requested. - void fillGroupData(SRT_MSGCTRL& w_out, //< MSGCTRL to be written - const SRT_MSGCTRL& in //< MSGCTRL read from the data-providing socket - ); - - void copyGroupData(const CUDTGroup::SocketData& source, SRT_SOCKGROUPDATA& w_target); - -#if ENABLE_HEAVY_LOGGING - void debugGroup(); -#else - void debugGroup() {} -#endif - - void ackMessage(int32_t msgno); - void processKeepalive(SocketData*); - void internalKeepalive(SocketData*); - -private: - // Check if there's at least one connected socket. - // If so, grab the status of all member sockets. - void getGroupCount(size_t& w_size, bool& w_still_alive); - - srt::CUDTUnited& m_Global; - srt::sync::Mutex m_GroupLock; - - SRTSOCKET m_GroupID; - SRTSOCKET m_PeerGroupID; - struct GroupContainer - { - std::list m_List; - - /// This field is used only by some types of groups that need - /// to keep track as to which link was lately used. Note that - /// by removal of a node from the m_List container, this link - /// must be appropriately reset. - gli_t m_LastActiveLink; - - GroupContainer() - : m_LastActiveLink(m_List.end()) - { - } - - // Property active = { m_LastActiveLink; } - SRTU_PROPERTY_RW(gli_t, active, m_LastActiveLink); - - gli_t begin() { return m_List.begin(); } - gli_t end() { return m_List.end(); } - bool empty() { return m_List.empty(); } - void push_back(const SocketData& data) { m_List.push_back(data); } - void clear() - { - m_LastActiveLink = end(); - m_List.clear(); - } - size_t size() { return m_List.size(); } - - void erase(gli_t it); - }; - GroupContainer m_Group; - const bool m_bSyncOnMsgNo; // It goes into a dedicated HS field. Could be true for balancing groups (not implemented). - SRT_GROUP_TYPE m_type; - CUDTSocket* m_listener; // A "group" can only have one listener. - srt::sync::atomic m_iBusy; - CallbackHolder m_cbConnectHook; - void installConnectHook(srt_connect_callback_fn* hook, void* opaq) - { - m_cbConnectHook.set(opaq, hook); - } - -public: - void apiAcquire() { ++m_iBusy; } - void apiRelease() { --m_iBusy; } - - // A normal cycle of the send/recv functions is the following: - // - [Initial API call for a group] - // - GroupKeeper - ctor - // - LOCK: GlobControlLock - // - Find the group ID in the group container (break if not found) - // - LOCK: GroupLock of that group - // - Set BUSY flag - // - UNLOCK GroupLock - // - UNLOCK GlobControlLock - // - [Call the sending function (sendBroadcast/sendBackup)] - // - LOCK GroupLock - // - Preparation activities - // - Loop over group members - // - Send over a single socket - // - Check send status and conditions - // - Exit, if nothing else to be done - // - Check links to send extra - // - UNLOCK GroupLock - // - Wait for first ready link - // - LOCK GroupLock - // - Check status and find sendable link - // - Send over a single socket - // - Check status and update data - // - UNLOCK GroupLock, Exit - // - GroupKeeper - dtor - // - LOCK GroupLock - // - Clear BUSY flag - // - UNLOCK GroupLock - // END. - // - // The possibility for isStillBusy to go on is only the following: - // 1. Before calling the API function. As GlobControlLock is locked, - // the nearest lock on GlobControlLock by GroupKeeper can happen: - // - before the group is moved to ClosedGroups (this allows it to be found) - // - after the group is moved to ClosedGroups (this makes the group not found) - // - NOT after the group was deleted, as it could not be found and occupied. - // - // 2. Before release of GlobControlLock (acquired by GC), but before the - // API function locks GroupLock: - // - the GC call to isStillBusy locks GroupLock, but BUSY flag is already set - // - GC then avoids deletion of the group - // - // 3. In any further place up to the exit of the API implementation function, - // the BUSY flag is still set. - // - // 4. After exit of GroupKeeper destructor and unlock of GroupLock - // - the group is no longer being accessed and can be freely deleted. - // - the group also can no longer be found by ID. - - bool isStillBusy() - { - sync::ScopedLock glk(m_GroupLock); - return m_iBusy || !m_Group.empty(); - } - - struct BufferedMessageStorage - { - size_t blocksize; - size_t maxstorage; - std::vector storage; - - BufferedMessageStorage(size_t blk, size_t max = 0) - : blocksize(blk) - , maxstorage(max) - , storage() - { - } - - char* get() - { - if (storage.empty()) - return new char[blocksize]; - - // Get the element from the end - char* block = storage.back(); - storage.pop_back(); - return block; - } - - void put(char* block) - { - if (storage.size() >= maxstorage) - { - // Simply delete - delete[] block; - return; - } - - // Put the block into the spare buffer - storage.push_back(block); - } - - ~BufferedMessageStorage() - { - for (size_t i = 0; i < storage.size(); ++i) - delete[] storage[i]; - } - }; - - struct BufferedMessage - { - static BufferedMessageStorage storage; - - SRT_MSGCTRL mc; - mutable char* data; - size_t size; - - BufferedMessage() - : data() - , size() - { - } - ~BufferedMessage() - { - if (data) - storage.put(data); - } - - // NOTE: size 's' must be checked against SRT_LIVE_MAX_PLSIZE - // before calling - void copy(const char* buf, size_t s) - { - size = s; - data = storage.get(); - memcpy(data, buf, s); - } - - BufferedMessage(const BufferedMessage& foreign) - : mc(foreign.mc) - , data(foreign.data) - , size(foreign.size) - { - foreign.data = 0; - } - - BufferedMessage& operator=(const BufferedMessage& foreign) - { - data = foreign.data; - size = foreign.size; - mc = foreign.mc; - - foreign.data = 0; - return *this; - } - - private: - void swap_with(BufferedMessage& b) - { - std::swap(this->mc, b.mc); - std::swap(this->data, b.data); - std::swap(this->size, b.size); - } - }; - - typedef std::deque senderBuffer_t; - // typedef StaticBuffer senderBuffer_t; - -private: - // Fields required for SRT_GTYPE_BACKUP groups. - senderBuffer_t m_SenderBuffer; - int32_t m_iSndOldestMsgNo; // oldest position in the sender buffer - sync::atomic m_iSndAckedMsgNo; - uint32_t m_uOPT_MinStabilityTimeout_us; - - // THIS function must be called only in a function for a group type - // that does use sender buffer. - int32_t addMessageToBuffer(const char* buf, size_t len, SRT_MSGCTRL& w_mc); - - std::set m_sPollID; // set of epoll ID to trigger - int m_iMaxPayloadSize; - int m_iAvgPayloadSize; - bool m_bSynRecving; - bool m_bSynSending; - bool m_bTsbPd; - bool m_bTLPktDrop; - int64_t m_iTsbPdDelay_us; - int m_RcvEID; - class CEPollDesc* m_RcvEpolld; - int m_SndEID; - class CEPollDesc* m_SndEpolld; - - int m_iSndTimeOut; // sending timeout in milliseconds - int m_iRcvTimeOut; // receiving timeout in milliseconds - - // Start times for TsbPd. These times shall be synchronized - // between all sockets in the group. The first connected one - // defines it, others shall derive it. The value 0 decides if - // this has been already set. - time_point m_tsStartTime; - time_point m_tsRcvPeerStartTime; - - struct ReadPos - { - std::vector packet; - SRT_MSGCTRL mctrl; - ReadPos(int32_t s) - : mctrl(srt_msgctrl_default) - { - mctrl.pktseq = s; - } - }; - std::map m_Positions; - - ReadPos* checkPacketAhead(); - - void recv_CollectAliveAndBroken(std::vector& w_alive, std::set& w_broken); - - /// The function polls alive member sockets and retrieves a list of read-ready. - /// [acquires lock for CUDT::uglobal()->m_GlobControlLock] - /// [[using locked(m_GroupLock)]] temporally unlocks-locks internally - /// - /// @returns list of read-ready sockets - /// @throws CUDTException(MJ_CONNECTION, MN_NOCONN, 0) - /// @throws CUDTException(MJ_AGAIN, MN_RDAVAIL, 0) - std::vector recv_WaitForReadReady(const std::vector& aliveMembers, std::set& w_broken); - - // This is the sequence number of a packet that has been previously - // delivered. Initially it should be set to SRT_SEQNO_NONE so that the sequence read - // from the first delivering socket will be taken as a good deal. - sync::atomic m_RcvBaseSeqNo; - - bool m_bOpened; // Set to true when at least one link is at least pending - bool m_bConnected; // Set to true on first link confirmed connected - bool m_bClosing; - - // There's no simple way of transforming config - // items that are predicted to be used on socket. - // Use some options for yourself, store the others - // for setting later on a socket. - std::vector m_config; - - // Signal for the blocking user thread that the packet - // is ready to deliver. - sync::Condition m_RcvDataCond; - sync::Mutex m_RcvDataLock; - sync::atomic m_iLastSchedSeqNo; // represetnts the value of CUDT::m_iSndNextSeqNo for each running socket - sync::atomic m_iLastSchedMsgNo; - // Statistics - - struct Stats - { - // Stats state - time_point tsActivateTime; // Time when this group sent or received the first data packet - time_point tsLastSampleTime; // Time reset when clearing stats - - stats::Metric sent; // number of packets sent from the application - stats::Metric recv; // number of packets delivered from the group to the application - stats::Metric recvDrop; // number of packets dropped by the group receiver (not received from any member) - stats::Metric recvDiscard; // number of packets discarded as already delivered - - void init() - { - tsActivateTime = srt::sync::steady_clock::time_point(); - tsLastSampleTime = srt::sync::steady_clock::now(); - sent.reset(); - recv.reset(); - recvDrop.reset(); - recvDiscard.reset(); - } - - void reset() - { - tsLastSampleTime = srt::sync::steady_clock::now(); - - sent.resetTrace(); - recv.resetTrace(); - recvDrop.resetTrace(); - recvDiscard.resetTrace(); - } - } m_stats; - - void updateAvgPayloadSize(int size) - { - if (m_iAvgPayloadSize == -1) - m_iAvgPayloadSize = size; - else - m_iAvgPayloadSize = avg_iir<4>(m_iAvgPayloadSize, size); - } - - int avgRcvPacketSize() - { - // In case when no packet has been received yet, but already notified - // a dropped packet, its size will be SRT_LIVE_DEF_PLSIZE. It will be - // the value most matching in the typical uses, although no matter what - // value would be used here, each one would be wrong from some points - // of view. This one is simply the best choice for typical uses of groups - // provided that they are to be ued only for live mode. - return m_iAvgPayloadSize == -1 ? SRT_LIVE_DEF_PLSIZE : m_iAvgPayloadSize; - } - -public: - void bstatsSocket(CBytePerfMon* perf, bool clear); - - // Required after the call on newGroup on the listener side. - // On the listener side the group is lazily created just before - // accepting a new socket and therefore always open. - void setOpen() { m_bOpened = true; } - - std::string CONID() const - { -#if ENABLE_LOGGING - std::ostringstream os; - os << "@" << m_GroupID << ":"; - return os.str(); -#else - return ""; -#endif - } - - void resetInitialRxSequence() - { - // The app-reader doesn't care about the real sequence number. - // The first provided one will be taken as a good deal; even if - // this is going to be past the ISN, at worst it will be caused - // by TLPKTDROP. - m_RcvBaseSeqNo = SRT_SEQNO_NONE; - } - - bool applyGroupTime(time_point& w_start_time, time_point& w_peer_start_time) - { - using srt::sync::is_zero; - using srt_logging::gmlog; - - if (is_zero(m_tsStartTime)) - { - // The first socket, defines the group time for the whole group. - m_tsStartTime = w_start_time; - m_tsRcvPeerStartTime = w_peer_start_time; - return true; - } - - // Sanity check. This should never happen, fix the bug if found! - if (is_zero(m_tsRcvPeerStartTime)) - { - LOGC(gmlog.Error, log << "IPE: only StartTime is set, RcvPeerStartTime still 0!"); - // Kinda fallback, but that's not too safe. - m_tsRcvPeerStartTime = w_peer_start_time; - } - - // The redundant connection, derive the times - w_start_time = m_tsStartTime; - w_peer_start_time = m_tsRcvPeerStartTime; - - return false; - } - - // Live state synchronization - bool getBufferTimeBase(srt::CUDT* forthesakeof, time_point& w_tb, bool& w_wp, duration& w_dr); - bool applyGroupSequences(SRTSOCKET, int32_t& w_snd_isn, int32_t& w_rcv_isn); - - /// @brief Synchronize TSBPD base time and clock drift among members using the @a srcMember as a reference. - /// @param srcMember a reference for synchronization. - void synchronizeDrift(const srt::CUDT* srcMember); - - void updateLatestRcv(srt::CUDTSocket*); - - // Property accessors - SRTU_PROPERTY_RW_CHAIN(CUDTGroup, SRTSOCKET, id, m_GroupID); - SRTU_PROPERTY_RW_CHAIN(CUDTGroup, SRTSOCKET, peerid, m_PeerGroupID); - SRTU_PROPERTY_RW_CHAIN(CUDTGroup, SRT_GROUP_TYPE, type, m_type); - SRTU_PROPERTY_RW_CHAIN(CUDTGroup, int32_t, currentSchedSequence, m_iLastSchedSeqNo); - SRTU_PROPERTY_RRW(std::set&, epollset, m_sPollID); - SRTU_PROPERTY_RW_CHAIN(CUDTGroup, int64_t, latency, m_iTsbPdDelay_us); - SRTU_PROPERTY_RO(bool, synconmsgno, m_bSyncOnMsgNo); - SRTU_PROPERTY_RO(bool, closing, m_bClosing); -}; - -} // namespace srt - -#endif // INC_SRT_GROUP_H diff --git a/Vendor/SRT/Includes/group_backup.h b/Vendor/SRT/Includes/group_backup.h deleted file mode 100644 index 790cf55ed..000000000 --- a/Vendor/SRT/Includes/group_backup.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * SRT - Secure, Reliable, Transport - * Copyright (c) 2021 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/. - * - */ - - /***************************************************************************** - Written by - Haivision Systems Inc. - *****************************************************************************/ - -#ifndef INC_SRT_GROUP_BACKUP_H -#define INC_SRT_GROUP_BACKUP_H - -#include "srt.h" -#include "common.h" -#include "group_common.h" - -#include - -namespace srt -{ -namespace groups -{ - enum BackupMemberState - { - BKUPST_UNKNOWN = -1, - - BKUPST_PENDING = 0, - BKUPST_STANDBY = 1, - BKUPST_BROKEN = 2, - - BKUPST_ACTIVE_UNSTABLE = 3, - BKUPST_ACTIVE_UNSTABLE_WARY = 4, - BKUPST_ACTIVE_FRESH = 5, - BKUPST_ACTIVE_STABLE = 6, - - BKUPST_E_SIZE = 7 - }; - - const char* stateToStr(BackupMemberState state); - - inline bool isStateActive(BackupMemberState state) - { - if (state == BKUPST_ACTIVE_FRESH - || state == BKUPST_ACTIVE_STABLE - || state == BKUPST_ACTIVE_UNSTABLE - || state == BKUPST_ACTIVE_UNSTABLE_WARY) - { - return true; - } - - return false; - } - - struct BackupMemberStateEntry - { - BackupMemberStateEntry(SocketData* psock, BackupMemberState st) - : pSocketData(psock) - , socketID(psock->id) - , state(st) - {} - - SocketData* pSocketData; // accessing pSocketDataIt requires m_GroupLock - SRTSOCKET socketID; // therefore socketID is saved separately (needed to close broken sockets) - BackupMemberState state; - }; - - /// @brief A context needed for main/backup sending function. - /// @todo Using gli_t here does not allow to safely store the context outside of the sendBackup calls. - class SendBackupCtx - { - public: - SendBackupCtx() - : m_stateCounter() // default init with zeros - , m_activeMaxWeight() - , m_standbyMaxWeight() - { - } - - /// @brief Adds or updates a record of the member socket state. - /// @param pSocketDataIt Iterator to a socket - /// @param st State of the memmber socket - /// @todo Implement updating member state - void recordMemberState(SocketData* pSocketDataIt, BackupMemberState st); - - /// @brief Updates a record of the member socket state. - /// @param pSocketDataIt Iterator to a socket - /// @param st State of the memmber socket - /// @todo To be replaced by recordMemberState - /// @todo Update max weights? - void updateMemberState(const SocketData* pSocketDataIt, BackupMemberState st); - - /// @brief sorts members in order - /// Higher weight comes first, same weight: stable first, then fresh active. - void sortByWeightAndState(); - - BackupMemberState getMemberState(const SocketData* pSocketDataIt) const; - - unsigned countMembersByState(BackupMemberState st) const; - - const std::vector& memberStates() const { return m_memberStates; } - - uint16_t maxStandbyWeight() const { return m_standbyMaxWeight; } - uint16_t maxActiveWeight() const { return m_activeMaxWeight; } - - std::string printMembers() const; - - void setRateEstimate(const CRateEstimator& rate) { m_rateEstimate = rate; } - - const CRateEstimator& getRateEstimate() const { return m_rateEstimate; } - - private: - std::vector m_memberStates; // TODO: consider std::map here? - unsigned m_stateCounter[BKUPST_E_SIZE]; - uint16_t m_activeMaxWeight; - uint16_t m_standbyMaxWeight; - CRateEstimator m_rateEstimate; // The rate estimator state of the active link to copy to a backup on activation. - }; - -} // namespace groups -} // namespace srt - -#endif // INC_SRT_GROUP_BACKUP_H diff --git a/Vendor/SRT/Includes/group_common.h b/Vendor/SRT/Includes/group_common.h deleted file mode 100644 index d780d0b9a..000000000 --- a/Vendor/SRT/Includes/group_common.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SRT - Secure, Reliable, Transport - * Copyright (c) 2021 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/. - * - */ - -/***************************************************************************** -Written by - Haivision Systems Inc. -*****************************************************************************/ - -#ifndef INC_SRT_GROUP_COMMON_H -#define INC_SRT_GROUP_COMMON_H - -#include "srt.h" -#include "common.h" -#include "core.h" - -#include - -namespace srt -{ -namespace groups -{ - typedef SRT_MEMBERSTATUS GroupState; - - struct SocketData - { - SRTSOCKET id; // same as ps->m_SocketID - CUDTSocket* ps; - int token; - SRT_SOCKSTATUS laststatus; - GroupState sndstate; - GroupState rcvstate; - int sndresult; - int rcvresult; - sockaddr_any agent; - sockaddr_any peer; - bool ready_read; - bool ready_write; - bool ready_error; - - // Configuration - uint16_t weight; - - // Stats - int64_t pktSndDropTotal; - }; - - SocketData prepareSocketData(CUDTSocket* s); - - typedef std::list group_t; - typedef group_t::iterator gli_t; - -} // namespace groups -} // namespace srt - -#endif // INC_SRT_GROUP_COMMON_H diff --git a/Vendor/SRT/Includes/handshake.h b/Vendor/SRT/Includes/handshake.h deleted file mode 100644 index 93a351f39..000000000 --- a/Vendor/SRT/Includes/handshake.h +++ /dev/null @@ -1,366 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#ifndef INC_SRT_HANDSHAKE_H -#define INC_SRT_HANDSHAKE_H - -#include - -#include "crypto.h" -#include "utilities.h" - -namespace srt -{ - -typedef Bits<31, 16> HS_CMDSPEC_CMD; -typedef Bits<15, 0> HS_CMDSPEC_SIZE; - -// NOTE: Some of these flags represent CAPABILITIES, that is, -// as long as these flags are defined, they must be always set -// (unless they are deprecated). -enum SrtOptions -{ - SRT_OPT_TSBPDSND = BIT(0), /* Timestamp-based Packet delivery real-time data sender */ - SRT_OPT_TSBPDRCV = BIT(1), /* Timestamp-based Packet delivery real-time data receiver */ - SRT_OPT_HAICRYPT = BIT(2), /* CAPABILITY: HaiCrypt AES-128/192/256-CTR */ - SRT_OPT_TLPKTDROP = BIT(3), /* Drop real-time data packets too late to be processed in time */ - SRT_OPT_NAKREPORT = BIT(4), /* Periodic NAK report */ - SRT_OPT_REXMITFLG = BIT(5), // CAPABILITY: One bit in payload packet msgno is "retransmitted" flag - // (this flag can be reused for something else, when pre-1.2.0 versions are all abandoned) - SRT_OPT_STREAM = BIT(6), // STREAM MODE (not MESSAGE mode) - SRT_OPT_FILTERCAP = BIT(7), // CAPABILITY: Packet filter supported -}; - -inline int SrtVersionCapabilities() -{ - // NOTE: SRT_OPT_REXMITFLG is not included here because - // SRT is prepared to handle also peers that don't have this - // capability, so a listener responding to a peer that doesn't - // support it should NOT set this flag. - // - // This state will remain until this backward compatibility is - // decided to be broken, in which case this flag will be always - // set, and clients that do not support this capability will be - // rejected. - return SRT_OPT_HAICRYPT | SRT_OPT_FILTERCAP; -} - - -std::string SrtFlagString(int32_t flags); - -const int SRT_CMD_REJECT = 0, // REJECT is only a symbol for return type - SRT_CMD_HSREQ = 1, - SRT_CMD_HSRSP = 2, - SRT_CMD_KMREQ = 3, - SRT_CMD_KMRSP = 4, - SRT_CMD_SID = 5, - SRT_CMD_CONGESTION = 6, - SRT_CMD_FILTER = 7, - SRT_CMD_GROUP = 8, - SRT_CMD_NONE = -1; // for cases when {no pong for ping is required} | {no extension block found} - -enum SrtDataStruct -{ - SRT_HS_VERSION = 0, - SRT_HS_FLAGS, - SRT_HS_LATENCY, - - // Keep it always last - SRT_HS_E_SIZE -}; - -// For HSv5 the lo and hi part is used for particular side's latency -typedef Bits<31, 16> SRT_HS_LATENCY_RCV; -typedef Bits<15, 0> SRT_HS_LATENCY_SND; -// For HSv4 only the lower part is used. -typedef Bits<15, 0> SRT_HS_LATENCY_LEG; - - -struct SrtHandshakeExtension -{ - int16_t type; - std::vector contents; - - SrtHandshakeExtension(int16_t cmd): type(cmd) {} -}; - -// Implemented in core.cpp, so far -void SrtExtractHandshakeExtensions(const char* bufbegin, size_t size, - std::vector& w_output); - - -struct SrtHSRequest: public SrtHandshakeExtension -{ - typedef Bits<31, 16> SRT_HSTYPE_ENCFLAGS; - typedef Bits<15, 0> SRT_HSTYPE_HSFLAGS; - - // For translating PBKEYLEN into crypto flags - // This value is 16, 24, 32; after cutting off - // the leftmost 3 bits, it is 2, 3, 4. - typedef Bits<5, 3> SRT_PBKEYLEN_BITS; - - // This value fits ins SRT_HSTYPE_HSFLAGS. - // .... HAIVISIOn - static const int32_t SRT_MAGIC_CODE = 0x4A17; - - static int32_t wrapFlags(bool withmagic, int crypto_keylen) - { - int32_t base = withmagic ? SRT_MAGIC_CODE : 0; - return base | SRT_HSTYPE_ENCFLAGS::wrap( SRT_PBKEYLEN_BITS::unwrap(crypto_keylen) ); - } - - // Group handshake extension layout - - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | Group ID | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | Group Type | Group's Flags | Group's Weight | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - typedef Bits<31, 24> HS_GROUP_TYPE; - typedef Bits<23, 16> HS_GROUP_FLAGS; - typedef Bits<15, 0> HS_GROUP_WEIGHT; - -private: - friend class CHandShake; - - static const size_t SRT_HS_SIZE = 4*sizeof(uint32_t); // 4 existing fields - static const size_t SRT_EXT_HS_SIZE = 2*sizeof(uint32_t) + SRT_HS_SIZE; // SRT magic and SRT HS type, used only in UDT HS ext - - typedef Bits<15, 0> SRT_TSBPD_DELAY; - - uint32_t m_iSrtVersion; - uint32_t m_iSrtFlags; - uint32_t m_iSrtTsbpd; - uint32_t m_iSrtReserved; - -public: - - SrtHSRequest(): SrtHandshakeExtension(SRT_CMD_HSREQ), m_iSrtVersion(), m_iSrtFlags(), m_iSrtTsbpd(), m_iSrtReserved() {} - - void setVersion(uint32_t v) { m_iSrtVersion = v; } - uint32_t version() const { return m_iSrtVersion; } - - void setFlag(SrtOptions opt) { m_iSrtFlags |= uint32_t(opt); } - void clearFlag(SrtOptions opt) { m_iSrtFlags &= ~opt; } - uint32_t flags() const { return m_iSrtFlags; } - - void setTsbPdDelay(uint16_t delay) { m_iSrtTsbpd |= SRT_TSBPD_DELAY::wrap(delay); } - // Unknown what the 1-16 bits have to be used for. - uint16_t tsbPdDelay() const - { - return SRT_TSBPD_DELAY::unwrap(m_iSrtTsbpd); - } - - size_t size() const { return SRT_EXT_HS_SIZE; } - - bool serialize(char* p, size_t size) const; - bool deserialize(const char* mem, size_t size); -}; - -struct SrtKMRequest: public SrtHandshakeExtension -{ - uint32_t m_iKmState; - char m_aKey[1]; // dynamic size -}; - - -//////////////////////////////////////////////////////////////////////////////// - -enum UDTRequestType -{ - URQ_INDUCTION_TYPES = 0, // XXX used to check in one place. Consdr rm. - - URQ_INDUCTION = 1, // First part for client-server connection - URQ_WAVEAHAND = 0, // First part for rendezvous connection - - URQ_CONCLUSION = -1, // Second part of handshake negotiation - URQ_AGREEMENT = -2, // Extra (last) step for rendezvous only - URQ_DONE = -3, // Special value used only in state-switching, to state that nothing should be sent in response - - // Note: the client-server connection uses: - // --> INDUCTION (empty) - // <-- INDUCTION (cookie) - // --> CONCLUSION (cookie) - // <-- CONCLUSION (ok) - - // The rendezvous HSv4 (legacy): - // --> WAVEAHAND (effective only if peer is also connecting) - // <-- CONCLUSION (empty) (consider yourself connected upon reception) - // --> AGREEMENT (sent as a response for conclusion, requires no response) - - // The rendezvous HSv5 (using SRT extensions): - // --> WAVEAHAND (with cookie) - // --- (selecting INITIATOR/RESPONDER by cookie contest - comparing one another's cookie) - // <-- CONCLUSION (without extensions, if RESPONDER, with extensions, if INITIATOR) - // --> CONCLUSION (with response extensions, if RESPONDER) - // <-- AGREEMENT (sent exclusively by INITIATOR upon reception of CONCLUSIOn with response extensions) - - // This marks the beginning of values that are error codes. - URQ_FAILURE_TYPES = 1000, - - // NOTE: codes above 1000 are reserved for failure codes for - // rejection reason, as per `SRT_REJECT_REASON` enum. The - // actual rejection code is the value of the request type - // minus URQ_FAILURE_TYPES. - - // This is in order to return standard error codes for server - // data retrieval failures. - URQ_SERVER_FAILURE_TYPES = URQ_FAILURE_TYPES + SRT_REJC_PREDEFINED, - - // This is for a completely user-defined reject reasons. - URQ_USER_FAILURE_TYPES = URQ_FAILURE_TYPES + SRT_REJC_USERDEFINED -}; - -inline UDTRequestType URQFailure(int reason) -{ - return UDTRequestType(URQ_FAILURE_TYPES + int(reason)); -} - -inline int RejectReasonForURQ(UDTRequestType req) -{ - if (req < URQ_FAILURE_TYPES) - return SRT_REJ_UNKNOWN; - - int reason = req - URQ_FAILURE_TYPES; - if (reason < SRT_REJC_PREDEFINED && reason >= SRT_REJ_E_SIZE) - return SRT_REJ_UNKNOWN; - - return reason; -} - -// DEPRECATED values. Use URQFailure(SRT_REJECT_REASON). -const UDTRequestType URQ_ERROR_REJECT SRT_ATR_DEPRECATED = (UDTRequestType)1002; // == 1000 + SRT_REJ_PEER -const UDTRequestType URQ_ERROR_INVALID SRT_ATR_DEPRECATED = (UDTRequestType)1004; // == 1000 + SRT_REJ_ROGUE - -// XXX Change all uses of that field to UDTRequestType when possible -#if ENABLE_LOGGING -std::string RequestTypeStr(UDTRequestType); -#else -inline std::string RequestTypeStr(UDTRequestType) { return ""; } -#endif - - -class CHandShake -{ -public: - CHandShake(); - - int store_to(char* buf, size_t& size); - int load_from(const char* buf, size_t size); - -public: - // This is the size of SERIALIZED handshake. - // Might be defined as simply sizeof(CHandShake), but the - // enum values would have to be forced as int32_t, which is only - // available in C++11. Theoretically they are all 32-bit, but - // such a statement is not reliable and not portable. - static const size_t m_iContentSize = 48; // Size of hand shake data - - // Extension flags - - static const int32_t HS_EXT_HSREQ = BIT(0); - static const int32_t HS_EXT_KMREQ = BIT(1); - static const int32_t HS_EXT_CONFIG = BIT(2); - - static std::string ExtensionFlagStr(int32_t fl); - - // Applicable only when m_iVersion == HS_VERSION_SRT1 - int32_t flags() { return m_iType; } - -public: - int32_t m_iVersion; // UDT version (HS_VERSION_* symbols) - int32_t m_iType; // UDT4: socket type (only UDT_DGRAM is valid); SRT1: extension flags - int32_t m_iISN; // random initial sequence number - int32_t m_iMSS; // maximum segment size - int32_t m_iFlightFlagSize; // flow control window size - UDTRequestType m_iReqType; // handshake stage - int32_t m_iID; // SRT socket ID of HS sender - int32_t m_iCookie; // cookie - uint32_t m_piPeerIP[4]; // The IP address that the peer's UDP port is bound to - - bool m_extension; - - bool valid(); - std::string show(); - - // The rendezvous state machine used in HSv5 only (in HSv4 everything is happening the old way). - // - // The WAVING state is the very initial state of the rendezvous connection and restored after the - // connection is closed. - // The ATTENTION and FINE are two alternative states that are transited to from WAVING. The possible - // situations are: - // - "serial arrangement": one party transits to ATTENTION and the other party transits to FINE - // - "parallel arrangement" both parties transit to ATTENTION - // - // Parallel arrangement is a "virtually impossible" case, in which both parties must send the first - // URQ_WAVEAHAND message in a perfect time synchronization, when they are started at exactly the same - // time, on machines with exactly the same performance and all things preceding the message sending - // have taken perfectly identical amount of time. This isn't anyhow possible otherwise because if - // the clients have started at different times, the one who started first sends a message and the - // system of the receiver buffers this message even before the client binds the port for enough long - // time so that it outlasts also the possible second, repeated waveahand. - enum RendezvousState - { - RDV_INVALID, //< This socket wasn't prepared for rendezvous process. Reject any events. - RDV_WAVING, //< Initial state for rendezvous. No contact seen from the peer. - RDV_ATTENTION, //< When received URQ_WAVEAHAND. [WAVING]:URQ_WAVEAHAND --> [ATTENTION]. - RDV_FINE, //< When received URQ_CONCLUSION. [WAVING]:URQ_CONCLUSION --> [FINE]. - RDV_INITIATED, //< When received URQ_CONCLUSION+HSREQ extension in ATTENTION state. - RDV_CONNECTED //< Final connected state. [ATTENTION]:URQ_CONCLUSION --> [CONNECTED] <-- [FINE]:URQ_AGREEMENT. - }; - -#if ENABLE_LOGGING - static std::string RdvStateStr(RendezvousState s); -#else - static std::string RdvStateStr(RendezvousState) { return ""; } -#endif - -}; - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/list.h b/Vendor/SRT/Includes/list.h deleted file mode 100644 index 03f05e927..000000000 --- a/Vendor/SRT/Includes/list.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/22/2011 -modified by - Haivision Systems Inc. -*****************************************************************************/ - -#ifndef INC_SRT_LIST_H -#define INC_SRT_LIST_H - -#include "udt.h" -#include "common.h" - -namespace srt { - -class CSndLossList -{ -public: - CSndLossList(int size = 1024); - ~CSndLossList(); - - /// Insert a seq. no. into the sender loss list. - /// @param [in] seqno1 sequence number starts. - /// @param [in] seqno2 sequence number ends. - /// @return number of packets that are not in the list previously. - int insert(int32_t seqno1, int32_t seqno2); - - /// Remove the given sequence number and all numbers that precede it. - /// @param [in] seqno sequence number. - void removeUpTo(int32_t seqno); - - /// Read the loss length.∏ - /// @return The length of the list. - int getLossLength() const; - - /// Read the first (smallest) loss seq. no. in the list and remove it. - /// @return The seq. no. or -1 if the list is empty. - int32_t popLostSeq(); - - void traceState() const; - -private: - struct Seq - { - int32_t seqstart; // sequence number starts - int32_t seqend; // sequence number ends - int inext; // index of the next node in the list - } * m_caSeq; - - int m_iHead; // first node - int m_iLength; // loss length - const int m_iSize; // size of the static array - int m_iLastInsertPos; // position of last insert node - - mutable srt::sync::Mutex m_ListLock; // used to synchronize list operation - -private: - /// Inserts an element to the beginning and updates head pointer. - /// No lock. - void insertHead(int pos, int32_t seqno1, int32_t seqno2); - - /// Inserts an element after previous element. - /// No lock. - void insertAfter(int pos, int pos_after, int32_t seqno1, int32_t seqno2); - - /// Check if it is possible to coalesce element at loc with further elements. - /// @param loc - last changed location - void coalesce(int loc); - - /// Update existing element with the new range (increase only) - /// @param pos position of the element being updated - /// @param seqno1 first sequence number in range - /// @param seqno2 last sequence number in range (SRT_SEQNO_NONE if no range) - bool updateElement(int pos, int32_t seqno1, int32_t seqno2); - -private: - CSndLossList(const CSndLossList&); - CSndLossList& operator=(const CSndLossList&); -}; - -//////////////////////////////////////////////////////////////////////////////// - -class CRcvLossList -{ -public: - CRcvLossList(int size = 1024); - ~CRcvLossList(); - - /// Insert a series of loss seq. no. between "seqno1" and "seqno2" into the receiver's loss list. - /// @param [in] seqno1 sequence number starts. - /// @param [in] seqno2 seqeunce number ends. - - void insert(int32_t seqno1, int32_t seqno2); - - /// Remove a loss seq. no. from the receiver's loss list. - /// @param [in] seqno sequence number. - /// @return if the packet is removed (true) or no such lost packet is found (false). - - bool remove(int32_t seqno); - - /// Remove all packets between seqno1 and seqno2. - /// @param [in] seqno1 start sequence number. - /// @param [in] seqno2 end sequence number. - /// @return if the packet is removed (true) or no such lost packet is found (false). - - bool remove(int32_t seqno1, int32_t seqno2); - - /// Find if there is any lost packets whose sequence number falling seqno1 and seqno2. - /// @param [in] seqno1 start sequence number. - /// @param [in] seqno2 end sequence number. - /// @return True if found; otherwise false. - - bool find(int32_t seqno1, int32_t seqno2) const; - - /// Read the loss length. - /// @return the length of the list. - - int getLossLength() const; - - /// Read the first (smallest) seq. no. in the list. - /// @return the sequence number or -1 if the list is empty. - - int32_t getFirstLostSeq() const; - - /// Get a encoded loss array for NAK report. - /// @param [out] array the result list of seq. no. to be included in NAK. - /// @param [out] len physical length of the result array. - /// @param [in] limit maximum length of the array. - - void getLossArray(int32_t* array, int& len, int limit); - -private: - struct Seq - { - int32_t seqstart; // sequence number starts - int32_t seqend; // sequence number ends - int inext; // index of the next node in the list - int iprior; // index of the previous node in the list - } * m_caSeq; - - int m_iHead; // first node in the list - int m_iTail; // last node in the list; - int m_iLength; // loss length - int m_iSize; // size of the static array - int m_iLargestSeq; // largest seq ever seen - -private: - CRcvLossList(const CRcvLossList&); - CRcvLossList& operator=(const CRcvLossList&); - -public: - struct iterator - { - int32_t head; - Seq* seq; - - iterator(Seq* str, int32_t v) - : head(v) - , seq(str) - { - } - - iterator next() const - { - if (head == -1) - return *this; // should report error, but we can only throw exception, so simply ignore it. - - return iterator(seq, seq[head].inext); - } - - iterator& operator++() - { - *this = next(); - return *this; - } - - iterator operator++(int) - { - iterator old(seq, head); - *this = next(); - return old; - } - - bool operator==(const iterator& second) const - { - // Ignore seq - should be the same and this is only a sanity check. - return head == second.head; - } - - bool operator!=(const iterator& second) const { return !(*this == second); } - - std::pair operator*() { return std::make_pair(seq[head].seqstart, seq[head].seqend); } - }; - - iterator begin() { return iterator(m_caSeq, m_iHead); } - iterator end() { return iterator(m_caSeq, -1); } -}; - -struct CRcvFreshLoss -{ - int32_t seq[2]; - int ttl; - srt::sync::steady_clock::time_point timestamp; - - CRcvFreshLoss(int32_t seqlo, int32_t seqhi, int initial_ttl); - -// Don't WTF when looking at this. The Windows system headers define -// a publicly visible preprocessor macro with that name. REALLY! -#ifdef DELETE -#undef DELETE -#endif - enum Emod - { - NONE, //< the given sequence was not found in this range - STRIPPED, //< it was equal to first or last, already taken care of - SPLIT, //< found in the middle, you have to split this range into two - DELETE //< This was a range of one element exactly equal to sequence. Simply delete it. - }; - - Emod revoke(int32_t sequence); - Emod revoke(int32_t lo, int32_t hi); -}; - -} // namespace srt - -#endif diff --git a/Vendor/SRT/Includes/logger_defs.h b/Vendor/SRT/Includes/logger_defs.h deleted file mode 100644 index 63a4caf3e..000000000 --- a/Vendor/SRT/Includes/logger_defs.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - WARNING: Generated from ../scripts/generate-logging-defs.tcl - - DO NOT MODIFY. - - Copyright applies as per the generator script. - */ - - -#ifndef INC_SRT_LOGGER_DEFS_H -#define INC_SRT_LOGGER_DEFS_H - -#include "srt.h" -#include "logging.h" - -namespace srt_logging -{ - struct AllFaOn - { - LogConfig::fa_bitset_t allfa; - AllFaOn(); - }; - - extern Logger gglog; - extern Logger smlog; - extern Logger cnlog; - extern Logger xtlog; - extern Logger tslog; - extern Logger rslog; - - extern Logger cclog; - extern Logger pflog; - - extern Logger aclog; - - extern Logger qclog; - - extern Logger eilog; - - extern Logger arlog; - extern Logger brlog; - extern Logger qrlog; - extern Logger krlog; - extern Logger grlog; - - extern Logger aslog; - extern Logger bslog; - extern Logger qslog; - extern Logger kslog; - extern Logger gslog; - - extern Logger inlog; - - extern Logger qmlog; - extern Logger kmlog; - extern Logger gmlog; - extern Logger ealog; - -} // namespace srt_logging - -#endif diff --git a/Vendor/SRT/Includes/logging.h b/Vendor/SRT/Includes/logging.h deleted file mode 100644 index e79785b46..000000000 --- a/Vendor/SRT/Includes/logging.h +++ /dev/null @@ -1,488 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -written by - Haivision Systems Inc. - *****************************************************************************/ - -#ifndef INC_SRT_LOGGING_H -#define INC_SRT_LOGGING_H - - -#include -#include -#include -#include -#include -#ifdef _WIN32 -#include "win/wintime.h" -#include -#else -#include -#endif - -#include "srt.h" -#include "utilities.h" -#include "threadname.h" -#include "logging_api.h" -#include "srt_compat.h" -#include "sync.h" - -#ifdef __GNUC__ -#define PRINTF_LIKE __attribute__((format(printf,2,3))) -#else -#define PRINTF_LIKE -#endif - -#if ENABLE_LOGGING - -// GENERAL NOTE: All logger functions ADD THEIR OWN \n (EOL). Don't add any your own EOL character. -// The logging system may not add the EOL character, if appropriate flag was set in log settings. -// Anyway, treat the whole contents of eventually formatted message as exactly one line. - -// LOGC uses an iostream-like syntax, using the special 'log' symbol. -// This symbol isn't visible outside the log macro parameters. -// Usage: LOGC(gglog.Debug, log << param1 << param2 << param3); -#define LOGC(logdes, args) if (logdes.CheckEnabled()) \ -{ \ - srt_logging::LogDispatcher::Proxy log(logdes); \ - log.setloc(__FILE__, __LINE__, __FUNCTION__); \ - const srt_logging::LogDispatcher::Proxy& log_prox SRT_ATR_UNUSED = args; \ -} - -// LOGF uses printf-like style formatting. -// Usage: LOGF(gglog.Debug, "%s: %d", param1.c_str(), int(param2)); -#define LOGF(logdes, ...) if (logdes.CheckEnabled()) logdes().setloc(__FILE__, __LINE__, __FUNCTION__).form(__VA_ARGS__) - -// LOGP is C++11 only OR with only one string argument. -// Usage: LOGP(gglog.Debug, param1, param2, param3); -#define LOGP(logdes, ...) if (logdes.CheckEnabled()) logdes.printloc(__FILE__, __LINE__, __FUNCTION__,##__VA_ARGS__) - -#define IF_LOGGING(instr) instr - -#if ENABLE_HEAVY_LOGGING - -#define HLOGC LOGC -#define HLOGP LOGP -#define HLOGF LOGF - -#define IF_HEAVY_LOGGING(instr) instr - -#else - -#define HLOGC(...) -#define HLOGF(...) -#define HLOGP(...) - -#define IF_HEAVY_LOGGING(instr) (void)0 - -#endif - -#else - -#define LOGC(...) -#define LOGF(...) -#define LOGP(...) - -#define HLOGC(...) -#define HLOGF(...) -#define HLOGP(...) - -#define IF_HEAVY_LOGGING(instr) (void)0 -#define IF_LOGGING(instr) (void)0 - -#endif - -namespace srt_logging -{ - -struct LogConfig -{ - typedef std::bitset fa_bitset_t; - fa_bitset_t enabled_fa; // NOTE: assumed atomic reading - LogLevel::type max_level; // NOTE: assumed atomic reading - std::ostream* log_stream; - SRT_LOG_HANDLER_FN* loghandler_fn; - void* loghandler_opaque; - srt::sync::Mutex mutex; - int flags; - - LogConfig(const fa_bitset_t& efa, - LogLevel::type l = LogLevel::warning, - std::ostream* ls = &std::cerr) - : enabled_fa(efa) - , max_level(l) - , log_stream(ls) - , loghandler_fn() - , loghandler_opaque() - , flags() - { - } - - ~LogConfig() - { - } - - SRT_ATTR_ACQUIRE(mutex) - void lock() { mutex.lock(); } - - SRT_ATTR_RELEASE(mutex) - void unlock() { mutex.unlock(); } -}; - -// The LogDispatcher class represents the object that is responsible for -// a decision whether to log something or not, and if so, print the log. -struct SRT_API LogDispatcher -{ -private: - int fa; - LogLevel::type level; - static const size_t MAX_PREFIX_SIZE = 32; - char prefix[MAX_PREFIX_SIZE+1]; - LogConfig* src_config; - - bool isset(int flg) { return (src_config->flags & flg) != 0; } - -public: - - LogDispatcher(int functional_area, LogLevel::type log_level, const char* your_pfx, - const char* logger_pfx /*[[nullable]]*/, LogConfig& config): - fa(functional_area), - level(log_level), - src_config(&config) - { - // XXX stpcpy desired, but not enough portable - // Composing the exact prefix is not critical, so simply - // cut the prefix, if the length is exceeded - - // See Logger::Logger; we know this has normally 2 characters, - // except !!FATAL!!, which has 9. Still less than 32. - strcpy(prefix, your_pfx); - - // If the size of the FA name together with severity exceeds the size, - // just skip the former. - if (logger_pfx && strlen(prefix) + strlen(logger_pfx) + 1 < MAX_PREFIX_SIZE) - { - strcat(prefix, ":"); - strcat(prefix, logger_pfx); - } - } - - ~LogDispatcher() - { - } - - bool CheckEnabled(); - - void CreateLogLinePrefix(std::ostringstream&); - void SendLogLine(const char* file, int line, const std::string& area, const std::string& sl); - - // log.Debug("This is the ", nth, " time"); <--- C++11 only. - // log.Debug() << "This is the " << nth << " time"; <--- C++03 available. - -#if HAVE_CXX11 - - template - void PrintLogLine(const char* file, int line, const std::string& area, Args&&... args); - - template - void operator()(Arg1&& arg1, Args&&... args) - { - PrintLogLine("UNKNOWN.c++", 0, "UNKNOWN", arg1, args...); - } - - template - void printloc(const char* file, int line, const std::string& area, Arg1&& arg1, Args&&... args) - { - PrintLogLine(file, line, area, arg1, args...); - } -#else - template - void PrintLogLine(const char* file, int line, const std::string& area, const Arg& arg); - - // For C++03 (older) standard provide only with one argument. - template - void operator()(const Arg& arg) - { - PrintLogLine("UNKNOWN.c++", 0, "UNKNOWN", arg); - } - - void printloc(const char* file, int line, const std::string& area, const std::string& arg1) - { - PrintLogLine(file, line, area, arg1); - } -#endif - -#if ENABLE_LOGGING - - struct Proxy; - friend struct Proxy; - - Proxy operator()(); -#else - - // Dummy proxy that does nothing - struct DummyProxy - { - DummyProxy(LogDispatcher&) - { - } - - template - DummyProxy& operator<<(const T& ) // predicted for temporary objects - { - return *this; - } - - DummyProxy& form(const char*, ...) - { - return *this; - } - - DummyProxy& vform(const char*, va_list) - { - return *this; - } - - DummyProxy& setloc(const char* , int , std::string) - { - return *this; - } - }; - - DummyProxy operator()() - { - return DummyProxy(*this); - } - -#endif - -}; - -#if ENABLE_LOGGING - -struct LogDispatcher::Proxy -{ - LogDispatcher& that; - - std::ostringstream os; - - // Cache the 'enabled' state in the beginning. If the logging - // becomes enabled or disabled in the middle of the log, we don't - // want it to be partially printed anyway. - bool that_enabled; - int flags; - - // CACHE!!! - const char* i_file; - int i_line; - std::string area; - - Proxy& setloc(const char* f, int l, std::string a) - { - i_file = f; - i_line = l; - area = a; - return *this; - } - - // Left for future. Not sure if it's more convenient - // to use this to translate __PRETTY_FUNCTION__ to - // something short, or just let's leave __FUNCTION__ - // or better __func__. - std::string ExtractName(std::string pretty_function); - - Proxy(LogDispatcher& guy); - - // Copy constructor is needed due to noncopyable ostringstream. - // This is used only in creation of the default object, so just - // use the default values, just copy the location cache. - Proxy(const Proxy& p): that(p.that), area(p.area) - { - i_file = p.i_file; - i_line = p.i_line; - that_enabled = false; - flags = p.flags; - } - - - template - Proxy& operator<<(const T& arg) // predicted for temporary objects - { - if ( that_enabled ) - { - os << arg; - } - return *this; - } - - ~Proxy() - { - if ( that_enabled ) - { - if ( (flags & SRT_LOGF_DISABLE_EOL) == 0 ) - os << std::endl; - that.SendLogLine(i_file, i_line, area, os.str()); - } - // Needed in destructor? - //os.clear(); - //os.str(""); - } - - Proxy& form(const char* fmts, ...) PRINTF_LIKE - { - if ( !that_enabled ) - return *this; - - if ( !fmts || fmts[0] == '\0' ) - return *this; - - va_list ap; - va_start(ap, fmts); - vform(fmts, ap); - va_end(ap); - return *this; - } - - Proxy& vform(const char* fmts, va_list ap) - { - char buf[512]; - - vsprintf(buf, fmts, ap); - size_t len = strlen(buf); - if ( buf[len-1] == '\n' ) - { - // Remove EOL character, should it happen to be at the end. - // The EOL will be added at the end anyway. - buf[len-1] = '\0'; - } - - os << buf; - return *this; - } -}; - - -#endif - -class Logger -{ - int m_fa; - LogConfig& m_config; - -public: - - LogDispatcher Debug; - LogDispatcher Note; - LogDispatcher Warn; - LogDispatcher Error; - LogDispatcher Fatal; - - Logger(int functional_area, LogConfig& config, const char* logger_pfx = NULL): - m_fa(functional_area), - m_config(config), - Debug ( m_fa, LogLevel::debug, " D", logger_pfx, m_config ), - Note ( m_fa, LogLevel::note, ".N", logger_pfx, m_config ), - Warn ( m_fa, LogLevel::warning, "!W", logger_pfx, m_config ), - Error ( m_fa, LogLevel::error, "*E", logger_pfx, m_config ), - Fatal ( m_fa, LogLevel::fatal, "!!FATAL!!", logger_pfx, m_config ) - { - } - -}; - -inline bool LogDispatcher::CheckEnabled() -{ - // Don't use enabler caching. Check enabled state every time. - - // These assume to be atomically read, so the lock is not needed - // (note that writing to this field is still mutex-protected). - // It's also no problem if the level was changed at the moment - // when the enabler check is tested here. Worst case, the log - // will be printed just a moment after it was turned off. - const LogConfig* config = src_config; // to enforce using const operator[] - int configured_enabled_fa = config->enabled_fa[fa]; - int configured_maxlevel = config->max_level; - - return configured_enabled_fa && level <= configured_maxlevel; -} - - -#if HAVE_CXX11 - -//extern std::mutex Debug_mutex; - -inline void PrintArgs(std::ostream&) {} - -template -inline void PrintArgs(std::ostream& serr, Arg1&& arg1, Args&&... args) -{ - serr << arg1; - PrintArgs(serr, args...); -} - -template -inline void LogDispatcher::PrintLogLine(const char* file SRT_ATR_UNUSED, int line SRT_ATR_UNUSED, const std::string& area SRT_ATR_UNUSED, Args&&... args SRT_ATR_UNUSED) -{ -#ifdef ENABLE_LOGGING - std::ostringstream serr; - CreateLogLinePrefix(serr); - PrintArgs(serr, args...); - - if ( !isset(SRT_LOGF_DISABLE_EOL) ) - serr << std::endl; - - // Not sure, but it wasn't ever used. - SendLogLine(file, line, area, serr.str()); -#endif -} - -#else - -template -inline void LogDispatcher::PrintLogLine(const char* file SRT_ATR_UNUSED, int line SRT_ATR_UNUSED, const std::string& area SRT_ATR_UNUSED, const Arg& arg SRT_ATR_UNUSED) -{ -#ifdef ENABLE_LOGGING - std::ostringstream serr; - CreateLogLinePrefix(serr); - serr << arg; - - if ( !isset(SRT_LOGF_DISABLE_EOL) ) - serr << std::endl; - - // Not sure, but it wasn't ever used. - SendLogLine(file, line, area, serr.str()); -#endif -} - -#endif - -// SendLogLine can be compiled normally. It's intermediately used by: -// - Proxy object, which is replaced by DummyProxy when !ENABLE_LOGGING -// - PrintLogLine, which has empty body when !ENABLE_LOGGING -inline void LogDispatcher::SendLogLine(const char* file, int line, const std::string& area, const std::string& msg) -{ - src_config->lock(); - if ( src_config->loghandler_fn ) - { - (*src_config->loghandler_fn)(src_config->loghandler_opaque, int(level), file, line, area.c_str(), msg.c_str()); - } - else if ( src_config->log_stream ) - { - (*src_config->log_stream) << msg; - (*src_config->log_stream).flush(); - } - src_config->unlock(); -} - -} - -#endif diff --git a/Vendor/SRT/Includes/logging_api.h b/Vendor/SRT/Includes/logging_api.h deleted file mode 100644 index 4fc3b812b..000000000 --- a/Vendor/SRT/Includes/logging_api.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -written by - Haivision Systems Inc. - *****************************************************************************/ - -#ifndef INC_SRT_LOGGING_API_H -#define INC_SRT_LOGGING_API_H - -// These are required for access functions: -// - adding FA (requires set) -// - setting a log stream (requires iostream) -#ifdef __cplusplus -#include -#include -#endif - -#ifdef _WIN32 -#include "win/syslog_defs.h" -#else -#include -#endif - -// Syslog is included so that it provides log level names. -// Haivision log standard requires the same names plus extra one: -#ifndef LOG_DEBUG_TRACE -#define LOG_DEBUG_TRACE 8 -#endif -// It's unused anyway, just for the record. -#define SRT_LOG_LEVEL_MIN LOG_CRIT -#define SRT_LOG_LEVEL_MAX LOG_DEBUG - -// Flags -#define SRT_LOGF_DISABLE_TIME 1 -#define SRT_LOGF_DISABLE_THREADNAME 2 -#define SRT_LOGF_DISABLE_SEVERITY 4 -#define SRT_LOGF_DISABLE_EOL 8 - -// Handler type. -typedef void SRT_LOG_HANDLER_FN(void* opaque, int level, const char* file, int line, const char* area, const char* message); - -#ifdef __cplusplus -namespace srt_logging -{ - - -struct LogFA -{ -private: - int value; -public: - operator int() const { return value; } - - LogFA(int v): value(v) - { - // Generally this was what it has to be used for. - // Unfortunately it couldn't be agreed with the - //logging_fa_all.insert(v); - } -}; - -const LogFA LOGFA_GENERAL = 0; - - - -namespace LogLevel -{ - // There are 3 general levels: - - // A. fatal - this means the application WILL crash. - // B. unexpected: - // - error: this was unexpected for the library - // - warning: this was expected by the library, but may be harmful for the application - // C. expected: - // - note: a significant, but rarely occurring event - // - debug: may occur even very often and enabling it can harm performance - - enum type - { - fatal = LOG_CRIT, - // Fatal vs. Error: with Error, you can still continue. - error = LOG_ERR, - // Error vs. Warning: Warning isn't considered a problem for the library. - warning = LOG_WARNING, - // Warning vs. Note: Note means something unusual, but completely correct behavior. - note = LOG_NOTICE, - // Note vs. Debug: Debug may occur even multiple times in a millisecond. - // (Well, worth noting that Error and Warning potentially also can). - debug = LOG_DEBUG - }; -} - -class Logger; - -} -#endif - -#endif diff --git a/Vendor/SRT/Includes/md5.h b/Vendor/SRT/Includes/md5.h deleted file mode 100644 index 98bd07665..000000000 --- a/Vendor/SRT/Includes/md5.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.h,v 1.2 2007/12/24 05:58:37 lilyco Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.h is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . - 1999-05-03 lpd Original version. - */ - -#ifndef md5_INCLUDED -# define md5_INCLUDED - -/* - * All symbols have been put under the srt namespace - * to avoid potential linkage conflicts. - */ -namespace srt { - -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; - -/* Initialize the algorithm. */ -void md5_init(md5_state_t *pms); - -/* Append a string to the message. */ -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); - -/* Finish the message and return the digest. */ -void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); - -} // namespace srt - -#endif /* md5_INCLUDED */ diff --git a/Vendor/SRT/Includes/module.modulemap b/Vendor/SRT/Includes/module.modulemap deleted file mode 100644 index df46f3069..000000000 --- a/Vendor/SRT/Includes/module.modulemap +++ /dev/null @@ -1,4 +0,0 @@ -module libsrt { - header "srt.h" - export * -} diff --git a/Vendor/SRT/Includes/platform_sys.h b/Vendor/SRT/Includes/platform_sys.h deleted file mode 100644 index fae95803f..000000000 --- a/Vendor/SRT/Includes/platform_sys.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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/. - * - */ -#ifndef INC__PLATFORM_SYS_H -#define INC__PLATFORM_SYS_H - -#ifdef _WIN32 - #include - #include - #include - #include - #include - #include - #if defined(_MSC_VER) - #pragma warning(disable:4251) - #endif -#else -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#endif diff --git a/Vendor/SRT/Includes/srt.h b/Vendor/SRT/Includes/srt.h deleted file mode 100644 index 0e566e859..000000000 --- a/Vendor/SRT/Includes/srt.h +++ /dev/null @@ -1,747 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -written by - Haivision Systems Inc. - *****************************************************************************/ - -#ifndef INC__SRTC_H -#define INC__SRTC_H - -#include "version.h" - -#include "platform_sys.h" - -#include -#include - -#include "srt4udt.h" -#include "logging_api.h" - -//////////////////////////////////////////////////////////////////////////////// - -//if compiling on VC6.0 or pre-WindowsXP systems -//use -DLEGACY_WIN32 - -//if compiling with MinGW, it only works on XP or above -//use -D_WIN32_WINNT=0x0501 - - -#ifdef _WIN32 - #ifndef __MINGW__ - // Explicitly define 32-bit and 64-bit numbers - typedef __int32 int32_t; - typedef __int64 int64_t; - typedef unsigned __int32 uint32_t; - #ifndef LEGACY_WIN32 - typedef unsigned __int64 uint64_t; - #else - // VC 6.0 does not support unsigned __int64: may cause potential problems. - typedef __int64 uint64_t; - #endif - - #ifdef SRT_DYNAMIC - #ifdef SRT_EXPORTS - #define SRT_API __declspec(dllexport) - #else - #define SRT_API __declspec(dllimport) - #endif - #else - #define SRT_API - #endif - #else // __MINGW__ - #define SRT_API - #endif -#else - #define SRT_API __attribute__ ((visibility("default"))) -#endif - - -// For feature tests if you need. -// You can use these constants with SRTO_MINVERSION option. -#define SRT_VERSION_FEAT_HSv5 0x010300 - -// When compiling in C++17 mode, use the standard C++17 attributes -// (out of these, only [[deprecated]] is supported in C++14, so -// for all lesser standard use compiler-specific attributes). -#if defined(SRT_NO_DEPRECATED) - -#define SRT_ATR_UNUSED -#define SRT_ATR_DEPRECATED -#define SRT_ATR_NODISCARD - -#elif defined(__cplusplus) && __cplusplus > 201406 - -#define SRT_ATR_UNUSED [[maybe_unused]] -#define SRT_ATR_DEPRECATED [[deprecated]] -#define SRT_ATR_NODISCARD [[nodiscard]] - -// GNUG is GNU C/C++; this syntax is also supported by Clang -#elif defined( __GNUC__) -#define SRT_ATR_UNUSED __attribute__((unused)) -#define SRT_ATR_DEPRECATED __attribute__((deprecated)) -#define SRT_ATR_NODISCARD __attribute__((warn_unused_result)) -#else -#define SRT_ATR_UNUSED -#define SRT_ATR_DEPRECATED -#define SRT_ATR_NODISCARD -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int SRTSOCKET; // SRTSOCKET is a typedef to int anyway, and it's not even in UDT namespace :) - -#ifdef _WIN32 - #ifndef __MINGW__ - typedef SOCKET SYSSOCKET; - #else - typedef int SYSSOCKET; - #endif -#else - typedef int SYSSOCKET; -#endif - -typedef SYSSOCKET UDPSOCKET; - - -// Values returned by srt_getsockstate() -typedef enum SRT_SOCKSTATUS { - SRTS_INIT = 1, - SRTS_OPENED, - SRTS_LISTENING, - SRTS_CONNECTING, - SRTS_CONNECTED, - SRTS_BROKEN, - SRTS_CLOSING, - SRTS_CLOSED, - SRTS_NONEXIST -} SRT_SOCKSTATUS; - -// This is a duplicate enum. Must be kept in sync with the original UDT enum for -// backward compatibility until all compat is destroyed. -typedef enum SRT_SOCKOPT { - - SRTO_MSS = 0, // the Maximum Transfer Unit - SRTO_SNDSYN = 1, // if sending is blocking - SRTO_RCVSYN = 2, // if receiving is blocking - SRTO_ISN = 3, // Initial Sequence Number (valid only after srt_connect or srt_accept-ed sockets) - SRTO_FC = 4, // Flight flag size (window size) - SRTO_SNDBUF = 5, // maximum buffer in sending queue - SRTO_RCVBUF = 6, // UDT receiving buffer size - SRTO_LINGER = 7, // waiting for unsent data when closing - SRTO_UDP_SNDBUF = 8, // UDP sending buffer size - SRTO_UDP_RCVBUF = 9, // UDP receiving buffer size - // XXX Free space for 2 options - // after deprecated ones are removed - SRTO_RENDEZVOUS = 12, // rendezvous connection mode - SRTO_SNDTIMEO = 13, // send() timeout - SRTO_RCVTIMEO = 14, // recv() timeout - SRTO_REUSEADDR = 15, // reuse an existing port or create a new one - SRTO_MAXBW = 16, // maximum bandwidth (bytes per second) that the connection can use - SRTO_STATE = 17, // current socket state, see UDTSTATUS, read only - SRTO_EVENT = 18, // current available events associated with the socket - SRTO_SNDDATA = 19, // size of data in the sending buffer - SRTO_RCVDATA = 20, // size of data available for recv - SRTO_SENDER = 21, // Sender mode (independent of conn mode), for encryption, tsbpd handshake. - SRTO_TSBPDMODE = 22, // Enable/Disable TsbPd. Enable -> Tx set origin timestamp, Rx deliver packet at origin time + delay - SRTO_LATENCY = 23, // NOT RECOMMENDED. SET: to both SRTO_RCVLATENCY and SRTO_PEERLATENCY. GET: same as SRTO_RCVLATENCY. - SRTO_TSBPDDELAY = 23, // DEPRECATED. ALIAS: SRTO_LATENCY - SRTO_INPUTBW = 24, // Estimated input stream rate. - SRTO_OHEADBW, // MaxBW ceiling based on % over input stream rate. Applies when UDT_MAXBW=0 (auto). - SRTO_PASSPHRASE = 26, // Crypto PBKDF2 Passphrase size[0,10..64] 0:disable crypto - SRTO_PBKEYLEN, // Crypto key len in bytes {16,24,32} Default: 16 (128-bit) - SRTO_KMSTATE, // Key Material exchange status (UDT_SRTKmState) - SRTO_IPTTL = 29, // IP Time To Live (passthru for system sockopt IPPROTO_IP/IP_TTL) - SRTO_IPTOS, // IP Type of Service (passthru for system sockopt IPPROTO_IP/IP_TOS) - SRTO_TLPKTDROP = 31, // Enable receiver pkt drop - SRTO_SNDDROPDELAY = 32, // Extra delay towards latency for sender TLPKTDROP decision (-1 to off) - SRTO_NAKREPORT = 33, // Enable receiver to send periodic NAK reports - SRTO_VERSION = 34, // Local SRT Version - SRTO_PEERVERSION, // Peer SRT Version (from SRT Handshake) - SRTO_CONNTIMEO = 36, // Connect timeout in msec. Ccaller default: 3000, rendezvous (x 10) - // deprecated: SRTO_TWOWAYDATA, SRTO_SNDPBKEYLEN, SRTO_RCVPBKEYLEN (@c below) - _DEPRECATED_SRTO_SNDPBKEYLEN = 38, // (needed to use inside the code without generating -Wswitch) - // - SRTO_SNDKMSTATE = 40, // (GET) the current state of the encryption at the peer side - SRTO_RCVKMSTATE, // (GET) the current state of the encryption at the agent side - SRTO_LOSSMAXTTL, // Maximum possible packet reorder tolerance (number of packets to receive after loss to send lossreport) - SRTO_RCVLATENCY, // TsbPd receiver delay (mSec) to absorb burst of missed packet retransmission - SRTO_PEERLATENCY, // Minimum value of the TsbPd receiver delay (mSec) for the opposite side (peer) - SRTO_MINVERSION, // Minimum SRT version needed for the peer (peers with less version will get connection reject) - SRTO_STREAMID, // A string set to a socket and passed to the listener's accepted socket - SRTO_CONGESTION, // Congestion controller type selection - SRTO_MESSAGEAPI, // In File mode, use message API (portions of data with boundaries) - SRTO_PAYLOADSIZE, // Maximum payload size sent in one UDP packet (0 if unlimited) - SRTO_TRANSTYPE = 50, // Transmission type (set of options required for given transmission type) - SRTO_KMREFRESHRATE, // After sending how many packets the encryption key should be flipped to the new key - SRTO_KMPREANNOUNCE, // How many packets before key flip the new key is annnounced and after key flip the old one decommissioned - SRTO_ENFORCEDENCRYPTION, // Connection to be rejected or quickly broken when one side encryption set or bad password - SRTO_IPV6ONLY, // IPV6_V6ONLY mode - SRTO_PEERIDLETIMEO, // Peer-idle timeout (max time of silence heard from peer) in [ms] - // (some space left) - SRTO_PACKETFILTER = 60 // Add and configure a packet filter -} SRT_SOCKOPT; - - -#ifdef __cplusplus - -typedef SRT_ATR_DEPRECATED SRT_SOCKOPT SRT_SOCKOPT_DEPRECATED; -#define SRT_DEPRECATED_OPTION(value) ((SRT_SOCKOPT_DEPRECATED)value) - -#else - -// deprecated enum labels are supported only since gcc 6, so in C there -// will be a whole deprecated enum type, as it's not an error in C to mix -// enum types -enum SRT_ATR_DEPRECATED SRT_SOCKOPT_DEPRECATED -{ - - // Dummy last option, as every entry ends with a comma - SRTO_DEPRECATED_END = 0 - -}; -#define SRT_DEPRECATED_OPTION(value) ((enum SRT_SOCKOPT_DEPRECATED)value) -#endif - -// DEPRECATED OPTIONS: - -// SRTO_TWOWAYDATA: not to be used. SRT connection is always bidirectional if -// both clients support HSv5 - that is, since version 1.3.0. This flag was -// introducted around 1.2.0 version when full bidirectional support was added, -// but the bidirectional feature was decided no to be enabled due to huge -// differences between bidirectional support (especially concerning encryption) -// with HSv4 and HSv5 (that is, HSv4 was decided to remain unidirectional only, -// even though partial support is already provided in this version). - -#define SRTO_TWOWAYDATA SRT_DEPRECATED_OPTION(37) - -// This has been deprecated a long time ago, treat this as never implemented. -// The value is also already reused for another option. -#define SRTO_TSBPDMAXLAG SRT_DEPRECATED_OPTION(32) - -// This option is a derivative from UDT; the mechanism that uses it is now -// settable by SRTO_CONGESTION, or more generally by SRTO_TRANSTYPE. The freed -// number has been reused for a read-only option SRTO_ISN. This option should -// have never been used anywhere, just for safety this is temporarily declared -// as deprecated. -#define SRTO_CC SRT_DEPRECATED_OPTION(3) - -// These two flags were derived from UDT, but they were never used. -// Probably it didn't make sense anyway. The maximum size of the message -// in File/Message mode is defined by SRTO_SNDBUF, and the MSGTTL is -// a parameter used in `srt_sendmsg` and `srt_sendmsg2`. -#define SRTO_MAXMSG SRT_DEPRECATED_OPTION(10) -#define SRTO_MSGTTL SRT_DEPRECATED_OPTION(11) - -// These flags come from an older experimental implementation of bidirectional -// encryption support, which were used two different SEKs, KEKs and passphrases -// per direction. The current implementation uses just one in both directions, -// so SRTO_PBKEYLEN should be used for both cases. -#define SRTO_SNDPBKEYLEN SRT_DEPRECATED_OPTION(38) -#define SRTO_RCVPBKEYLEN SRT_DEPRECATED_OPTION(39) - -// Keeping old name for compatibility (deprecated) -#define SRTO_SMOOTHER SRT_DEPRECATED_OPTION(47) -#define SRTO_STRICTENC SRT_DEPRECATED_OPTION(53) - -typedef enum SRT_TRANSTYPE -{ - SRTT_LIVE, - SRTT_FILE, - SRTT_INVALID -} SRT_TRANSTYPE; - -// These sizes should be used for Live mode. In Live mode you should not -// exceed the size that fits in a single MTU. - -// This is for MPEG TS and it's a default SRTO_PAYLOADSIZE for SRTT_LIVE. -static const int SRT_LIVE_DEF_PLSIZE = 1316; // = 188*7, recommended for MPEG TS - -// This is the maximum payload size for Live mode, should you have a different -// payload type than MPEG TS. -static const int SRT_LIVE_MAX_PLSIZE = 1456; // MTU(1500) - UDP.hdr(28) - SRT.hdr(16) - -// Latency for Live transmission: default is 120 -static const int SRT_LIVE_DEF_LATENCY_MS = 120; - -// Importrant note: please add new fields to this structure to the end and don't remove any existing fields -struct CBytePerfMon -{ - // global measurements - int64_t msTimeStamp; // time since the UDT entity is started, in milliseconds - int64_t pktSentTotal; // total number of sent data packets, including retransmissions - int64_t pktRecvTotal; // total number of received packets - int pktSndLossTotal; // total number of lost packets (sender side) - int pktRcvLossTotal; // total number of lost packets (receiver side) - int pktRetransTotal; // total number of retransmitted packets - int pktSentACKTotal; // total number of sent ACK packets - int pktRecvACKTotal; // total number of received ACK packets - int pktSentNAKTotal; // total number of sent NAK packets - int pktRecvNAKTotal; // total number of received NAK packets - int64_t usSndDurationTotal; // total time duration when UDT is sending data (idle time exclusive) - //>new - int pktSndDropTotal; // number of too-late-to-send dropped packets - int pktRcvDropTotal; // number of too-late-to play missing packets - int pktRcvUndecryptTotal; // number of undecrypted packets - uint64_t byteSentTotal; // total number of sent data bytes, including retransmissions - uint64_t byteRecvTotal; // total number of received bytes -#ifdef SRT_ENABLE_LOSTBYTESCOUNT - uint64_t byteRcvLossTotal; // total number of lost bytes -#endif - uint64_t byteRetransTotal; // total number of retransmitted bytes - uint64_t byteSndDropTotal; // number of too-late-to-send dropped bytes - uint64_t byteRcvDropTotal; // number of too-late-to play missing bytes (estimate based on average packet size) - uint64_t byteRcvUndecryptTotal; // number of undecrypted bytes - //< - - // local measurements - int64_t pktSent; // number of sent data packets, including retransmissions - int64_t pktRecv; // number of received packets - int pktSndLoss; // number of lost packets (sender side) - int pktRcvLoss; // number of lost packets (receiver side) - int pktRetrans; // number of retransmitted packets - int pktRcvRetrans; // number of retransmitted packets received - int pktSentACK; // number of sent ACK packets - int pktRecvACK; // number of received ACK packets - int pktSentNAK; // number of sent NAK packets - int pktRecvNAK; // number of received NAK packets - double mbpsSendRate; // sending rate in Mb/s - double mbpsRecvRate; // receiving rate in Mb/s - int64_t usSndDuration; // busy sending time (i.e., idle time exclusive) - int pktReorderDistance; // size of order discrepancy in received sequences - double pktRcvAvgBelatedTime; // average time of packet delay for belated packets (packets with sequence past the ACK) - int64_t pktRcvBelated; // number of received AND IGNORED packets due to having come too late - //>new - int pktSndDrop; // number of too-late-to-send dropped packets - int pktRcvDrop; // number of too-late-to play missing packets - int pktRcvUndecrypt; // number of undecrypted packets - uint64_t byteSent; // number of sent data bytes, including retransmissions - uint64_t byteRecv; // number of received bytes -#ifdef SRT_ENABLE_LOSTBYTESCOUNT - uint64_t byteRcvLoss; // number of retransmitted bytes -#endif - uint64_t byteRetrans; // number of retransmitted bytes - uint64_t byteSndDrop; // number of too-late-to-send dropped bytes - uint64_t byteRcvDrop; // number of too-late-to play missing bytes (estimate based on average packet size) - uint64_t byteRcvUndecrypt; // number of undecrypted bytes - //< - - // instant measurements - double usPktSndPeriod; // packet sending period, in microseconds - int pktFlowWindow; // flow window size, in number of packets - int pktCongestionWindow; // congestion window size, in number of packets - int pktFlightSize; // number of packets on flight - double msRTT; // RTT, in milliseconds - double mbpsBandwidth; // estimated bandwidth, in Mb/s - int byteAvailSndBuf; // available UDT sender buffer size - int byteAvailRcvBuf; // available UDT receiver buffer size - //>new - double mbpsMaxBW; // Transmit Bandwidth ceiling (Mbps) - int byteMSS; // MTU - - int pktSndBuf; // UnACKed packets in UDT sender - int byteSndBuf; // UnACKed bytes in UDT sender - int msSndBuf; // UnACKed timespan (msec) of UDT sender - int msSndTsbPdDelay; // Timestamp-based Packet Delivery Delay - - int pktRcvBuf; // Undelivered packets in UDT receiver - int byteRcvBuf; // Undelivered bytes of UDT receiver - int msRcvBuf; // Undelivered timespan (msec) of UDT receiver - int msRcvTsbPdDelay; // Timestamp-based Packet Delivery Delay - - int pktSndFilterExtraTotal; // number of control packets supplied by packet filter - int pktRcvFilterExtraTotal; // number of control packets received and not supplied back - int pktRcvFilterSupplyTotal; // number of packets that the filter supplied extra (e.g. FEC rebuilt) - int pktRcvFilterLossTotal; // number of packet loss not coverable by filter - - int pktSndFilterExtra; // number of control packets supplied by packet filter - int pktRcvFilterExtra; // number of control packets received and not supplied back - int pktRcvFilterSupply; // number of packets that the filter supplied extra (e.g. FEC rebuilt) - int pktRcvFilterLoss; // number of packet loss not coverable by filter - int pktReorderTolerance; // packet reorder tolerance value - //< -}; - -//////////////////////////////////////////////////////////////////////////////// - -// Error codes - define outside the CUDTException class -// because otherwise you'd have to use CUDTException::MJ_SUCCESS etc. -// in all throw CUDTException expressions. -enum CodeMajor -{ - MJ_UNKNOWN = -1, - MJ_SUCCESS = 0, - MJ_SETUP = 1, - MJ_CONNECTION = 2, - MJ_SYSTEMRES = 3, - MJ_FILESYSTEM = 4, - MJ_NOTSUP = 5, - MJ_AGAIN = 6, - MJ_PEERERROR = 7 -}; - -enum CodeMinor -{ - // These are "minor" error codes from various "major" categories - // MJ_SETUP - MN_NONE = 0, - MN_TIMEOUT = 1, - MN_REJECTED = 2, - MN_NORES = 3, - MN_SECURITY = 4, - // MJ_CONNECTION - MN_CONNLOST = 1, - MN_NOCONN = 2, - // MJ_SYSTEMRES - MN_THREAD = 1, - MN_MEMORY = 2, - // MJ_FILESYSTEM - MN_SEEKGFAIL = 1, - MN_READFAIL = 2, - MN_SEEKPFAIL = 3, - MN_WRITEFAIL = 4, - // MJ_NOTSUP - MN_ISBOUND = 1, - MN_ISCONNECTED = 2, - MN_INVAL = 3, - MN_SIDINVAL = 4, - MN_ISUNBOUND = 5, - MN_NOLISTEN = 6, - MN_ISRENDEZVOUS = 7, - MN_ISRENDUNBOUND = 8, - MN_INVALMSGAPI = 9, - MN_INVALBUFFERAPI = 10, - MN_BUSY = 11, - MN_XSIZE = 12, - MN_EIDINVAL = 13, - // MJ_AGAIN - MN_WRAVAIL = 1, - MN_RDAVAIL = 2, - MN_XMTIMEOUT = 3, - MN_CONGESTION = 4 -}; - -static const enum CodeMinor MN_ISSTREAM SRT_ATR_DEPRECATED = (enum CodeMinor)(9); -static const enum CodeMinor MN_ISDGRAM SRT_ATR_DEPRECATED = (enum CodeMinor)(10); - -// Stupid, but effective. This will be #undefined, so don't worry. -#define MJ(major) (1000 * MJ_##major) -#define MN(major, minor) (1000 * MJ_##major + MN_##minor) - -// Some better way to define it, and better for C language. -typedef enum SRT_ERRNO -{ - SRT_EUNKNOWN = -1, - SRT_SUCCESS = MJ_SUCCESS, - - SRT_ECONNSETUP = MJ(SETUP), - SRT_ENOSERVER = MN(SETUP, TIMEOUT), - SRT_ECONNREJ = MN(SETUP, REJECTED), - SRT_ESOCKFAIL = MN(SETUP, NORES), - SRT_ESECFAIL = MN(SETUP, SECURITY), - - SRT_ECONNFAIL = MJ(CONNECTION), - SRT_ECONNLOST = MN(CONNECTION, CONNLOST), - SRT_ENOCONN = MN(CONNECTION, NOCONN), - - SRT_ERESOURCE = MJ(SYSTEMRES), - SRT_ETHREAD = MN(SYSTEMRES, THREAD), - SRT_ENOBUF = MN(SYSTEMRES, MEMORY), - - SRT_EFILE = MJ(FILESYSTEM), - SRT_EINVRDOFF = MN(FILESYSTEM, SEEKGFAIL), - SRT_ERDPERM = MN(FILESYSTEM, READFAIL), - SRT_EINVWROFF = MN(FILESYSTEM, SEEKPFAIL), - SRT_EWRPERM = MN(FILESYSTEM, WRITEFAIL), - - SRT_EINVOP = MJ(NOTSUP), - SRT_EBOUNDSOCK = MN(NOTSUP, ISBOUND), - SRT_ECONNSOCK = MN(NOTSUP, ISCONNECTED), - SRT_EINVPARAM = MN(NOTSUP, INVAL), - SRT_EINVSOCK = MN(NOTSUP, SIDINVAL), - SRT_EUNBOUNDSOCK = MN(NOTSUP, ISUNBOUND), - SRT_ENOLISTEN = MN(NOTSUP, NOLISTEN), - SRT_ERDVNOSERV = MN(NOTSUP, ISRENDEZVOUS), - SRT_ERDVUNBOUND = MN(NOTSUP, ISRENDUNBOUND), - SRT_EINVALMSGAPI = MN(NOTSUP, INVALMSGAPI), - SRT_EINVALBUFFERAPI = MN(NOTSUP, INVALBUFFERAPI), - SRT_EDUPLISTEN = MN(NOTSUP, BUSY), - SRT_ELARGEMSG = MN(NOTSUP, XSIZE), - SRT_EINVPOLLID = MN(NOTSUP, EIDINVAL), - - SRT_EASYNCFAIL = MJ(AGAIN), - SRT_EASYNCSND = MN(AGAIN, WRAVAIL), - SRT_EASYNCRCV = MN(AGAIN, RDAVAIL), - SRT_ETIMEOUT = MN(AGAIN, XMTIMEOUT), - SRT_ECONGEST = MN(AGAIN, CONGESTION), - - SRT_EPEERERR = MJ(PEERERROR) -} SRT_ERRNO; - -static const SRT_ERRNO SRT_EISSTREAM SRT_ATR_DEPRECATED = (SRT_ERRNO) MN(NOTSUP, INVALMSGAPI); -static const SRT_ERRNO SRT_EISDGRAM SRT_ATR_DEPRECATED = (SRT_ERRNO) MN(NOTSUP, INVALBUFFERAPI); - -#undef MJ -#undef MN - -enum SRT_REJECT_REASON -{ - SRT_REJ_UNKNOWN, // initial set when in progress - SRT_REJ_SYSTEM, // broken due to system function error - SRT_REJ_PEER, // connection was rejected by peer - SRT_REJ_RESOURCE, // internal problem with resource allocation - SRT_REJ_ROGUE, // incorrect data in handshake messages - SRT_REJ_BACKLOG, // listener's backlog exceeded - SRT_REJ_IPE, // internal program error - SRT_REJ_CLOSE, // socket is closing - SRT_REJ_VERSION, // peer is older version than agent's minimum set - SRT_REJ_RDVCOOKIE, // rendezvous cookie collision - SRT_REJ_BADSECRET, // wrong password - SRT_REJ_UNSECURE, // password required or unexpected - SRT_REJ_MESSAGEAPI, // streamapi/messageapi collision - SRT_REJ_CONGESTION, // incompatible congestion-controller type - SRT_REJ_FILTER, // incompatible packet filter - - SRT_REJ__SIZE, -}; - -// Logging API - specialization for SRT. - -// Define logging functional areas for log selection. -// Use values greater than 0. Value 0 is reserved for LOGFA_GENERAL, -// which is considered always enabled. - -// Logger Functional Areas -// Note that 0 is "general". - -// Made by #define so that it's available also for C API. -#define SRT_LOGFA_GENERAL 0 -#define SRT_LOGFA_BSTATS 1 -#define SRT_LOGFA_CONTROL 2 -#define SRT_LOGFA_DATA 3 -#define SRT_LOGFA_TSBPD 4 -#define SRT_LOGFA_REXMIT 5 -#define SRT_LOGFA_HAICRYPT 6 -#define SRT_LOGFA_CONGEST 7 - -// To make a typical int32_t size, although still use std::bitset. -// C API will carry it over. -#define SRT_LOGFA_LASTNONE 31 - -enum SRT_KM_STATE -{ - SRT_KM_S_UNSECURED = 0, //No encryption - SRT_KM_S_SECURING = 1, //Stream encrypted, exchanging Keying Material - SRT_KM_S_SECURED = 2, //Stream encrypted, keying Material exchanged, decrypting ok. - SRT_KM_S_NOSECRET = 3, //Stream encrypted and no secret to decrypt Keying Material - SRT_KM_S_BADSECRET = 4 //Stream encrypted and wrong secret, cannot decrypt Keying Material -}; - -enum SRT_EPOLL_OPT -{ - SRT_EPOLL_OPT_NONE = 0x0, // fallback - // this values are defined same as linux epoll.h - // so that if system values are used by mistake, they should have the same effect - SRT_EPOLL_IN = 0x1, - SRT_EPOLL_OUT = 0x4, - SRT_EPOLL_ERR = 0x8, - SRT_EPOLL_ET = 1u << 31 -}; -// These are actually flags - use a bit container: -typedef int32_t SRT_EPOLL_T; - -enum SRT_EPOLL_FLAGS -{ - /// This allows the EID container to be empty when calling the waiting - /// function with infinite time. This means an infinite hangup, although - /// a socket can be added to this EID from a separate thread. - SRT_EPOLL_ENABLE_EMPTY = 1, - - /// This makes the waiting function check if there is output container - /// passed to it, and report an error if it isn't. By default it is allowed - /// that the output container is 0 size or NULL and therefore the readiness - /// state is reported only as a number of ready sockets from return value. - SRT_EPOLL_ENABLE_OUTPUTCHECK = 2 -}; - -#ifdef __cplusplus -// In C++ these enums cannot be treated as int and glued by operator |. -// Unless this operator is defined. -inline SRT_EPOLL_OPT operator|(SRT_EPOLL_OPT a1, SRT_EPOLL_OPT a2) -{ - return SRT_EPOLL_OPT( (int)a1 | (int)a2 ); -} - -inline bool operator&(int flags, SRT_EPOLL_OPT eflg) -{ - // Using an enum prevents treating int automatically as enum, - // requires explicit enum to be passed here, and minimizes the - // risk that the right side value will contain multiple flags. - return (flags & int(eflg)) != 0; -} -#endif - - - -typedef struct CBytePerfMon SRT_TRACEBSTATS; - -static const SRTSOCKET SRT_INVALID_SOCK = -1; -static const int SRT_ERROR = -1; - -// library initialization -SRT_API int srt_startup(void); -SRT_API int srt_cleanup(void); - -// -// Socket operations -// -SRT_API SRTSOCKET srt_socket (int af, int type, int protocol); -SRT_API SRTSOCKET srt_create_socket(); -SRT_API int srt_bind (SRTSOCKET u, const struct sockaddr* name, int namelen); -SRT_API int srt_bind_peerof (SRTSOCKET u, UDPSOCKET udpsock); -SRT_API int srt_listen (SRTSOCKET u, int backlog); -SRT_API SRTSOCKET srt_accept (SRTSOCKET u, struct sockaddr* addr, int* addrlen); -typedef int srt_listen_callback_fn (void* opaq, SRTSOCKET ns, int hsversion, const struct sockaddr* peeraddr, const char* streamid); -SRT_API int srt_listen_callback(SRTSOCKET lsn, srt_listen_callback_fn* hook_fn, void* hook_opaque); -SRT_API int srt_connect (SRTSOCKET u, const struct sockaddr* name, int namelen); -SRT_API int srt_connect_debug(SRTSOCKET u, const struct sockaddr* name, int namelen, int forced_isn); -SRT_API int srt_rendezvous (SRTSOCKET u, const struct sockaddr* local_name, int local_namelen, - const struct sockaddr* remote_name, int remote_namelen); -SRT_API int srt_close (SRTSOCKET u); -SRT_API int srt_getpeername (SRTSOCKET u, struct sockaddr* name, int* namelen); -SRT_API int srt_getsockname (SRTSOCKET u, struct sockaddr* name, int* namelen); -SRT_API int srt_getsockopt (SRTSOCKET u, int level /*ignored*/, SRT_SOCKOPT optname, void* optval, int* optlen); -SRT_API int srt_setsockopt (SRTSOCKET u, int level /*ignored*/, SRT_SOCKOPT optname, const void* optval, int optlen); -SRT_API int srt_getsockflag (SRTSOCKET u, SRT_SOCKOPT opt, void* optval, int* optlen); -SRT_API int srt_setsockflag (SRTSOCKET u, SRT_SOCKOPT opt, const void* optval, int optlen); - - -// XXX Note that the srctime functionality doesn't work yet and needs fixing. -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 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 - uint64_t srctime; // source timestamp (usec), 0: use internal time - 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_MSGCTRL; - -// You are free to use either of these two methods to set SRT_MSGCTRL object -// to default values: either call srt_msgctrl_init(&obj) or obj = srt_msgctrl_default. -SRT_API void srt_msgctrl_init(SRT_MSGCTRL* mctrl); -SRT_API extern const SRT_MSGCTRL srt_msgctrl_default; - -// The send/receive functions. -// These functions have different names due to different sets of parameters -// to be supplied. Not all of them are needed or make sense in all modes: - -// Plain: supply only the buffer and its size. -// Msg: supply additionally -// - TTL (message is not delivered when exceeded) and -// - INORDER (when false, the message is allowed to be delivered in different -// order than when it was sent, when the later message is earlier ready to -// deliver) -// Msg2: Supply extra parameters in SRT_MSGCTRL. When receiving, these -// parameters will be filled, as needed. NULL is acceptable, in which case -// the defaults are used. - -// NOTE: srt_send and srt_recv have the last "..." left to allow ignore a -// deprecated and unused "flags" parameter. After confirming that all -// compat applications that pass useless 0 there are fixed, this will be -// removed. - -// -// Sending functions -// -SRT_API int srt_send (SRTSOCKET u, const char* buf, int len); -SRT_API int srt_sendmsg (SRTSOCKET u, const char* buf, int len, int ttl/* = -1*/, int inorder/* = false*/); -SRT_API int srt_sendmsg2(SRTSOCKET u, const char* buf, int len, SRT_MSGCTRL *mctrl); - -// -// Receiving functions -// -SRT_API int srt_recv (SRTSOCKET u, char* buf, int len); - -// srt_recvmsg is actually an alias to srt_recv, it stays under the old name for compat reasons. -SRT_API int srt_recvmsg (SRTSOCKET u, char* buf, int len); -SRT_API int srt_recvmsg2(SRTSOCKET u, char *buf, int len, SRT_MSGCTRL *mctrl); - - -// Special send/receive functions for files only. -#define SRT_DEFAULT_SENDFILE_BLOCK 364000 -#define SRT_DEFAULT_RECVFILE_BLOCK 7280000 -SRT_API int64_t srt_sendfile(SRTSOCKET u, const char* path, int64_t* offset, int64_t size, int block); -SRT_API int64_t srt_recvfile(SRTSOCKET u, const char* path, int64_t* offset, int64_t size, int block); - - -// last error detection -SRT_API const char* srt_getlasterror_str(void); -SRT_API int srt_getlasterror(int* errno_loc); -SRT_API const char* srt_strerror(int code, int errnoval); -SRT_API void srt_clearlasterror(void); - -// performance track -// perfmon with Byte counters for better bitrate estimation. -SRT_API int srt_bstats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear); -// permon with Byte counters and instantaneous stats instead of moving averages for Snd/Rcvbuffer sizes. -SRT_API int srt_bistats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear, int instantaneous); - -// Socket Status (for problem tracking) -SRT_API SRT_SOCKSTATUS srt_getsockstate(SRTSOCKET u); - -SRT_API int srt_epoll_create(void); -SRT_API int srt_epoll_add_usock(int eid, SRTSOCKET u, const int* events); -SRT_API int srt_epoll_add_ssock(int eid, SYSSOCKET s, const int* events); -SRT_API int srt_epoll_remove_usock(int eid, SRTSOCKET u); -SRT_API int srt_epoll_remove_ssock(int eid, SYSSOCKET s); -SRT_API int srt_epoll_update_usock(int eid, SRTSOCKET u, const int* events); -SRT_API int srt_epoll_update_ssock(int eid, SYSSOCKET s, const int* events); - -SRT_API 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); -typedef struct SRT_EPOLL_EVENT_ -{ - SRTSOCKET fd; - int events; // SRT_EPOLL_IN | SRT_EPOLL_OUT | SRT_EPOLL_ERR -} SRT_EPOLL_EVENT; -SRT_API int srt_epoll_uwait(int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut); - -SRT_API int32_t srt_epoll_set(int eid, int32_t flags); -SRT_API int srt_epoll_release(int eid); - -// Logging control - -SRT_API void srt_setloglevel(int ll); -SRT_API void srt_addlogfa(int fa); -SRT_API void srt_dellogfa(int fa); -SRT_API void srt_resetlogfa(const int* fara, size_t fara_size); -// This isn't predicted, will be only available in SRT C++ API. -// For the time being, until this API is ready, use UDT::setlogstream. -// SRT_API void srt_setlogstream(std::ostream& stream); -SRT_API void srt_setloghandler(void* opaque, SRT_LOG_HANDLER_FN* handler); -SRT_API void srt_setlogflags(int flags); - - -SRT_API int srt_getsndbuffer(SRTSOCKET sock, size_t* blocks, size_t* bytes); - -SRT_API enum SRT_REJECT_REASON srt_getrejectreason(SRTSOCKET sock); -SRT_API extern const char* const srt_rejectreason_msg []; -const char* srt_rejectreason_str(enum SRT_REJECT_REASON id); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Vendor/SRT/Includes/srt4udt.h b/Vendor/SRT/Includes/srt4udt.h deleted file mode 100644 index 49f6d9f7a..000000000 --- a/Vendor/SRT/Includes/srt4udt.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -written by - Haivision Systems Inc. - *****************************************************************************/ - -#ifndef SRT4UDT_H -#define SRT4UDT_H - -#ifndef INC__SRTC_H -#error "This is protected header, used by udt.h. This shouldn't be included directly" -#endif - -//undef SRT_ENABLE_ECN 1 /* Early Congestion Notification (for source bitrate control) */ - -//undef SRT_DEBUG_TSBPD_OUTJITTER 1 /* Packet Delivery histogram */ -//undef SRT_DEBUG_TSBPD_DRIFT 1 /* Debug Encoder-Decoder Drift) */ -//undef SRT_DEBUG_TSBPD_WRAP 1 /* Debug packet timestamp wraparound */ -//undef SRT_DEBUG_TLPKTDROP_DROPSEQ 1 -//undef SRT_DEBUG_SNDQ_HIGHRATE 1 - - -/* -* SRT_ENABLE_CONNTIMEO -* Option UDT_CONNTIMEO added to the API to set/get the connection timeout. -* The UDT hard coded default of 3000 msec is too small for some large RTT (satellite) use cases. -* The SRT handshake (2 exchanges) needs 2 times the RTT to complete with no packet loss. -*/ -#define SRT_ENABLE_CONNTIMEO 1 - -/* -* SRT_ENABLE_NOCWND -* Set the congestion window at its max (then disabling it) to prevent stopping transmission -* when too many packets are not acknowledged. -* The congestion windows is the maximum distance in pkts since the last acknowledged packets. -*/ -#define SRT_ENABLE_NOCWND 1 - -/* -* SRT_ENABLE_NAKREPORT -* Send periodic NAK report for more efficient retransmission instead of relying on ACK timeout -* to retransmit all non-ACKed packets, very inefficient with real-time and no congestion window. -*/ -#define SRT_ENABLE_NAKREPORT 1 - -#define SRT_ENABLE_RCVBUFSZ_MAVG 1 /* Recv buffer size moving average */ -#define SRT_ENABLE_SNDBUFSZ_MAVG 1 /* Send buffer size moving average */ -#define SRT_MAVG_SAMPLING_RATE 40 /* Max sampling rate */ - -#define SRT_ENABLE_LOSTBYTESCOUNT 1 - - -/* -* SRT_ENABLE_IPOPTS -* Enable IP TTL and ToS setting -*/ -#define SRT_ENABLE_IPOPTS 1 - - -#define SRT_ENABLE_CLOSE_SYNCH 1 - -#endif /* SRT4UDT_H */ diff --git a/Vendor/SRT/Includes/udt.h b/Vendor/SRT/Includes/udt.h deleted file mode 100644 index 77f903bd5..000000000 --- a/Vendor/SRT/Includes/udt.h +++ /dev/null @@ -1,413 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the University of Illinois - nor the names of its contributors may be used to - endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** -written by - Yunhong Gu, last updated 01/18/2011 -modified by - Haivision Systems Inc. -*****************************************************************************/ - -/* WARNING!!! - * Since now this file is a "C and C++ header". - * It should be then able to be interpreted by C compiler, so - * all C++-oriented things must be ifdef'd-out by __cplusplus. - * - * Mind also comments - to prevent any portability problems, - * B/C++ comments (// -> EOL) should not be used unless the - * area is under __cplusplus condition already. - * - * NOTE: this file contains _STRUCTURES_ that are common to C and C++, - * plus some functions and other functionalities ONLY FOR C++. This - * file doesn't contain _FUNCTIONS_ predicted to be used in C - see udtc.h - */ - -#ifndef __UDT_H__ -#define __UDT_H__ - -#include "srt.h" - -/* -* SRT_ENABLE_THREADCHECK (THIS IS SET IN MAKEFILE NOT HERE) -*/ -#if defined(SRT_ENABLE_THREADCHECK) -#include -#else -#define THREAD_STATE_INIT(name) -#define THREAD_EXIT() -#define THREAD_PAUSED() -#define THREAD_RESUMED() -#define INCREMENT_THREAD_ITERATIONS() -#endif - -/* Obsolete way to define MINGW */ -#ifndef __MINGW__ -#if defined(__MINGW32__) || defined(__MINGW64__) -#define __MINGW__ 1 -#endif -#endif - -#ifdef __cplusplus -#include -#include -#include -#include -#endif - - -// Legacy/backward/deprecated -#define UDT_API SRT_API - -//////////////////////////////////////////////////////////////////////////////// - -//if compiling on VC6.0 or pre-WindowsXP systems -//use -DLEGACY_WIN32 - -//if compiling with MinGW, it only works on XP or above -//use -D_WIN32_WINNT=0x0501 - - -//////////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -// This facility is used only for select() function. -// This is considered obsolete and the epoll() functionality rather should be used. -typedef std::set ud_set; -#define UD_CLR(u, uset) ((uset)->erase(u)) -#define UD_ISSET(u, uset) ((uset)->find(u) != (uset)->end()) -#define UD_SET(u, uset) ((uset)->insert(u)) -#define UD_ZERO(uset) ((uset)->clear()) -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// Legacy names - -#define UDT_MSS SRTO_MSS -#define UDT_SNDSYN SRTO_SNDSYN -#define UDT_RCVSYN SRTO_RCVSYN -#define UDT_FC SRTO_FC -#define UDT_SNDBUF SRTO_SNDBUF -#define UDT_RCVBUF SRTO_RCVBUF -#define UDT_LINGER SRTO_LINGER -#define UDP_SNDBUF SRTO_UDP_SNDBUF -#define UDP_RCVBUF SRTO_UDP_RCVBUF -#define UDT_MAXMSG SRTO_MAXMSG -#define UDT_MSGTTL SRTO_MSGTTL -#define UDT_RENDEZVOUS SRTO_RENDEZVOUS -#define UDT_SNDTIMEO SRTO_SNDTIMEO -#define UDT_RCVTIMEO SRTO_RCVTIMEO -#define UDT_REUSEADDR SRTO_REUSEADDR -#define UDT_MAXBW SRTO_MAXBW -#define UDT_STATE SRTO_STATE -#define UDT_EVENT SRTO_EVENT -#define UDT_SNDDATA SRTO_SNDDATA -#define UDT_RCVDATA SRTO_RCVDATA -#define SRT_SENDER SRTO_SENDER -#define SRT_TSBPDMODE SRTO_TSBPDMODE -#define SRT_TSBPDDELAY SRTO_TSBPDDELAY -#define SRT_INPUTBW SRTO_INPUTBW -#define SRT_OHEADBW SRTO_OHEADBW -#define SRT_PASSPHRASE SRTO_PASSPHRASE -#define SRT_PBKEYLEN SRTO_PBKEYLEN -#define SRT_KMSTATE SRTO_KMSTATE -#define SRT_IPTTL SRTO_IPTTL -#define SRT_IPTOS SRTO_IPTOS -#define SRT_TLPKTDROP SRTO_TLPKTDROP -#define SRT_TSBPDMAXLAG SRTO_TSBPDMAXLAG -#define SRT_RCVNAKREPORT SRTO_NAKREPORT -#define SRT_CONNTIMEO SRTO_CONNTIMEO -#define SRT_SNDPBKEYLEN SRTO_SNDPBKEYLEN -#define SRT_RCVPBKEYLEN SRTO_RCVPBKEYLEN -#define SRT_SNDPEERKMSTATE SRTO_SNDPEERKMSTATE -#define SRT_RCVKMSTATE SRTO_RCVKMSTATE - -#define UDT_EPOLL_OPT SRT_EPOLL_OPT -#define UDT_EPOLL_IN SRT_EPOLL_IN -#define UDT_EPOLL_OUT SRT_EPOLL_OUT -#define UDT_EPOLL_ERR SRT_EPOLL_ERR - -/* Binary backward compatibility obsolete options */ -#define SRT_NAKREPORT SRT_RCVNAKREPORT - -#if !defined(SRT_DISABLE_LEGACY_UDTSTATUS) -#define UDTSTATUS SRT_SOCKSTATUS -#define INIT SRTS_INIT -#define OPENED SRTS_OPENED -#define LISTENING SRTS_LISTENING -#define CONNECTING SRTS_CONNECTING -#define CONNECTED SRTS_CONNECTED -#define BROKEN SRTS_BROKEN -#define CLOSING SRTS_CLOSING -#define CLOSED SRTS_CLOSED -#define NONEXIST SRTS_NONEXIST -#endif - -//////////////////////////////////////////////////////////////////////////////// - -struct CPerfMon -{ - // global measurements - int64_t msTimeStamp; // time since the UDT entity is started, in milliseconds - int64_t pktSentTotal; // total number of sent data packets, including retransmissions - int64_t pktRecvTotal; // total number of received packets - int pktSndLossTotal; // total number of lost packets (sender side) - int pktRcvLossTotal; // total number of lost packets (receiver side) - int pktRetransTotal; // total number of retransmitted packets - int pktRcvRetransTotal; // total number of retransmitted packets received - int pktSentACKTotal; // total number of sent ACK packets - int pktRecvACKTotal; // total number of received ACK packets - int pktSentNAKTotal; // total number of sent NAK packets - int pktRecvNAKTotal; // total number of received NAK packets - int64_t usSndDurationTotal; // total time duration when UDT is sending data (idle time exclusive) - - // local measurements - int64_t pktSent; // number of sent data packets, including retransmissions - int64_t pktRecv; // number of received packets - int pktSndLoss; // number of lost packets (sender side) - int pktRcvLoss; // number of lost packets (receiver side) - int pktRetrans; // number of retransmitted packets - int pktRcvRetrans; // number of retransmitted packets received - int pktSentACK; // number of sent ACK packets - int pktRecvACK; // number of received ACK packets - int pktSentNAK; // number of sent NAK packets - int pktRecvNAK; // number of received NAK packets - double mbpsSendRate; // sending rate in Mb/s - double mbpsRecvRate; // receiving rate in Mb/s - int64_t usSndDuration; // busy sending time (i.e., idle time exclusive) - int pktReorderDistance; // size of order discrepancy in received sequences - double pktRcvAvgBelatedTime; // average time of packet delay for belated packets (packets with sequence past the ACK) - int64_t pktRcvBelated; // number of received AND IGNORED packets due to having come too late - - // instant measurements - double usPktSndPeriod; // packet sending period, in microseconds - int pktFlowWindow; // flow window size, in number of packets - int pktCongestionWindow; // congestion window size, in number of packets - int pktFlightSize; // number of packets on flight - double msRTT; // RTT, in milliseconds - double mbpsBandwidth; // estimated bandwidth, in Mb/s - int byteAvailSndBuf; // available UDT sender buffer size - int byteAvailRcvBuf; // available UDT receiver buffer size -}; - -typedef SRTSOCKET UDTSOCKET; //legacy alias - -#ifdef __cplusplus - -// Class CUDTException exposed for C++ API. -// This is actually useless, unless you'd use a DIRECT C++ API, -// however there's no such API so far. The current C++ API for UDT/SRT -// is predicted to NEVER LET ANY EXCEPTION out of implementation, -// so it's useless to catch this exception anyway. - -class UDT_API CUDTException -{ -public: - - CUDTException(CodeMajor major = MJ_SUCCESS, CodeMinor minor = MN_NONE, int err = -1); - CUDTException(const CUDTException& e); - - ~CUDTException(); - - /// Get the description of the exception. - /// @return Text message for the exception description. - - const char* getErrorMessage(); - - /// Get the system errno for the exception. - /// @return errno. - - int getErrorCode() const; - - /// Get the system network errno for the exception. - /// @return errno. - - int getErrno() const; - /// Clear the error code. - - void clear(); - -private: - CodeMajor m_iMajor; // major exception categories - CodeMinor m_iMinor; // for specific error reasons - int m_iErrno; // errno returned by the system if there is any - std::string m_strMsg; // text error message - - std::string m_strAPI; // the name of UDT function that returns the error - std::string m_strDebug; // debug information, set to the original place that causes the error - -public: // Legacy Error Code - - static const int EUNKNOWN = SRT_EUNKNOWN; - static const int SUCCESS = SRT_SUCCESS; - static const int ECONNSETUP = SRT_ECONNSETUP; - static const int ENOSERVER = SRT_ENOSERVER; - static const int ECONNREJ = SRT_ECONNREJ; - static const int ESOCKFAIL = SRT_ESOCKFAIL; - static const int ESECFAIL = SRT_ESECFAIL; - static const int ECONNFAIL = SRT_ECONNFAIL; - static const int ECONNLOST = SRT_ECONNLOST; - static const int ENOCONN = SRT_ENOCONN; - static const int ERESOURCE = SRT_ERESOURCE; - static const int ETHREAD = SRT_ETHREAD; - static const int ENOBUF = SRT_ENOBUF; - static const int EFILE = SRT_EFILE; - static const int EINVRDOFF = SRT_EINVRDOFF; - static const int ERDPERM = SRT_ERDPERM; - static const int EINVWROFF = SRT_EINVWROFF; - static const int EWRPERM = SRT_EWRPERM; - static const int EINVOP = SRT_EINVOP; - static const int EBOUNDSOCK = SRT_EBOUNDSOCK; - static const int ECONNSOCK = SRT_ECONNSOCK; - static const int EINVPARAM = SRT_EINVPARAM; - static const int EINVSOCK = SRT_EINVSOCK; - static const int EUNBOUNDSOCK = SRT_EUNBOUNDSOCK; - static const int ESTREAMILL = SRT_EINVALMSGAPI; - static const int EDGRAMILL = SRT_EINVALBUFFERAPI; - static const int ENOLISTEN = SRT_ENOLISTEN; - static const int ERDVNOSERV = SRT_ERDVNOSERV; - static const int ERDVUNBOUND = SRT_ERDVUNBOUND; - static const int EINVALMSGAPI = SRT_EINVALMSGAPI; - static const int EINVALBUFFERAPI = SRT_EINVALBUFFERAPI; - static const int EDUPLISTEN = SRT_EDUPLISTEN; - static const int ELARGEMSG = SRT_ELARGEMSG; - static const int EINVPOLLID = SRT_EINVPOLLID; - static const int EASYNCFAIL = SRT_EASYNCFAIL; - static const int EASYNCSND = SRT_EASYNCSND; - static const int EASYNCRCV = SRT_EASYNCRCV; - static const int ETIMEOUT = SRT_ETIMEOUT; - static const int ECONGEST = SRT_ECONGEST; - static const int EPEERERR = SRT_EPEERERR; -}; - -namespace UDT -{ - -typedef CUDTException ERRORINFO; -//typedef UDT_SOCKOPT SOCKOPT; -typedef CPerfMon TRACEINFO; -typedef CBytePerfMon TRACEBSTATS; -typedef ud_set UDSET; - -UDT_API extern const SRTSOCKET INVALID_SOCK; -#undef ERROR -UDT_API extern const int ERROR; - -UDT_API int startup(); -UDT_API int cleanup(); -UDT_API UDTSOCKET socket(int af, int type, int protocol); -UDT_API int bind(UDTSOCKET u, const struct sockaddr* name, int namelen); -UDT_API int bind2(UDTSOCKET u, UDPSOCKET udpsock); -UDT_API int listen(UDTSOCKET u, int backlog); -UDT_API UDTSOCKET accept(UDTSOCKET u, struct sockaddr* addr, int* addrlen); -UDT_API int connect(UDTSOCKET u, const struct sockaddr* name, int namelen); -UDT_API int close(UDTSOCKET u); -UDT_API int getpeername(UDTSOCKET u, struct sockaddr* name, int* namelen); -UDT_API int getsockname(UDTSOCKET u, struct sockaddr* name, int* namelen); -UDT_API int getsockopt(UDTSOCKET u, int level, SRT_SOCKOPT optname, void* optval, int* optlen); -UDT_API int setsockopt(UDTSOCKET u, int level, SRT_SOCKOPT optname, const void* optval, int optlen); -UDT_API int send(UDTSOCKET u, const char* buf, int len, int flags); -UDT_API int recv(UDTSOCKET u, char* buf, int len, int flags); - -UDT_API int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl = -1, bool inorder = false, uint64_t srctime = 0); -UDT_API int recvmsg(UDTSOCKET u, char* buf, int len, uint64_t& srctime); -UDT_API int recvmsg(UDTSOCKET u, char* buf, int len); - -UDT_API int64_t sendfile(UDTSOCKET u, std::fstream& ifs, int64_t& offset, int64_t size, int block = 364000); -UDT_API int64_t recvfile(UDTSOCKET u, std::fstream& ofs, int64_t& offset, int64_t size, int block = 7280000); -UDT_API int64_t sendfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 364000); -UDT_API int64_t recvfile2(UDTSOCKET u, const char* path, int64_t* offset, int64_t size, int block = 7280000); - -// select and selectEX are DEPRECATED; please use epoll. -UDT_API int select(int nfds, UDSET* readfds, UDSET* writefds, UDSET* exceptfds, const struct timeval* timeout); -UDT_API int selectEx(const std::vector& fds, std::vector* readfds, - std::vector* writefds, std::vector* exceptfds, int64_t msTimeOut); - -UDT_API int epoll_create(); -UDT_API int epoll_add_usock(int eid, UDTSOCKET u, const int* events = NULL); -UDT_API int epoll_add_ssock(int eid, SYSSOCKET s, const int* events = NULL); -UDT_API int epoll_remove_usock(int eid, UDTSOCKET u); -UDT_API int epoll_remove_ssock(int eid, SYSSOCKET s); -UDT_API int epoll_update_usock(int eid, UDTSOCKET u, const int* events = NULL); -UDT_API int epoll_update_ssock(int eid, SYSSOCKET s, const int* events = NULL); -UDT_API int epoll_wait(int eid, std::set* readfds, std::set* writefds, int64_t msTimeOut, - std::set* lrfds = NULL, std::set* wrfds = NULL); -UDT_API int epoll_wait2(int eid, UDTSOCKET* readfds, int* rnum, UDTSOCKET* writefds, int* wnum, int64_t msTimeOut, - SYSSOCKET* lrfds = NULL, int* lrnum = NULL, SYSSOCKET* lwfds = NULL, int* lwnum = NULL); -UDT_API int epoll_uwait(const int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut); -UDT_API int epoll_release(int eid); -UDT_API ERRORINFO& getlasterror(); -UDT_API int getlasterror_code(); -UDT_API const char* getlasterror_desc(); -UDT_API int bstats(UDTSOCKET u, TRACEBSTATS* perf, bool clear = true); -UDT_API SRT_SOCKSTATUS getsockstate(UDTSOCKET u); - -// This is a C++ SRT API extension. This is not a part of legacy UDT API. -UDT_API void setloglevel(srt_logging::LogLevel::type ll); -UDT_API void addlogfa(srt_logging::LogFA fa); -UDT_API void dellogfa(srt_logging::LogFA fa); -UDT_API void resetlogfa(std::set fas); -UDT_API void resetlogfa(const int* fara, size_t fara_size); -UDT_API void setlogstream(std::ostream& stream); -UDT_API void setloghandler(void* opaque, SRT_LOG_HANDLER_FN* handler); -UDT_API void setlogflags(int flags); - -UDT_API bool setstreamid(UDTSOCKET u, const std::string& sid); -UDT_API std::string getstreamid(UDTSOCKET u); - -} // namespace UDT - -// This is a log configuration used inside SRT. -// Applications using SRT, if they want to use the logging mechanism -// are free to create their own logger configuration objects for their -// own logger FA objects, or create their own. The object of this type -// is required to initialize the logger FA object. -namespace srt_logging { struct LogConfig; } -UDT_API extern srt_logging::LogConfig srt_logger_config; - - -#endif /* __cplusplus */ - -#endif diff --git a/Vendor/SRT/Includes/version.h b/Vendor/SRT/Includes/version.h deleted file mode 100644 index 7033968e8..000000000 --- a/Vendor/SRT/Includes/version.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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/. - * - */ - -/***************************************************************************** -written by - Haivision Systems Inc. - *****************************************************************************/ - -#ifndef INC_SRT_VERSION_H -#define INC_SRT_VERSION_H - -// To construct version value -#define SRT_MAKE_VERSION(major, minor, patch) \ - ((patch) + ((minor)*0x100) + ((major)*0x10000)) -#define SRT_MAKE_VERSION_VALUE SRT_MAKE_VERSION - -#define SRT_VERSION_MAJOR 1 -#define SRT_VERSION_MINOR 5 -#define SRT_VERSION_PATCH 1 -/* #undef SRT_VERSION_BUILD */ - -#define SRT_VERSION_STRING "1.5.1" -#define SRT_VERSION_VALUE \ - SRT_MAKE_VERSION_VALUE( \ - SRT_VERSION_MAJOR, SRT_VERSION_MINOR, SRT_VERSION_PATCH ) - -#endif // INC_SRT_VERSION_H diff --git a/Vendor/SRT/build-xcframework.sh b/Vendor/SRT/build-xcframework.sh index 2c9a6fc56..114595937 100755 --- a/Vendor/SRT/build-xcframework.sh +++ b/Vendor/SRT/build-xcframework.sh @@ -11,10 +11,12 @@ if which $(pwd)/srt >/dev/null; then else git clone git@github.com:Haivision/srt.git pushd srt - git checkout refs/tags/v1.5.1 + git checkout refs/tags/v1.5.3 popd fi +cp srt/srtcore/*.h Includes + srt() { IOS_OPENSSL=$(pwd)/OpenSSL/$1 @@ -37,13 +39,11 @@ srt_macosx() { # macOS srt_macosx macosx arm64 -srt_macosx macosx x86_64 rm -f ./build/macosx/libsrt-lipo.a -lipo -create ./build/macosx/arm64/libsrt.a ./build/macosx/x86_64/libsrt.a -output ./build/macosx/libsrt-lipo.a -libtool -static -o ./build/macosx/libsrt.a ./build/macosx/libsrt-lipo.a ./OpenSSL/macosx/lib/libcrypto.a ./OpenSSL/macosx/lib/libssl.a +libtool -static -o ./build/macosx/libsrt.a ./build/macosx/arm64/libsrt.a ./OpenSSL/macosx/lib/libcrypto.a ./OpenSSL/macosx/lib/libssl.a # iOS -export IPHONEOS_DEPLOYMENT_TARGET=11.0 +export IPHONEOS_DEPLOYMENT_TARGET=12.0 SDKVERSION=$(xcrun --sdk iphoneos --show-sdk-version) srt iphonesimulator SIMULATOR64 x86_64 srt iphonesimulator SIMULATOR64 arm64 diff --git a/Vendor/SRT/libsrt.xcframework/Info.plist b/Vendor/SRT/libsrt.xcframework/Info.plist index db8313177..3a337d628 100644 --- a/Vendor/SRT/libsrt.xcframework/Info.plist +++ b/Vendor/SRT/libsrt.xcframework/Info.plist @@ -5,37 +5,43 @@ AvailableLibraries + BinaryPath + libsrt.a HeadersPath Headers LibraryIdentifier - ios-arm64_x86_64-simulator + ios-arm64 LibraryPath libsrt.a SupportedArchitectures arm64 - x86_64 SupportedPlatform ios - SupportedPlatformVariant - simulator + BinaryPath + libsrt.a HeadersPath Headers LibraryIdentifier - ios-arm64 + ios-arm64_x86_64-simulator LibraryPath libsrt.a SupportedArchitectures arm64 + x86_64 SupportedPlatform ios + SupportedPlatformVariant + simulator + BinaryPath + libsrt.a HeadersPath Headers LibraryIdentifier diff --git a/Vendor/SRT/libsrt.xcframework/ios-arm64/libsrt.a b/Vendor/SRT/libsrt.xcframework/ios-arm64/libsrt.a index 3fc12cbfc..41022b64d 100644 Binary files a/Vendor/SRT/libsrt.xcframework/ios-arm64/libsrt.a and b/Vendor/SRT/libsrt.xcframework/ios-arm64/libsrt.a differ diff --git a/Vendor/SRT/libsrt.xcframework/ios-arm64_x86_64-simulator/libsrt.a b/Vendor/SRT/libsrt.xcframework/ios-arm64_x86_64-simulator/libsrt.a index 47bbbf8f4..af1e7cbd8 100644 Binary files a/Vendor/SRT/libsrt.xcframework/ios-arm64_x86_64-simulator/libsrt.a and b/Vendor/SRT/libsrt.xcframework/ios-arm64_x86_64-simulator/libsrt.a differ diff --git a/Vendor/SRT/libsrt.xcframework/macos-arm64_x86_64/libsrt.a b/Vendor/SRT/libsrt.xcframework/macos-arm64_x86_64/libsrt.a index 81592cbd2..348913d6b 100644 Binary files a/Vendor/SRT/libsrt.xcframework/macos-arm64_x86_64/libsrt.a and b/Vendor/SRT/libsrt.xcframework/macos-arm64_x86_64/libsrt.a differ