38#define RESIPROCATE_SUBSYSTEM FlowManagerSubsystem::FLOWMANAGER
40#define LOG_PREFIX << mLocalBinding << " ComponentId=" << mComponentId << ", CallId=" << (mFlowContext ? mFlowContext->getSipCallId() : "") << ": "
46 case srtp_err_status_ok:
47 return "nothing to report";
49 case srtp_err_status_fail:
50 return "unspecified failure";
52 case srtp_err_status_bad_param:
53 return "unsupported parameter";
55 case srtp_err_status_alloc_fail:
56 return "couldn't allocate memory";
58 case srtp_err_status_dealloc_fail:
59 return "couldn't deallocate properly";
61 case srtp_err_status_init_fail:
62 return "couldn't initialize";
64 case srtp_err_status_terminus:
65 return "can't process as much data as requested";
67 case srtp_err_status_auth_fail:
68 return "authentication failure";
70 case srtp_err_status_cipher_fail:
71 return "cipher failure";
73 case srtp_err_status_replay_fail:
74 return "replay check failed (bad index)";
76 case srtp_err_status_replay_old:
77 return "replay check failed (index too old)";
79 case srtp_err_status_algo_fail:
80 return "algorithm failed test routine";
82 case srtp_err_status_no_such_op:
83 return "unsupported operation";
85 case srtp_err_status_no_ctx:
86 return "no appropriate context found";
88 case srtp_err_status_cant_check:
89 return "unable to perform desired validation";
91 case srtp_err_status_key_expired:
92 return "can't use key any more";
94 case srtp_err_status_socket_err:
95 return "error in use of socket";
97 case srtp_err_status_signal_err:
98 return "error in use POSIX signals";
100 case srtp_err_status_nonce_bad:
101 return "nonce check failed";
103 case srtp_err_status_read_fail:
104 return "couldn't read data";
106 case srtp_err_status_write_fail:
107 return "couldn't write data";
109 case srtp_err_status_parse_err:
110 return "error pasring data";
112 case srtp_err_status_encode_err:
113 return "error encoding data";
115 case srtp_err_status_semaphore_err:
116 return "error while using semaphores";
118 case srtp_err_status_pfkey_err:
119 return "error while using pfkey";
122 return "unrecognized error";
128 asio::ssl::context& sslContext,
130 unsigned int componentId,
134 std::shared_ptr<RTCPEventLoggingHandler> rtcpEventLoggingHandler,
135 std::shared_ptr<FlowContext> context)
136 : mIOService(ioService),
138 mSslContext(sslContext),
140 mComponentId(componentId),
141 mLocalBinding(localBinding),
142 mMediaStream(mediaStream),
143 mForceCOMedia(forceCOMedia),
144 mRtcpEventLoggingHandler(rtcpEventLoggingHandler),
145 mFlowContext(context),
148 mReservationToken(0),
149 mSharedMutex(std::make_shared<
resip::
Mutex>()),
150 mMutex(*mSharedMutex),
151 mActiveDestinationPort(0),
152 mFlowState(Unconnected),
153 mReceivedDataFifo(maxReceiveFifoDuration, maxReceiveFifoSize)
159 ErrLog(
LOG_PREFIX <<
"attempting to set an RTCPEventLoggingHandler for non-RTCP flow");
160 mRtcpEventLoggingHandler.reset();
166 mTurnSocket = std::make_shared<TurnAsyncUdpSocket>(mIOService,
this, mLocalBinding.
getAddress(), mLocalBinding.
getPort());
169 mTurnSocket = std::make_shared<TurnAsyncTcpSocket>(mIOService,
this, mLocalBinding.
getAddress(), mLocalBinding.
getPort());
173 mTurnSocket = std::make_shared<TurnAsyncTlsSocket>(mIOService,
203 std::map<reTurn::StunTuple, dtls::DtlsSocket*>::iterator it;
204 for(it = mDtlsSockets.begin(); it != mDtlsSockets.end(); it++)
214 mTurnSocket->disableTurnAsyncHandler();
215 mTurnSocket->close();
222 mReservationToken = reservationToken;
229 mAllocationProps = allocationProps;
231 if (mTurnSocket && mTurnSocket->getBindError())
235 const asio::error_code& e = mTurnSocket->getBindError();
236 ErrLog(
LOG_PREFIX <<
"Unable to bind to the local address and port, error=" << e.value() <<
"(" << e.message() <<
")");
237 mMediaStream.onFlowError(mComponentId, e.value());
252 changeFlowState(
Ready);
253 mMediaStream.onFlowReady(mComponentId);
267 return mTurnSocket ? mTurnSocket->getSocketDescriptor() : 0;
277 if(processSendData(buffer, size, mTurnSocket->getConnectedAddress(), mTurnSocket->getConnectedPort()))
279 mTurnSocket->send(buffer, size);
284 onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(
flowmanager::InvalidState, asio::error::misc_category));
289Flow::sendTo(
const asio::ip::address& address,
unsigned short port,
char* buffer,
unsigned int size)
294 if(processSendData(buffer, size, address, port))
296 mTurnSocket->sendTo(address, port, buffer, size);
301 onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(
flowmanager::InvalidState, asio::error::misc_category));
307Flow::rawSendTo(
const asio::ip::address& address,
unsigned short port,
const char* buffer,
unsigned int size)
310 mTurnSocket->sendTo(address, port, buffer, size);
315Flow::processSendData(
char* buffer,
unsigned int& size,
const asio::ip::address& address,
unsigned short port)
317 if(mRtcpEventLoggingHandler.get())
321 mRtcpEventLoggingHandler->outboundEvent(mFlowContext, mLocalBinding, dest, _buf);
326 if(status != srtp_err_status_ok)
329 onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(
flowmanager::SRTPError, asio::error::misc_category));
341 if(status != srtp_err_status_ok)
344 onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(
flowmanager::SRTPError, asio::error::misc_category));
348 else if(dtlsSocket || !mRemoteSDPFingerprint.
empty())
353 onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(
flowmanager::InvalidState, asio::error::misc_category));
366Flow::receiveFrom(
const asio::ip::address& address,
unsigned short port,
char* buffer,
unsigned int& size,
unsigned int timeout)
369 asio::error_code errorCode;
372 unsigned int recvTimeout;
376 if(timeout == 0 && mReceivedDataFifo.
empty())
382 recvTimeout = timeout ? (
unsigned int)(timeout - (
Timer::getTimeMs() - startTime)) : 0;
383 if(timeout != 0 && recvTimeout <= 0)
388 ReceivedData* receivedData = mReceivedDataFifo.
getNext(recvTimeout);
391 mFakeSelectSocketDescriptor.
receive();
394 if(address == receivedData->mAddress && port == receivedData->mPort)
396 errorCode = processReceivedData(buffer, size, receivedData);
412Flow::receive(
char* buffer,
unsigned int& size,
unsigned int timeout, asio::ip::address* sourceAddress,
unsigned short* sourcePort)
414 asio::error_code errorCode;
418 if(timeout == 0 && mReceivedDataFifo.
empty())
424 if(mReceivedDataFifo.
empty())
429 ReceivedData* receivedData = mReceivedDataFifo.
getNext(timeout);
432 mFakeSelectSocketDescriptor.
receive();
433 errorCode = processReceivedData(buffer, size, receivedData, sourceAddress, sourcePort);
447Flow::processReceivedData(
char* buffer,
unsigned int& size, ReceivedData* receivedData, asio::ip::address* sourceAddress,
unsigned short* sourcePort)
449 asio::error_code errorCode;
450 unsigned int receivedsize = (
unsigned int)receivedData->mData->size();
456 srtp_err_status_t status = mMediaStream.
srtpUnprotect((
void*)receivedData->mData->data(), (
int*)&receivedsize, mComponentId ==
RTCP_COMPONENT_ID);
457 if(status != srtp_err_status_ok)
471 if(status != srtp_err_status_ok)
477 else if(dtlsSocket || !mRemoteSDPFingerprint.
empty())
481 DebugLog(
LOG_PREFIX <<
"Discarding media from " << receivedData->mAddress.to_string() <<
":" << receivedData->mPort <<
", which has no DTLS-SRTP association");
488 if(size > receivedsize)
491 memcpy(buffer, receivedData->mData->data(), size);
497 InfoLog(
LOG_PREFIX <<
"Receive buffer too small for data size=" << receivedsize);
502 *sourceAddress = receivedData->mAddress;
506 *sourcePort = receivedData->mPort;
508 if(mRtcpEventLoggingHandler.get())
512 mRtcpEventLoggingHandler->inboundEvent(mFlowContext, _source, mLocalBinding, _buf);
523 asio::ip::address peerAddress = asio::ip::make_address(address);
528 if (peerAddress == mActiveDestinationAddress && port == mActiveDestinationPort)
533 mActiveDestinationAddress = peerAddress;
534 mActiveDestinationPort = port;
537 if(peerAddress.is_v4())
539 asio::ip::address_v4::bytes_type _bytes = peerAddress.to_v4().to_bytes();
541 mPrivatePeer = _bytes[0] == 10 ||
542 (_bytes[0] == 172 && (_bytes[1] & 0xf0) == 16) ||
543 (_bytes[0] == 192 && _bytes[1] == 168);
548 InfoLog(
LOG_PREFIX <<
"Connecting socket to remote peer " << address <<
":" << port << (mPrivatePeer ?
" [PRIVATE]" :
""));
550 mTurnSocket->connect(address, port);
554 InfoLog(
LOG_PREFIX <<
"Setting TURN destination to remote peer " << address <<
":" << port << (mPrivatePeer ?
" [PRIVATE]" :
""));
555 mTurnSocket->setActiveDestination(peerAddress, port);
577 mRemoteSDPFingerprintHashFunction = hashFunction;
578 mRemoteSDPFingerprint = fingerprint;
582 std::map<reTurn::StunTuple, dtls::DtlsSocket*>::iterator it;
583 for(it = mDtlsSockets.begin(); it != mDtlsSockets.end(); it++)
585 ((
FlowDtlsSocketContext*)it->second->getSocketContext())->checkRemoteFingerprint(hashFunction, fingerprint);
594 return mRemoteSDPFingerprint;
600 return mLocalBinding;
615 return mReflexiveTuple;
617 return mLocalBinding;
633 return mReflexiveTuple;
641 return mReservationToken;
645Flow::onConnectSuccess(
unsigned int socketDesc,
const asio::ip::address& address,
unsigned short port)
647 InfoLog(
LOG_PREFIX <<
"Flow::onConnectSuccess: socketDesc=" << socketDesc <<
", address=" << address.to_string() <<
", port=" << port);
656 mTurnSocket->bindRequest();
660 changeFlowState(
Ready);
661 mMediaStream.onFlowReady(mComponentId);
669 mReservationToken != 0 ? mReservationToken :
TurnAsyncSocket::UnspecifiedToken,
674 changeFlowState(
Ready);
675 mMediaStream.onFlowReady(mComponentId);
681Flow::onConnectFailure(
unsigned int socketDesc,
const asio::error_code& e)
683 WarningLog(
LOG_PREFIX <<
"Flow::onConnectFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
685 mMediaStream.onFlowError(mComponentId, e.value());
689Flow::onSharedSecretSuccess(
unsigned int socketDesc,
const char* username,
unsigned int usernameSize,
const char* password,
unsigned int passwordSize)
691 InfoLog(
LOG_PREFIX <<
"Flow::onSharedSecretSuccess: socketDesc=" << socketDesc <<
", username=" << username <<
", password=" << password);
695Flow::onSharedSecretFailure(
unsigned int socketDesc,
const asio::error_code& e)
697 WarningLog(
LOG_PREFIX <<
"Flow::onSharedSecretFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
701Flow::onBindSuccess(
unsigned int socketDesc,
const StunTuple& reflexiveTuple,
const StunTuple& stunServerTuple)
703 InfoLog(
LOG_PREFIX <<
"Flow::onBindingSuccess: socketDesc=" << socketDesc <<
", reflexive=" << reflexiveTuple);
706 mReflexiveTuple = reflexiveTuple;
708 changeFlowState(
Ready);
709 mMediaStream.onFlowReady(mComponentId);
713Flow::onBindFailure(
unsigned int socketDesc,
const asio::error_code& e,
const StunTuple& stunServerTuple)
715 WarningLog(
LOG_PREFIX <<
"Flow::onBindingFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
717 mMediaStream.onFlowError(mComponentId, e.value());
721Flow::onAllocationSuccess(
unsigned int socketDesc,
const StunTuple& reflexiveTuple,
const StunTuple& relayTuple,
unsigned int lifetime,
unsigned int bandwidth,
uint64_t reservationToken)
724 ", reflexive=" << reflexiveTuple <<
725 ", relay=" << relayTuple <<
726 ", lifetime=" << lifetime <<
727 ", bandwidth=" << bandwidth <<
728 ", reservationToken=" << reservationToken);
731 mReflexiveTuple = reflexiveTuple;
732 mRelayTuple = relayTuple;
733 mReservationToken = reservationToken;
735 changeFlowState(
Ready);
736 mMediaStream.onFlowReady(mComponentId);
740Flow::onAllocationFailure(
unsigned int socketDesc,
const asio::error_code& e)
742 WarningLog(
LOG_PREFIX <<
"Flow::onAllocationFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
744 mMediaStream.onFlowError(mComponentId, e.value());
748Flow::onRefreshSuccess(
unsigned int socketDesc,
unsigned int lifetime)
750 InfoLog(
LOG_PREFIX <<
"Flow::onRefreshSuccess: socketDesc=" << socketDesc <<
", lifetime=" << lifetime);
758Flow::onRefreshFailure(
unsigned int socketDesc,
const asio::error_code& e)
760 WarningLog(
LOG_PREFIX <<
"Flow::onRefreshFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
764Flow::onSetActiveDestinationSuccess(
unsigned int socketDesc)
766 InfoLog(
LOG_PREFIX <<
"Flow::onSetActiveDestinationSuccess: socketDesc=" << socketDesc);
770Flow::onSetActiveDestinationFailure(
unsigned int socketDesc,
const asio::error_code& e)
772 WarningLog(
LOG_PREFIX <<
"Flow::onSetActiveDestinationFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
776Flow::onClearActiveDestinationSuccess(
unsigned int socketDesc)
778 InfoLog(
LOG_PREFIX <<
"Flow::onClearActiveDestinationSuccess: socketDesc=" << socketDesc);
782Flow::onClearActiveDestinationFailure(
unsigned int socketDesc,
const asio::error_code& e)
784 WarningLog(
LOG_PREFIX <<
"Flow::onClearActiveDestinationFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
788Flow::onChannelBindRequestSent(
unsigned int socketDesc,
unsigned short channelNumber)
790 InfoLog(
LOG_PREFIX <<
"Flow::onChannelBindRequestSent: socketDesc=" << socketDesc <<
", channelNumber=" << channelNumber);
794Flow::onChannelBindSuccess(
unsigned int socketDesc,
unsigned short channelNumber)
796 InfoLog(
LOG_PREFIX <<
"Flow::onChannelBindSuccess: socketDesc=" << socketDesc <<
", channelNumber=" << channelNumber);
800Flow::onChannelBindFailure(
unsigned int socketDesc,
const asio::error_code& e)
802 WarningLog(
LOG_PREFIX <<
"Flow::onChannelBindFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
806Flow::onSendSuccess(
unsigned int socketDesc)
812Flow::onSendFailure(
unsigned int socketDesc,
const asio::error_code& e)
818 InfoLog(
LOG_PREFIX <<
"Flow::onSendFailure: socketDesc=" << socketDesc <<
" socket is not in correct state to send yet, state=" << flowStateToString(mFlowState));
822 WarningLog(
LOG_PREFIX <<
"Flow::onSendFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
827Flow::onReceiveSuccess(
unsigned int socketDesc,
const asio::ip::address& address,
unsigned short port,
const std::shared_ptr<reTurn::DataBuffer>& data)
829 StackLog(
LOG_PREFIX <<
"Flow::onReceiveSuccess: socketDesc=" << socketDesc <<
", fromAddress=" << address.to_string() <<
", fromPort=" << port <<
", size=" << data->size());
831 if(address != mTurnSocket->getConnectedAddress() || port != mTurnSocket->getConnectedPort())
833 if(mForceCOMedia &&
isReady() && mPrivatePeer)
835 DebugLog(<<
"Peer with private IP " << mTurnSocket->getConnectedAddress() <<
":" << mTurnSocket->getConnectedPort()
836 <<
" appears to be sending from " << address <<
":" << port);
849 DtlsSocket* dtlsSocket = getDtlsSocket(endpoint);
852 dtlsSocket->
handlePacketMaybe((
const unsigned char*) data->data(), data->size());
857 acceptDtlsSocketServer(endpoint, (
const unsigned char*) data->data(), data->size());
865 ReceivedData* receivedData =
new ReceivedData(address, port, data);
868 WarningLog(
LOG_PREFIX <<
"Flow::onReceiveSuccess: TimeLimitFifo is full (countDepth=" << mReceivedDataFifo.
getCountDepth() <<
", timeDepth=" << mReceivedDataFifo.
getTimeDepth() <<
") - discarding data! socketDesc=" << socketDesc <<
", fromAddress=" << address.to_string() <<
", fromPort=" << port <<
", size=" << data->size());
873 mFakeSelectSocketDescriptor.
send();
878Flow::onReceiveFailure(
unsigned int socketDesc,
const asio::error_code& e)
882 (e.value() == asio::error::connection_reset ||
883 e.value() == asio::error::connection_refused))
885 DebugLog(
LOG_PREFIX <<
"Flow::onReceiveFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
887 mTurnSocket->turnReceive();
891 WarningLog(<<
"Flow::onReceiveFailure: socketDesc=" << socketDesc <<
" error=" << e.value() <<
"(" << e.message() <<
")");
896Flow::onIncomingBindRequestProcessed(
unsigned int socketDesc,
const StunTuple& sourceTuple)
898 InfoLog(
LOG_PREFIX <<
"Flow::onIncomingBindRequestProcessed: socketDesc=" << socketDesc <<
", sourceTuple=" << sourceTuple);
903Flow::changeFlowState(FlowState newState)
905 InfoLog(
LOG_PREFIX <<
"Flow::changeState: oldState=" << flowStateToString(mFlowState) <<
", newState=" << flowStateToString(newState));
906 mFlowState = newState;
910Flow::flowStateToString(FlowState state)
915 return "Unconnected";
917 return "ConnectingServer";
936Flow::getDtlsSocket(
const StunTuple& endpoint)
938 std::map<reTurn::StunTuple, dtls::DtlsSocket*>::iterator it = mDtlsSockets.find(endpoint);
939 if(it != mDtlsSockets.end())
947Flow::createDtlsSocketClient(
const StunTuple& endpoint)
949 DtlsSocket* dtlsSocket = getDtlsSocket(endpoint);
956 mDtlsSockets[endpoint] = dtlsSocket;
963Flow::acceptDtlsSocketServer(
const StunTuple& endpoint,
const unsigned char* data,
size_t len)
970 std::map<reTurn::StunTuple, dtls::DtlsSocket*>::iterator evict = mDtlsSockets.end();
971 if(mDtlsSockets.size() >= MaxDtlsSockets)
978 for(std::map<reTurn::StunTuple, dtls::DtlsSocket*>::iterator it = mDtlsSockets.begin(); it != mDtlsSockets.end();)
985 DebugLog(
LOG_PREFIX <<
"Dropping DTLS socket for " << it->first <<
" (" << (rejected ?
"no SRTP" :
"handshake failed") <<
") to make room");
987 it = mDtlsSockets.erase(it);
994 if(mDtlsSockets.size() >= MaxDtlsSockets)
999 for(std::map<reTurn::StunTuple, dtls::DtlsSocket*>::iterator it = mDtlsSockets.begin(); it != mDtlsSockets.end(); ++it)
1004 (evict == mDtlsSockets.end() || socket->
getAge() > evict->second->getAge()))
1009 if(evict == mDtlsSockets.end())
1011 if(!mDtlsSocketLimitLogged)
1013 WarningLog(
LOG_PREFIX <<
"Already " << mDtlsSockets.size() <<
" DTLS sockets, ignoring DTLS from new endpoints, eg. " << endpoint);
1014 mDtlsSocketLimitLogged =
true;
1027 std::ostringstream peer;
1030 std::vector<unsigned char> response;
1031 DtlsSocket* dtlsSocket = mDtlsListener->handlePacket(data, len, peer.str(), response, [
this, &endpoint]()
1033 return std::unique_ptr<DtlsSocketContext>(new FlowDtlsSocketContext(*this, endpoint.getAddress(), endpoint.getPort()));
1035 if(!response.empty())
1042 if(evict != mDtlsSockets.end())
1044 WarningLog(
LOG_PREFIX <<
"Dropping the DTLS socket for " << evict->first <<
", whose handshake has been in progress for "
1045 << std::chrono::duration_cast<std::chrono::seconds>(evict->second->getAge()).count() <<
" seconds, to make room for " << endpoint);
1046 delete evict->second;
1047 mDtlsSockets.erase(evict);
1050 mDtlsSockets[endpoint] = dtlsSocket;
const char * srtp_error_string(srtp_err_status_t error)
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
DtlsSocket * createClient(std::unique_ptr< DtlsSocketContext > context)
static PacketType demuxPacket(const unsigned char *buf, size_t len)
std::unique_ptr< DtlsListener > createListener()
bool handshakeFailed() const
std::chrono::steady_clock::duration getAge() const
SocketType getSocketType()
DtlsSocketContext * getSocketContext()
bool handlePacketMaybe(const unsigned char *bytes, size_t len)
bool handshakeCompleted()
unsigned int getSocketDescriptor()
const resip::Data getRemoteSDPFingerprint()
Retrieves the stored remote SDP Fingerprint.
StunTuple getReflexiveTuple()
uint64_t getReservationToken()
Flow(asio::io_context &ioService, asio::ssl::context &sslContext, unsigned int componentId, const StunTuple &localBinding, MediaStream &mediaStream, bool forceCOMedia, std::shared_ptr< RTCPEventLoggingHandler > rtcpEventLoggingHandler=nullptr, std::shared_ptr< FlowContext > context=nullptr)
const StunTuple & getLocalTuple()
asio::error_code receiveFrom(const asio::ip::address &address, unsigned short port, char *buffer, unsigned int &size, unsigned int timeout)
unsigned int getSocketDescriptor()
friend class FlowDtlsSocketContext
void send(char *buffer, unsigned int size)
Turn Send Methods WARNING - if using Secure media, then there must be room at the end of the passed i...
void setRemoteSDPFingerprint(const resip::Data &hashFunction, const resip::Data &fingerprint)
This method should be called when remote fingerprint is discovered via SDP negotiation (RFC 8122 a=fi...
void rawSendTo(const asio::ip::address &address, unsigned short port, const char *buffer, unsigned int size)
void setActiveDestination(const char *address, unsigned short port)
Used to set where this flow should be sending to.
static int maxReceiveFifoDuration
static int dtlsHandshakeEvictionGrace
Seconds after which a server DTLS handshake still in progress gives up its place, when a flow already...
StunTuple getSessionTuple()
void sendTo(const asio::ip::address &address, unsigned short port, char *buffer, unsigned int size)
static int maxReceiveFifoSize
asio::error_code receive(char *buffer, unsigned int &size, unsigned int timeout, asio::ip::address *sourceAddress=0, unsigned short *sourcePort=0)
Receive Methods.
unsigned int getSelectSocketDescriptor()
Returns a socket descriptor that can be used in a select call WARNING - this descriptor should not be...
void startDtlsClient(const char *address, unsigned short port)
Dtls-Srtp Methods.
StunTuple getRelayTuple()
void activateFlow(uint8_t allocationProps=StunMessage::PropsNone)
static const uint8_t PropsNone
TransportType getTransportType() const
const asio::ip::address & getAddress() const
unsigned int getPort() const
static unsigned int UnspecifiedBandwidth
static unsigned int UnspecifiedLifetime
bool empty() const
is the queue empty?
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
const char * c_str() const
Returns a null-terminated string representing.
@ Share
The Data instance will use the buffer in a read-only mode.
bool empty() const noexcept
Checks whether the Data is empty.
virtual size_t getCountDepth() const
gets the depth of the FIFO
Msg * getNext()
Returns the first message available.
virtual time_t getTimeDepth() const
Return the time depth of the queue.
bool add(Msg *msg, DepthUsage usage)
Add a message to the fifo.
static uint64_t getTimeMs()
Returns the current clock time in milliseconds.
This class is used during media sessions that use Dtls-Srtp for a media transport.
static const ErrorType ReceiveTimeout
static const ErrorType InvalidState
static const ErrorType BufferTooSmall
static const ErrorType SRTPError
dcm! – add UnusedChecking(_enum) below;
std::mutex Mutex
A semaphore that can be locked by only one thread at a time.
std::unique_lock< Mutex > Lock
A convenience class to lock a Lockable (such as a Mutex) on object creation, and unlock on destructio...
unsigned __int64 uint64_t