2#include "../AsyncSocketBase.hxx"
7#include "../ReTurnSubsystem.hxx"
12#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN
18#define TURN_CHANNEL_BINDING_REFRESH_SECONDS 240
19#define SOFTWARE_STRING "reTURN Async Client 0.3 - RFC5389/turn-12 "
21#ifdef BOOST_ASIO_HAS_STD_CHRONO
22using namespace std::chrono;
25using namespace std::chrono;
39 const asio::ip::address& address,
40 unsigned short port) :
41 mIOService(ioService),
42 mTurnAsyncSocketHandler(turnAsyncSocketHandler),
43 mLocalBinding(
StunTuple::None , address, port),
45 mHaveAllocation(false),
46 mActiveDestination(0),
47 mAsyncSocketBase(asyncSocketBase),
48 mCloseAfterDestroyAllocationFinishes(false),
49 mAllocationTimer(ioService)
59 clearActiveRequestMap();
60 cancelAllocationTimer();
61 cancelChannelBindingTimers();
63 DebugLog(<<
"TurnAsyncSocket::~TurnAsyncSocket destroyed!");
80 asio::dispatch(
mIOService, weak_bind<
AsyncSocketBase,
void()>(mAsyncSocketBase.shared_from_this(), [
this] { doRequestSharedSecret(); }));
84TurnAsyncSocket::doRequestSharedSecret()
100 sendStunMessage(request);
107 Data username_copy{username}, password_copy{password};
112TurnAsyncSocket::doSetUsernameAndPassword(
Data&& username,
Data&& password,
bool shortTermAuth)
126 Data password_copy{password};
131TurnAsyncSocket::doSetLocalPassword(
Data&& password)
139 asio::dispatch(
mIOService, weak_bind<
AsyncSocketBase,
void()>(mAsyncSocketBase.shared_from_this(), [
this] { doBindRequest(); }));
143TurnAsyncSocket::doBindRequest()
155 sendStunMessage(request);
163 asio::dispatch(
mIOService, weak_bind<
AsyncSocketBase,
void()>(mAsyncSocketBase.shared_from_this(), [
RESIP_LAMBDA_CAPTURE_ALL_AND_THIS] { doConnectivityCheck(new StunTuple(targetAddr.getTransportType(), targetAddr.getAddress(), targetAddr.getPort()), peerRflxPriority, setIceControlling, setIceControlled, numRetransmits, retrans_iterval_ms); }));
167TurnAsyncSocket::doConnectivityCheck(
StunTuple* targetAddr,
uint32_t peerRflxPriority,
bool setIceControlling,
bool setIceControlled,
unsigned int numRetransmits,
unsigned int retrans_iterval_ms)
172 if (setIceControlling)
177 else if (setIceControlled)
183 sendStunMessage(request,
false, numRetransmits, retrans_iterval_ms, targetAddr);
189 unsigned int bandwidth,
190 unsigned char requestedProps,
198TurnAsyncSocket::doCreateAllocation(
unsigned int lifetimeSecs,
199 unsigned int bandwidth,
200 unsigned char requestedProps,
236 request->mHasTurnLifetime =
true;
237 request->mTurnLifetime = lifetimeSecs;
242 request->mHasTurnBandwidth =
true;
243 request->mTurnBandwidth = bandwidth;
250 request->mHasTurnRequestedTransport =
true;
270 request->mHasTurnEvenPort =
true;
271 request->mTurnEvenPort.propType = requestedProps;
273 else if(reservationToken != 0)
275 request->mHasTurnReservationToken =
true;
276 request->mTurnReservationToken = reservationToken;
279 sendStunMessage(request);
289TurnAsyncSocket::doRefreshAllocation(
unsigned int lifetimeSecs)
297 if(mCloseAfterDestroyAllocationFinishes)
308 request->mHasTurnLifetime =
true;
309 request->mTurnLifetime = lifetimeSecs;
317 sendStunMessage(request);
323 asio::dispatch(
mIOService, weak_bind<
AsyncSocketBase,
void()>(mAsyncSocketBase.shared_from_this(), [
this] { doDestroyAllocation(); }));
327TurnAsyncSocket::doDestroyAllocation()
329 doRefreshAllocation(0);
339TurnAsyncSocket::doSetActiveDestination(
const asio::ip::address& address,
unsigned short port)
355 DebugLog(<<
"TurnAsyncSocket::doSetActiveDestination: Active Destination set to: " << remoteTuple);
360void TurnAsyncSocket::doChannelBinding(RemotePeer& remotePeer)
366 request->mHasTurnChannelNumber =
true;
367 request->mTurnChannelNumber = remotePeer.getChannel();
368 request->mCntTurnXorPeerAddress = 1;
372 sendStunMessage(request);
377 remotePeer.setChannelConfirmed();
387 asio::dispatch(
mIOService, weak_bind<
AsyncSocketBase,
void()>(mAsyncSocketBase.shared_from_this(), [
this] { doClearActiveDestination(); }));
391TurnAsyncSocket::doClearActiveDestination()
407TurnAsyncSocket::createNewStunMessage(
uint16_t stunclass,
uint16_t method,
bool addAuthInfo)
410 msg->createHeader(stunclass, method);
420 msg->mHasMessageIntegrity =
true;
436TurnAsyncSocket::sendStunMessage(
StunMessage* message,
bool reTransmission,
unsigned int numRetransmits,
unsigned int retrans_iterval_ms,
const StunTuple* targetAddress)
438 constexpr size_t REQUEST_BUFFER_SIZE = 4096;
440 unsigned int bufferSize;
441 bufferSize = message->stunEncodeMessage((
char*)buffer->data(), REQUEST_BUFFER_SIZE);
442 buffer->truncate(bufferSize);
449 const auto requestEntry = std::make_shared<RequestEntry>(
mIOService,
this, message, numRetransmits, retrans_iterval_ms, targetAddress);
450 mActiveRequestMap[message->mHeader.magicCookieAndTid] = requestEntry;
451 requestEntry->startTimer();
461 sendToUnframed(targetAddress->getAddress(), targetAddress->getPort(), buffer);
473 if(data->size() <= 4)
475 WarningLog(<<
"TurnAsyncSocket::handleReceivedData: not enough data received (" << data->size() <<
" bytes) for stun or channel data message - discarding!");
482 const unsigned char firstByte = (*data)[0];
487 &(*data)[0], (
unsigned int)data->size());
490 handleStunMessage(stunMsg);
503 DebugLog(<<
"TurnAsyncSocket::handleReceivedData: neither STUN nor channel data received from " << address.to_string() <<
":" << port <<
" while allocated - discarding");
514 unsigned short channelNumber;
515 memcpy(&channelNumber, &(*data)[0], 2);
516 channelNumber = ntohs(channelNumber);
521 unsigned short dataLen;
522 memcpy(&dataLen, &(*data)[2], 2);
523 dataLen = ntohs(dataLen);
525 if(data->size() < (
unsigned int)dataLen+4)
527 WarningLog(<<
"ChannelData message size=" << dataLen+4 <<
" too large for UDP packet size=" << data->size() <<
". Dropping.");
543 WarningLog(<<
"TurnAsyncSocket::handleReceivedData: receive channel data for non-existing channel - discarding!");
548TurnAsyncSocket::handleStunMessage(
StunMessage& stunMessage)
550 asio::error_code errorCode;
558 WarningLog(<<
"TurnAsyncSocket::handleStunMessage: Stun message integrity is bad!");
566 WarningLog(<<
"TurnAsyncSocket::handleStunMessage: Stun message integrity is bad!");
572 switch(stunMessage.
mClass)
583 response->mMethod = stunMessage.
mMethod;
584 response->setErrorCode(420,
"Unknown Attribute");
588 response->mHasUnknownAttributes =
true;
595 sendStunMessage(response);
599 errorCode = handleBindRequest(stunMessage);
609 response->mMethod = stunMessage.
mMethod;
610 response->setErrorCode(400,
"Invalid Request Method");
618 sendStunMessage(response);
630 WarningLog(<<
"Ignoring DataInd with unknown comprehension required attributes.");
635 errorCode = handleDataInd(stunMessage);
654 WarningLog(<<
"Ignoring Response with unknown comprehension required attributes.");
660 if(it == mActiveRequestMap.end())
667 const auto requestEntry = it->second;
668 mActiveRequestMap.erase(it);
669 requestEntry->stopTimer();
685 StunMessage* newRequest = requestEntry->mRequestMessage;
686 requestEntry->mRequestMessage = 0;
688 newRequest->createHeader(newRequest->mClass, newRequest->mMethod);
689 newRequest->mHasMessageIntegrity =
true;
694 sendStunMessage(newRequest);
701 errorCode = handleBindResponse(*requestEntry->mRequestMessage, stunMessage);
704 errorCode = handleSharedSecretResponse(*requestEntry->mRequestMessage, stunMessage);
707 errorCode = handleAllocateResponse(*requestEntry->mRequestMessage, stunMessage);
710 errorCode = handleRefreshResponse(*requestEntry->mRequestMessage, stunMessage);
713 errorCode = handleChannelBindResponse(*requestEntry->mRequestMessage, stunMessage);
730 WarningLog(<<
"TurnAsyncSocket::handleStunMessage: Read Invalid StunMsg.");
737TurnAsyncSocket::handleDataInd(
StunMessage& stunMessage)
739 if(stunMessage.mCntTurnXorPeerAddress == 0 || !stunMessage.mHasTurnData)
742 WarningLog(<<
"TurnAsyncSocket::handleDataInd: DataInd missing attributes.");
746 StunTuple remoteTuple;
753 const auto data = std::make_shared<DataBuffer>(stunMessage.mTurnData->data(), stunMessage.mTurnData->size());
756 remoteTuple.getAddress(),
757 remoteTuple.getPort(),
760 return asio::error_code();
774 WarningLog(<<
"TurnAsyncSocket::handleChannelBindResponse: Received ChannelBindResponse for unknown channel (" << response.mTurnChannelNumber <<
") - discarding");
781 DebugLog(<<
"TurnAsyncSocket::handleChannelBindResponse: Channel " << remotePeer->getChannel() <<
" is now bound to " << remotePeer->getPeerTuple());
782 remotePeer->refresh();
783 remotePeer->setChannelConfirmed();
784 startChannelBindingTimer(remotePeer->getChannel());
792 if(response.mHasErrorCode)
794 ErrLog(<<
"TurnAsyncSocket::handleChannelBindResponse: Received ChannelBindResponse error: " << response.mErrorCode.errorClass * 100 + response.mErrorCode.number);
795 asio::error_code ec(response.mErrorCode.errorClass * 100 + response.mErrorCode.number, asio::error::misc_category);
802 ErrLog(<<
"TurnAsyncSocket::handleChannelBindResponse: Received ChannelBindResponse error but no error code attribute found.");
809 return asio::error_code();
818 if(!response.mHasUsername || !response.mHasPassword)
820 WarningLog(<<
"TurnAsyncSocket::handleSharedSecretResponse: Stun response message for SharedSecretRequest is missing username and/or password!");
828 response.mPassword->c_str(), (
unsigned int)response.mPassword->size());
833 if(response.mHasErrorCode)
845 return asio::error_code();
849TurnAsyncSocket::handleBindRequest(
StunMessage& stunMessage)
859 response->mHeader.magicCookieAndTid = stunMessage.mHeader.magicCookieAndTid;
862 response->mHasXorMappedAddress =
true;
872 if (stunMessage.mHasMessageIntegrity)
874 response->mHasMessageIntegrity =
true;
878 if (stunMessage.mHasIceControlled || stunMessage.mHasIceControlling || stunMessage.mHasIcePriority)
880 response->mHasFingerprint =
true;
884 DebugLog(<<
"Sending response to BIND to " << stunMessage.mRemoteTuple);
890 return asio::error_code();
898 StunTuple reflexiveTuple;
900 if(response.mHasXorMappedAddress)
904 else if(response.mHasMappedAddress)
919 if(response.mHasErrorCode)
931 return asio::error_code();
939 StunTuple reflexiveTuple;
940 StunTuple relayTuple;
941 if(response.mHasXorMappedAddress)
946 if(response.mHasTurnXorRelayedAddress)
951 if(response.mHasTurnLifetime)
964 startAllocationTimer();
970 response.mHasTurnBandwidth ? response.mTurnBandwidth : 0,
971 response.mHasTurnReservationToken ? response.mTurnReservationToken : 0);
982 if(response.mHasErrorCode)
994 return asio::error_code();
1002 if(response.mHasTurnLifetime)
1013 startAllocationTimer();
1018 if(mCloseAfterDestroyAllocationFinishes)
1026 cancelAllocationTimer();
1033 if(mCloseAfterDestroyAllocationFinishes)
1042 if(response.mHasErrorCode)
1048 if(mCloseAfterDestroyAllocationFinishes)
1050 cancelAllocationTimer();
1054 else if(response.mErrorCode.errorClass == 4 && response.mErrorCode.number == 37)
1056 cancelAllocationTimer();
1067 if(mCloseAfterDestroyAllocationFinishes)
1069 cancelAllocationTimer();
1076 return asio::error_code();
1082 sendFramed(std::make_shared<DataBuffer>(buffer, size));
1088 sendToFramed(address, port, std::make_shared<DataBuffer>(buffer, size));
1107 mAsyncSocketBase.
send(destination, data);
1114 mAsyncSocketBase.
send(destination, data);
1118TurnAsyncSocket::doSendFramed(
const std::shared_ptr<DataBuffer>& data)
1131 DebugLog(<<
"no allocation, can't send!");
1136TurnAsyncSocket::doSendToFramed(
const asio::ip::address& address,
unsigned short port,
const std::shared_ptr<DataBuffer>& data)
1154 doChannelBinding(*remotePeer);
1156 return sendToRemotePeer(*remotePeer, data);
1160TurnAsyncSocket::sendToRemotePeer(RemotePeer& remotePeer,
const std::shared_ptr<DataBuffer>& data)
1162 if(remotePeer.isChannelConfirmed())
1165 sendOverChannel(remotePeer.getChannel(), data);
1173 ind->mCntTurnXorPeerAddress = 1;
1175 if(data->size() > 0)
1177 ind->setTurnData(data->data(), (
unsigned int)data->size());
1181 sendStunMessage(ind);
1188 Data software_copy{software};
1193TurnAsyncSocket::doSetSoftware(
Data&& software)
1198 if(unpaddedSize > 0)
1201 const uint32_t remainder = unpaddedSize % 4,
1202 paddedSize = remainder ? unpaddedSize + 4 - remainder : unpaddedSize;
1212 mAsyncSocketBase.
connect(address, port);
1222TurnAsyncSocket::doClose()
1228 mCloseAfterDestroyAllocationFinishes =
true;
1238TurnAsyncSocket::actualClose()
1240 clearActiveRequestMap();
1241 cancelAllocationTimer();
1242 cancelChannelBindingTimers();
1243 mAsyncSocketBase.
close();
1262TurnAsyncSocket::sendOverChannel(
unsigned short channel,
const std::shared_ptr<DataBuffer>& data)
1265 mAsyncSocketBase.
send(destination, channel, data);
1268TurnAsyncSocket::RequestEntry::RequestEntry(asio::io_context& ioService,
1269 TurnAsyncSocket* turnAsyncSocket,
1272 unsigned int retrans_interval_ms,
1273 const StunTuple* dest)
1275 mIOService(ioService),
1276 mTurnAsyncSocket(turnAsyncSocket),
1277 mRequestMessage(requestMessage),
1278 mRequestTimer(ioService),
1280 mDest(dest ? new StunTuple(dest->getTransportType(), dest->getAddress(), dest->getPort()) : 0),
1282 mRetransIntervalMs(retrans_interval_ms)
1290TurnAsyncSocket::RequestEntry::startTimer()
1294 mRequestTimer.expires_after(milliseconds(mTimeout));
1295 mRequestTimer.async_wait(weak_bind<RequestEntry,
void(
const asio::error_code&)>(shared_from_this(), std::bind(&TurnAsyncSocket::RequestEntry::requestTimerExpired,
this, std::placeholders::_1)));
1299TurnAsyncSocket::RequestEntry::stopTimer()
1303 mRequestTimer.cancel();
1306TurnAsyncSocket::RequestEntry::~RequestEntry()
1313 delete mRequestMessage;
1323TurnAsyncSocket::RequestEntry::requestTimerExpired(
const asio::error_code& e)
1325 if(!e && mRequestMessage)
1329 if(mTurnAsyncSocket->mLocalBinding.getTransportType() !=
StunTuple::UDP || mRequestsSent == mRc)
1331 mTurnAsyncSocket->requestTimeout(mRequestMessage->mHeader.magicCookieAndTid);
1337 if(mRequestsSent == mRc - 1)
1343 mTimeout = (mTimeout*2);
1348 mTimeout = mRetransIntervalMs;
1352 DebugLog(<<
"RequestEntry::requestTimerExpired: retransmitting...");
1361TurnAsyncSocket::requestTimeout(
UInt128 tid)
1363 RequestMap::iterator it = mActiveRequestMap.find(tid);
1364 if (it != mActiveRequestMap.end())
1366 const auto requestEntry = it->second;
1367 mActiveRequestMap.erase(tid);
1369 switch (requestEntry->mRequestMessage->mMethod)
1394 if (mCloseAfterDestroyAllocationFinishes)
1414TurnAsyncSocket::clearActiveRequestMap()
1417 RequestMap::iterator it = mActiveRequestMap.begin();
1418 for(;it != mActiveRequestMap.end(); it++)
1420 it->second->stopTimer();
1422 mActiveRequestMap.clear();
1426TurnAsyncSocket::startAllocationTimer()
1428 mAllocationTimer.expires_after(seconds((
mLifetime*5)/8));
1429 mAllocationTimer.async_wait(weak_bind<AsyncSocketBase,
void(
const asio::error_code&)>(mAsyncSocketBase.shared_from_this(), std::bind(&TurnAsyncSocket::allocationTimerExpired,
this, std::placeholders::_1)));
1433TurnAsyncSocket::cancelAllocationTimer()
1435 mAllocationTimer.cancel();
1439TurnAsyncSocket::allocationTimerExpired(
const asio::error_code& e)
1446TurnAsyncSocket::startChannelBindingTimer(
unsigned short channel)
1448 ChannelBindingTimerMap::iterator it = mChannelBindingTimers.find(channel);
1449 if(it==mChannelBindingTimers.end())
1451 std::pair<ChannelBindingTimerMap::iterator,bool> ret =
1452 mChannelBindingTimers.insert(std::pair<unsigned short, asio::steady_timer*>(channel,
new asio::steady_timer(
mIOService)));
1457 it->second->async_wait(weak_bind<AsyncSocketBase,
void(
const asio::error_code&)>( mAsyncSocketBase.shared_from_this(), std::bind(&TurnAsyncSocket::channelBindingTimerExpired,
this, std::placeholders::_1, channel)));
1461TurnAsyncSocket::cancelChannelBindingTimers()
1464 ChannelBindingTimerMap::iterator it = mChannelBindingTimers.begin();
1465 for(;it!=mChannelBindingTimers.end();it++)
1467 it->second->cancel();
1470 mChannelBindingTimers.clear();
1474TurnAsyncSocket::channelBindingTimerExpired(
const asio::error_code& e,
unsigned short channel)
1481 doChannelBinding(*remotePeer);
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
#define TURN_CHANNEL_BINDING_REFRESH_SECONDS
#define UDP_FINAL_REQUEST_TIME
#define TCP_RESPONSE_TIME
#define UDP_MAX_RETRANSMITS
#define DEFAULT_RETRANS_INTERVAL_MS
asio::ip::address & getConnectedAddress() noexcept
virtual void doFramedReceive()
static std::shared_ptr< DataBuffer > allocateBuffer(size_t size)
Utility API.
unsigned short getConnectedPort() const noexcept
std::function< void(unsigned int)> BeforeClosedHandler
virtual void setOnBeforeSocketClosedFp(BeforeClosedHandler fp)
bool isConnected() const noexcept
virtual void send(const StunTuple &destination, const std::shared_ptr< DataBuffer > &data)
Note: destination is ignored for TCP and TLS connections.
virtual void connect(const std::string &address, unsigned short port)=0
RemotePeer * findRemotePeerByChannel(unsigned short channelNumber)
RemotePeer * findRemotePeerByPeerAddress(const StunTuple &peerAddress)
RemotePeer * createChannelBinding(const StunTuple &peerTuple)
const StunTuple & getPeerTuple() const
static const uint16_t StunClassSuccessResponse
static const uint16_t SharedSecretMethod
static const uint16_t BindMethod
static const uint8_t PropsNone
void setIceUseCandidate()
static const uint16_t TurnSendMethod
StunAtrUnknown mUnknownRequiredAttributes
static const uint16_t StunClassErrorResponse
static const uint16_t StunClassRequest
void calculateHmacKey(resip::Data &hmacKey, const resip::Data &longtermAuthenticationPassword)
static const uint16_t TurnAllocateMethod
bool checkMessageIntegrity(const resip::Data &hmacKey)
static const uint32_t RequestedTransportTcp
static const uint16_t TurnDataMethod
static void setStunAtrAddressFromTuple(StunAtrAddress &address, const StunTuple &tuple)
static const uint16_t TurnRefreshMethod
static const uint32_t RequestedTransportUdp
void setIcePriority(uint32_t priority)
static const uint16_t TurnChannelBindMethod
static const uint16_t StunClassIndication
static void setTupleFromStunAtrAddress(StunTuple &tuple, const StunAtrAddress &address)
TransportType getTransportType() const
const asio::ip::address & getAddress() const
unsigned int getPort() const
virtual void onRefreshSuccess(unsigned int socketDesc, unsigned int lifetimeSecs)=0
virtual void onReceiveFailure(unsigned int socketDesc, const asio::error_code &e)=0
virtual void onBindSuccess(unsigned int socketDesc, const StunTuple &reflexiveTuple, const StunTuple &stunServerTuple)=0
virtual void onSharedSecretFailure(unsigned int socketDesc, const asio::error_code &e)=0
virtual void onClearActiveDestinationFailure(unsigned int socketDesc, const asio::error_code &e)=0
virtual void onBindFailure(unsigned int socketDesc, const asio::error_code &e, const StunTuple &stunServerTuple)=0
virtual void onAllocationSuccess(unsigned int socketDesc, const StunTuple &reflexiveTuple, const StunTuple &relayTuple, unsigned int lifetimeSecs, unsigned int bandwidth, uint64_t reservationToken)=0
virtual void onIncomingBindRequestProcessed(unsigned int socketDesc, const StunTuple &sourceTuple)=0
virtual void onChannelBindRequestSent(unsigned int socketDesc, unsigned short channelNumber)=0
virtual void onChannelBindSuccess(unsigned int socketDesc, unsigned short channelNumber)=0
virtual void onSharedSecretSuccess(unsigned int socketDesc, const char *username, unsigned int usernameSize, const char *password, unsigned int passwordSize)=0
virtual void onChannelBindFailure(unsigned int socketDesc, const asio::error_code &e)=0
virtual void onRefreshFailure(unsigned int socketDesc, const asio::error_code &e)=0
virtual void onSetActiveDestinationSuccess(unsigned int socketDesc)=0
virtual void onAllocationFailure(unsigned int socketDesc, const asio::error_code &e)=0
virtual void onClearActiveDestinationSuccess(unsigned int socketDesc)=0
virtual void onReceiveSuccess(unsigned int socketDesc, const asio::ip::address &address, unsigned short port, const std::shared_ptr< DataBuffer > &data)=0
virtual ~TurnAsyncSocket()
ChannelManager mChannelManager
resip::Data mLocalHmacKey
void refreshAllocation(unsigned int lifetimeSecs)
RemotePeer * mActiveDestination
virtual unsigned int getSocketDescriptor()=0
virtual void turnReceive()
resip::RecursiveMutex mHandlerMutex
virtual void sendUnframed(const std::shared_ptr< DataBuffer > &data)
void connectivityCheck(const StunTuple &targetAddr, uint32_t peerRflxPriority, bool setIceControlling, bool setIceControlled, unsigned int numRetransmits, unsigned int retrans_iterval_ms)
void requestSharedSecret()
virtual void sendToFramed(const asio::ip::address &address, unsigned short port, const std::shared_ptr< DataBuffer > &data)
static unsigned int UnspecifiedBandwidth
void setUsernameAndPassword(const char *username, const char *password, bool shortTermAuth=false)
void handleReceivedData(const asio::ip::address &address, unsigned short port, const std::shared_ptr< DataBuffer > &data)
void connect(const std::string &address, unsigned short port)
StunTuple::TransportType mRelayTransportType
void createAllocation(unsigned int lifetimeSecs=UnspecifiedLifetime, unsigned int bandwidth=UnspecifiedBandwidth, unsigned char requestedPortProps=StunMessage::PropsNone, uint64_t reservationToken=UnspecifiedToken, StunTuple::TransportType requestedTransportType=StunTuple::None)
virtual void sendToUnframed(const asio::ip::address &address, unsigned short port, const std::shared_ptr< DataBuffer > &data)
TurnAsyncSocketHandler * mTurnAsyncSocketHandler
void clearActiveDestination()
asio::io_context & mIOService
void setSoftware(const char *software)
StunTuple::TransportType mRequestedTransportType
static asio::ip::address UnspecifiedIpAddress
virtual void sendTo(const asio::ip::address &address, unsigned short port, const char *buffer, size_t size)
virtual void sendFramed(const std::shared_ptr< DataBuffer > &data)
static unsigned short UnspecifiedToken
void setActiveDestination(const asio::ip::address &address, unsigned short port)
TurnAsyncSocket(asio::io_context &ioService, AsyncSocketBase &asyncSocketBase, TurnAsyncSocketHandler *turnAsyncSocketHandler, const asio::ip::address &address=UnspecifiedIpAddress, unsigned short port=0)
static unsigned int UnspecifiedLifetime
void handleChannelData(const std::shared_ptr< DataBuffer > &data)
virtual void setOnBeforeSocketClosedFp(AsyncSocketBase::BeforeClosedHandler fp)
virtual void send(const char *buffer, size_t size)
void setLocalPassword(const char *password)
virtual void disableTurnAsyncHandler()
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
const char * c_str() const
Returns a null-terminated string representing.
Data & append(const char *str, size_type len)
Appends the specified number of bytes to the end of this Data.
bool empty() const noexcept
Checks whether the Data is empty.
size_type size() const noexcept
Returns the number of bytes in this Data.
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
#define RESIP_LAMBDA_CAPTURE_ALL_AND_THIS
Lambda capture default that also captures 'this'.
static const ErrorType ErrorParsingMessage
static const ErrorType NotConnected
static const ErrorType InvalidChannelNumberReceived
static const ErrorType BadMessageIntegrity
static const ErrorType MissingAttributes
static const ErrorType ResponseTimeout
static const ErrorType NoAllocation
static const ErrorType AlreadyAllocated
static const ErrorType UnknownRequiredAttributes
static const ErrorType StrayResponse
static const ErrorType FrameError
static const ErrorType InvalidRequestedTransport
dcm! – add UnusedChecking(_enum) below;
std::unique_lock< RecursiveMutex > RecursiveLock
unsigned __int64 uint64_t
UInt128 magicCookieAndTid