int OsNatSocketBaseImpl::handleTurnDataIndication(char* buffer, int bufferLength, UtlString* pRecvFromIp, int* pRecvFromPort) { int rc = 0 ; TurnMessage msg ; if (msg.parse(buffer, bufferLength)) { char* pData ; uint16_t nData ; if (msg.getData(pData, nData)) { assert(pData) ; assert(nData < bufferLength) ; if (pData && nData < bufferLength) { memcpy(buffer, pData, nData) ; rc = nData ; if (pRecvFromIp || pRecvFromPort) { char remoteAddr[32] ; uint16_t remotePort ; if (msg.getTurnRemoteAddress(remoteAddr, remotePort)) { if (pRecvFromIp) *pRecvFromIp = remoteAddr ; if (pRecvFromPort) *pRecvFromPort = remotePort ; } } } } } return rc ; }
bool StunUtils::allocateTurnAddress(OsDatagramSocket* pSocket, const char* szServerIp, const int port, char* szRelayIp, unsigned short* piRelayPort, unsigned long* plLifetime) { bool bSuccess = false ; TurnMessage msgSend ; size_t nLength ; char cMsgSend[2048] ; TurnMessage msgReceive ; char cMsgReceive[2048] ; msgSend.allocTransactionId() ; msgSend.setType(MSG_TURN_ALLOCATE_REQUEST) ; msgSend.setRequestXorOnly() ; if (msgSend.encode(cMsgSend, sizeof(cMsgSend), nLength)) { for (int i=0; (i<3) && (bSuccess == false); i++) { if (pSocket->write(cMsgSend, (int) nLength, szServerIp, port) > 0) { if (pSocket->isReadyToRead(500)) { int length = pSocket->read(cMsgReceive, sizeof(cMsgReceive)) ; if ((length > 0) && msgReceive.parse(cMsgReceive, length)) { if (msgReceive.getType() == MSG_TURN_ALLOCATE_RESPONSE) { bSuccess = true ; // Get optional mapped address if (szRelayIp && piRelayPort) { msgReceive.getMappedAddress(szRelayIp, *piRelayPort) ; } if (plLifetime) { msgReceive.getLifetime(*plLifetime) ; } } else { // Abort on error response break ; } } } } else { break ; } } } else { assert(false) ; } return bSuccess ; }