mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	fix https://github.com/ossrs/srs/issues/3155 Build srt-1-fit fails with `standard attributes in middle of decl-specifiers` on GCC 12,Arch Linux. See https://github.com/Haivision/srt/releases/tag/v1.5.3
		
			
				
	
	
		
			498 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			498 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * 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 <map>
 | |
| #include <vector>
 | |
| #include <string>
 | |
| #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<SRT_SOCKSTATUS> 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<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 is necessary to be called from the group before the group clears
 | |
|     // the connection with the socket. As for managed groups (and there are
 | |
|     // currently no other group types), a socket disconnected from the group
 | |
|     // is no longer usable.
 | |
|     void setClosing()
 | |
|     {
 | |
|         core().m_bClosing = true;
 | |
|     }
 | |
| 
 | |
|     /// 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<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;
 | |
|     }
 | |
| 
 | |
|     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);
 | |
|     static bool inet6SettingsCompat(const sockaddr_any& muxaddr, const CSrtMuxerConfig& cfgMuxer,
 | |
|         const sockaddr_any& reqaddr, const CSrtMuxerConfig& 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
 |