mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
SRT: Upgrade libsrt from 1.4.1 to 1.5.1. v6.0.12 (#3362)
Co-authored-by: winlin <winlin@vip.126.com>
This commit is contained in:
parent
7a56208f2f
commit
fe086dfc31
143 changed files with 38185 additions and 15108 deletions
603
trunk/3rdparty/srt-1-fit/srtcore/api.h
vendored
603
trunk/3rdparty/srt-1-fit/srtcore/api.h
vendored
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* 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/.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -45,14 +45,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Yunhong Gu, last updated 09/28/2010
|
||||
Yunhong Gu, last updated 09/28/2010
|
||||
modified by
|
||||
Haivision Systems Inc.
|
||||
Haivision Systems Inc.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_API_H__
|
||||
#define __UDT_API_H__
|
||||
|
||||
#ifndef INC_SRT_API_H
|
||||
#define INC_SRT_API_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
@ -64,237 +63,425 @@ modified by
|
|||
#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();
|
||||
~CUDTSocket();
|
||||
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();
|
||||
}
|
||||
|
||||
SRT_SOCKSTATUS m_Status; //< current socket state
|
||||
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();
|
||||
}
|
||||
|
||||
/// 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()).
|
||||
uint64_t m_ClosureTimeStamp;
|
||||
~CUDTSocket();
|
||||
|
||||
int m_iIPversion; //< IP version
|
||||
sockaddr* m_pSelfAddr; //< pointer to the local address of the socket
|
||||
sockaddr* m_pPeerAddr; //< pointer to the peer address of the socket
|
||||
void construct();
|
||||
|
||||
SRTSOCKET m_SocketID; //< socket ID
|
||||
SRTSOCKET m_ListenSocket; //< ID of the listener socket; 0 means this is an independent socket
|
||||
SRT_ATTR_GUARDED_BY(m_ControlLock)
|
||||
sync::atomic<SRT_SOCKSTATUS> m_Status; //< current socket state
|
||||
|
||||
SRTSOCKET m_PeerID; //< peer socket ID
|
||||
int32_t m_iISN; //< initial sequence number, used to tell different connection from same IP:port
|
||||
/// 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;
|
||||
|
||||
CUDT* m_pUDT; //< pointer to the UDT entity
|
||||
sockaddr_any m_SelfAddr; //< local address of the socket
|
||||
sockaddr_any m_PeerAddr; //< peer address of the socket
|
||||
|
||||
std::set<SRTSOCKET>* m_pQueuedSockets; //< set of connections waiting for accept()
|
||||
std::set<SRTSOCKET>* m_pAcceptSockets; //< set of accept()ed connections
|
||||
SRTSOCKET m_SocketID; //< socket ID
|
||||
SRTSOCKET m_ListenSocket; //< ID of the listener socket; 0 means this is an independent socket
|
||||
|
||||
pthread_cond_t m_AcceptCond; //< used to block "accept" call
|
||||
pthread_mutex_t m_AcceptLock; //< mutex associated to m_AcceptCond
|
||||
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
|
||||
|
||||
unsigned int m_uiBackLog; //< maximum number of connections in queue
|
||||
|
||||
int m_iMuxID; //< multiplexer ID
|
||||
|
||||
pthread_mutex_t m_ControlLock; //< lock this socket exclusively for control APIs: bind/listen/connect
|
||||
|
||||
static int64_t getPeerSpec(SRTSOCKET id, int32_t isn)
|
||||
{
|
||||
return (id << 30) + isn;
|
||||
}
|
||||
int64_t getPeerSpec()
|
||||
{
|
||||
return getPeerSpec(m_PeerID, m_iISN);
|
||||
}
|
||||
int32_t m_iISN; //< initial sequence number, used to tell different connection from same IP:port
|
||||
|
||||
private:
|
||||
CUDTSocket(const CUDTSocket&);
|
||||
CUDTSocket& operator=(const CUDTSocket&);
|
||||
CUDT m_UDT; //< internal SRT socket logic
|
||||
|
||||
public:
|
||||
std::set<SRTSOCKET> 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 CRendezvousQueue;
|
||||
friend class CUDT;
|
||||
friend class CUDTGroup;
|
||||
friend class CRendezvousQueue;
|
||||
friend class CCryptoControl;
|
||||
|
||||
public:
|
||||
CUDTUnited();
|
||||
~CUDTUnited();
|
||||
CUDTUnited();
|
||||
~CUDTUnited();
|
||||
|
||||
// Public constants
|
||||
static const int32_t MAX_SOCKET_VAL = SRTGROUP_MASK - 1; // maximum value for a regular socket
|
||||
|
||||
public:
|
||||
|
||||
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 [in] af IP version, IPv4 (AF_INET) or IPv6 (AF_INET6).
|
||||
/// @param [in] type (ignored)
|
||||
/// @return The new UDT socket ID, or INVALID_SOCK.
|
||||
|
||||
SRTSOCKET newSocket(int af, int );
|
||||
|
||||
/// Create a new UDT connection.
|
||||
/// @param [in] listen the listening UDT socket;
|
||||
/// @param [in] peer peer address.
|
||||
/// @param [in,out] hs handshake information from peer side (in), negotiated value (out);
|
||||
/// @return If the new connection is successfully created: 1 success, 0 already exist, -1 error.
|
||||
|
||||
int newConnection(const SRTSOCKET listen, const sockaddr* peer, CHandShake* hs, const CPacket& hspkt,
|
||||
ref_t<SRT_REJECT_REASON> r_error);
|
||||
|
||||
int installAcceptHook(const SRTSOCKET lsn, srt_listen_callback_fn* hook, void* opaq);
|
||||
|
||||
/// look up the UDT entity according to its ID.
|
||||
/// @param [in] u the UDT socket ID.
|
||||
/// @return Pointer to the UDT entity.
|
||||
|
||||
CUDT* lookup(const SRTSOCKET u);
|
||||
|
||||
/// 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(const SRTSOCKET u, const sockaddr* name, int namelen);
|
||||
int bind(const SRTSOCKET u, UDPSOCKET udpsock);
|
||||
int listen(const SRTSOCKET u, int backlog);
|
||||
SRTSOCKET accept(const SRTSOCKET listen, sockaddr* addr, int* addrlen);
|
||||
int connect(const SRTSOCKET u, const sockaddr* name, int namelen, int32_t forced_isn);
|
||||
int close(const SRTSOCKET u);
|
||||
int getpeername(const SRTSOCKET u, sockaddr* name, int* namelen);
|
||||
int getsockname(const SRTSOCKET u, sockaddr* name, int* namelen);
|
||||
int select(ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout);
|
||||
int selectEx(const std::vector<SRTSOCKET>& fds, std::vector<SRTSOCKET>* readfds, std::vector<SRTSOCKET>* writefds, std::vector<SRTSOCKET>* exceptfds, int64_t msTimeOut);
|
||||
int epoll_create();
|
||||
int epoll_add_usock(const int eid, const SRTSOCKET u, const int* events = NULL);
|
||||
int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events = NULL);
|
||||
int epoll_remove_usock(const int eid, const SRTSOCKET u);
|
||||
int epoll_remove_ssock(const int eid, const SYSSOCKET s);
|
||||
int epoll_update_usock(const int eid, const SRTSOCKET u, const int* events = NULL);
|
||||
int epoll_update_ssock(const int eid, const SYSSOCKET s, const int* events = NULL);
|
||||
int epoll_wait(const int eid, std::set<SRTSOCKET>* readfds, std::set<SRTSOCKET>* writefds, int64_t msTimeOut, std::set<SYSSOCKET>* lrfds = NULL, std::set<SYSSOCKET>* lwfds = 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);
|
||||
|
||||
/// record the UDT exception.
|
||||
/// @param [in] e pointer to a UDT exception instance.
|
||||
|
||||
void setError(CUDTException* e);
|
||||
|
||||
/// look up the most recent UDT exception.
|
||||
/// @return pointer to a UDT exception instance.
|
||||
|
||||
CUDTException* getError();
|
||||
|
||||
private:
|
||||
// void init();
|
||||
|
||||
private:
|
||||
std::map<SRTSOCKET, CUDTSocket*> m_Sockets; // stores all the socket structures
|
||||
|
||||
pthread_mutex_t m_ControlLock; // used to synchronize UDT API
|
||||
|
||||
pthread_mutex_t m_IDLock; // used to synchronize ID generation
|
||||
SRTSOCKET m_SocketIDGenerator; // seed to generate a new unique socket ID
|
||||
|
||||
std::map<int64_t, std::set<SRTSOCKET> > m_PeerRec;// record sockets from peers to avoid repeated connection request, int64_t = (socker_id << 30) + isn
|
||||
|
||||
private:
|
||||
pthread_key_t m_TLSError; // thread local error record (last error)
|
||||
static void TLSDestroy(void* e) {if (NULL != e) delete (CUDTException*)e;}
|
||||
|
||||
private:
|
||||
CUDTSocket* locate(const SRTSOCKET u);
|
||||
CUDTSocket* locate(const sockaddr* peer, const SRTSOCKET id, int32_t isn);
|
||||
void updateMux(CUDTSocket* s, const sockaddr* addr = NULL, const UDPSOCKET* = NULL);
|
||||
void updateListenerMux(CUDTSocket* s, const CUDTSocket* ls);
|
||||
|
||||
private:
|
||||
std::map<int, CMultiplexer> m_mMultiplexer; // UDP multiplexer
|
||||
pthread_mutex_t m_MultiplexerLock;
|
||||
|
||||
private:
|
||||
CCache<CInfoBlock>* m_pCache; // UDT network information cache
|
||||
|
||||
private:
|
||||
volatile bool m_bClosing;
|
||||
pthread_mutex_t m_GCStopLock;
|
||||
pthread_cond_t m_GCStopCond;
|
||||
|
||||
pthread_mutex_t m_InitLock;
|
||||
int m_iInstanceCount; // number of startup() called by application
|
||||
bool m_bGCStatus; // if the GC thread is working (true)
|
||||
|
||||
pthread_t m_GCThread;
|
||||
static void* garbageCollect(void*);
|
||||
|
||||
std::map<SRTSOCKET, CUDTSocket*> m_ClosedSockets; // temporarily store closed sockets
|
||||
|
||||
void checkBrokenSockets();
|
||||
void removeSocket(const SRTSOCKET u);
|
||||
|
||||
CEPoll m_EPoll; // handling epoll data structures and events
|
||||
|
||||
private:
|
||||
CUDTUnited(const CUDTUnited&);
|
||||
CUDTUnited& operator=(const CUDTUnited&);
|
||||
};
|
||||
|
||||
// Debug support
|
||||
inline std::string SockaddrToString(const sockaddr* sadr)
|
||||
{
|
||||
void* addr =
|
||||
sadr->sa_family == AF_INET ?
|
||||
(void*)&((sockaddr_in*)sadr)->sin_addr
|
||||
: sadr->sa_family == AF_INET6 ?
|
||||
(void*)&((sockaddr_in6*)sadr)->sin6_addr
|
||||
: 0;
|
||||
// (cast to (void*) is required because otherwise the 2-3 arguments
|
||||
// of ?: operator would have different types, which isn't allowed in C++.
|
||||
if ( !addr )
|
||||
return "unknown:0";
|
||||
|
||||
std::ostringstream output;
|
||||
char hostbuf[1024];
|
||||
int flags;
|
||||
|
||||
#if ENABLE_GETNAMEINFO
|
||||
flags = NI_NAMEREQD;
|
||||
#else
|
||||
flags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||
#endif
|
||||
|
||||
if (!getnameinfo(sadr, sizeof(*sadr), hostbuf, 1024, NULL, 0, flags))
|
||||
enum ErrorHandling
|
||||
{
|
||||
output << hostbuf;
|
||||
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<SRTSOCKET>& fds,
|
||||
std::vector<SRTSOCKET>* readfds,
|
||||
std::vector<SRTSOCKET>* writefds,
|
||||
std::vector<SRTSOCKET>* 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 <class EntityType>
|
||||
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;
|
||||
}
|
||||
|
||||
output << ":" << ntohs(((sockaddr_in*)sadr)->sin_port); // TRICK: sin_port and sin6_port have the same offset and size
|
||||
return output.str();
|
||||
}
|
||||
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<SRTSOCKET, CUDTSocket*> sockets_t; // stores all the socket structures
|
||||
sockets_t m_Sockets;
|
||||
|
||||
#if ENABLE_BONDING
|
||||
typedef std::map<SRTSOCKET, CUDTGroup*> 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<int64_t, std::set<SRTSOCKET> >
|
||||
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<int, CMultiplexer> m_mMultiplexer; // UDP multiplexer
|
||||
sync::Mutex m_MultiplexerLock;
|
||||
|
||||
private:
|
||||
CCache<CInfoBlock>* m_pCache; // UDT network information cache
|
||||
|
||||
private:
|
||||
srt::sync::atomic<bool> 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue