⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 turnsocket.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
      mRequestedIpAddress = UnspecifiedIpAddress;      return refreshAllocation();   }   else   {      return asio::error_code(reTurn::NoAllocation, asio::error::misc_category);    }}StunTuple& TurnSocket::getRelayTuple(){   return mRelayTuple;}StunTuple& TurnSocket::getReflexiveTuple(){   return mReflexiveTuple;}unsigned int TurnSocket::getLifetime(){   return mLifetime;}unsigned int TurnSocket::getBandwidth(){   return mBandwidth;}asio::error_code TurnSocket::setActiveDestination(const asio::ip::address& address, unsigned short port){   asio::error_code errorCode;   resip::Lock lock(mMutex);   // ensure there is an allocation   if(!mHaveAllocation)   {      if(mConnected)      {         // TODO - Disconnect      }      return connect(address.to_string(), port);      //return asio::error_code(reTurn::NoAllocation, asio::error::misc_category);    }   // Ensure Connected   if(!mConnected)   {      return asio::error_code(reTurn::NotConnected, asio::error::misc_category);    }   // Setup Remote Peer    StunTuple remoteTuple(mRelayTuple.getTransportType(), address, port);   RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(remoteTuple);   if(remotePeer)   {      mActiveDestination = remotePeer;   }   else   {      // No remote peer yet (ie. not data sent or received from remote peer) - so create one      mActiveDestination = mChannelManager.createRemotePeer(remoteTuple, mChannelManager.getNextChannelNumber(), 0);      assert(mActiveDestination);   }   return errorCode;}asio::error_code TurnSocket::clearActiveDestination(){   asio::error_code errorCode;   resip::Lock lock(mMutex);   // ensure there is an allocation   if(!mHaveAllocation)   {      return asio::error_code(reTurn::NoAllocation, asio::error::misc_category);    }   mActiveDestination = 0;   return errorCode;}asio::error_code TurnSocket::send(const char* buffer, unsigned int size){   // Allow raw data to be sent if there is no allocation   if(!mHaveAllocation)   {      return rawWrite(buffer, size);   }   if(!mActiveDestination)   {      return asio::error_code(reTurn::NoActiveDestination, asio::error::misc_category);    }   return sendTo(*mActiveDestination, buffer, size);}asio::error_code TurnSocket::sendTo(const asio::ip::address& address, unsigned short port, const char* buffer, unsigned int size){   resip::Lock lock(mMutex);   // ensure there is an allocation    if(!mHaveAllocation)   {      return asio::error_code(reTurn::NoAllocation, asio::error::misc_category);    }   // Setup Remote Peer    StunTuple remoteTuple(mRelayTuple.getTransportType(), address, port);   RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(remoteTuple);   if(!remotePeer)   {      // No remote peer yet (ie. not data sent or received from remote peer) - so create one      remotePeer = mChannelManager.createRemotePeer(remoteTuple, mChannelManager.getNextChannelNumber(), 0);      assert(remotePeer);   }   return sendTo(*remotePeer, buffer, size);}asio::error_code TurnSocket::sendTo(RemotePeer& remotePeer, const char* buffer, unsigned int size){   resip::Lock lock(mMutex);   // Check to see if an allocation refresh is required - if so send it and make sure it was sucessful   asio::error_code ret = checkIfAllocationRefreshRequired();   if(ret)   {      return ret;   }   if(remotePeer.isClientToServerChannelConfirmed())   {      // send framed data to active destination      char framing[4];      unsigned short channelNumber = remotePeer.getClientToServerChannel();      channelNumber = htons(channelNumber);      memcpy(&framing[0], &channelNumber, 2);      if(mLocalBinding.getTransportType() == StunTuple::UDP)      {         // No size in header for UDP         framing[2] = 0x00;         framing[3] = 0x00;      }      else      {         UInt16 turnDataSize = size;         turnDataSize = htons(turnDataSize);         memcpy((void*)&framing[2], &turnDataSize, 2);      }      std::vector<asio::const_buffer> bufs;      bufs.push_back(asio::buffer(framing, sizeof(framing)));      bufs.push_back(asio::buffer(buffer, size));      return rawWrite(bufs);   }   else   {      // Data must be wrapped in a Send Indication      // Wrap data in a SendInd      StunMessage ind;      ind.createHeader(StunMessage::StunClassIndication, StunMessage::TurnSendMethod);      ind.mHasTurnPeerAddress = true;      ind.mTurnPeerAddress.port = remotePeer.getPeerTuple().getPort();      if(remotePeer.getPeerTuple().getAddress().is_v6())      {         ind.mTurnPeerAddress.family = StunMessage::IPv6Family;         memcpy(&ind.mTurnPeerAddress.addr.ipv6, remotePeer.getPeerTuple().getAddress().to_v6().to_bytes().c_array(), sizeof(ind.mTurnPeerAddress.addr.ipv6));      }      else      {         ind.mTurnPeerAddress.family = StunMessage::IPv4Family;         ind.mTurnPeerAddress.addr.ipv4 = remotePeer.getPeerTuple().getAddress().to_v4().to_ulong();      }      ind.mHasTurnChannelNumber = true;      ind.mTurnChannelNumber = remotePeer.getClientToServerChannel();      if(size > 0)      {         ind.setTurnData(buffer, size);      }      // If not using UDP - then mark channel as confirmed      if(mLocalBinding.getTransportType() != StunTuple::UDP)      {         remotePeer.setClientToServerChannelConfirmed();      }      // Send indication to Turn Server      unsigned int msgsize = ind.stunEncodeFramedMessage(mWriteBuffer, sizeof(mWriteBuffer));      return rawWrite(mWriteBuffer, msgsize);   }}asio::error_code TurnSocket::receive(char* buffer, unsigned int& size, unsigned int timeout, asio::ip::address* sourceAddress, unsigned short* sourcePort){   asio::error_code errorCode;   resip::Lock lock(mMutex);   bool done = false;   // TODO - rethink this scheme so that we don't need to copy recieved data   // TODO - if we loop around more than once - timeout needs to be adjusted   while(!done)   {      done = true;      // Wait for response      unsigned int readSize;      errorCode = rawRead(timeout, &readSize, sourceAddress, sourcePort); // Note: SourceAddress and sourcePort may be overwritten below if from Turn Relay      if(errorCode)      {         return errorCode;      }      // Note if this is a UDP RFC3489 back compat socket, then allocations are not allowed and handleRawData will always be used      if(!mHaveAllocation)      {         return handleRawData(mReadBuffer, readSize, readSize, buffer, size);      }      // Check Channel      if(readSize > 4)      {         unsigned short channelNumber;         memcpy(&channelNumber, &mReadBuffer[0], 2);         channelNumber = ntohs(channelNumber);         if(channelNumber > 0)         {            RemotePeer* remotePeer = mChannelManager.findRemotePeerByServerToClientChannel(channelNumber);            if(remotePeer)            {               UInt16 dataLen;               memcpy(&dataLen, &mReadBuffer[2], 2);               dataLen = ntohs(dataLen);                  if(sourceAddress)               {                  *sourceAddress = remotePeer->getPeerTuple().getAddress();               }               if(sourcePort)               {                  *sourcePort = remotePeer->getPeerTuple().getPort();               }               errorCode = handleRawData(&mReadBuffer[4], readSize-4, dataLen, buffer, size);            }            else            {               // Invalid ServerToClient Channel - teardown?               errorCode = asio::error_code(reTurn::InvalidChannelNumberReceived, asio::error::misc_category);                 done = true;            }         }         else // We have received a Stun/Turn Message         {            // StunMessage            StunMessage* stunMsg = new StunMessage(mLocalBinding, mConnectedTuple, &mReadBuffer[4], readSize-4);            unsigned int tempsize = size;            errorCode = handleStunMessage(*stunMsg, buffer, tempsize, sourceAddress, sourcePort);            if(!errorCode && tempsize == 0)  // Signifies that a Stun/Turn request was received and there is nothing to return to receive caller            {               done = false;            }            else            {               size = tempsize;            }         }      }      else      {         // Less data than frame size received         errorCode = asio::error_code(reTurn::FrameError, asio::error::misc_category);         done = true;      }   }   return errorCode;}asio::error_code TurnSocket::receiveFrom(const asio::ip::address& address, unsigned short port, char* buffer, unsigned int& size, unsigned int timeout){   asio::ip::address sourceAddress;   unsigned short sourcePort;   bool done = false;   asio::error_code errorCode;   resip::Lock lock(mMutex);   while(!done)   {      done = true;      errorCode = receive(buffer, size, timeout, &sourceAddress, &sourcePort);      if(!errorCode)      {         if(sourceAddress != address || sourcePort != port)         {            WarningLog(<< "Recevied message but not from requested address/port - Discarding.");            done = false;         }      }   }   return errorCode;}asio::error_code TurnSocket::handleRawData(char* data, unsigned int dataSize, unsigned int expectedSize, char* buffer, unsigned int& bufferSize){   asio::error_code errorCode;   if(dataSize != expectedSize)   {      // TODO - fix read logic so that we can read in chuncks      WarningLog(<< "Did not read entire message: read=" << dataSize << " wanted=" << expectedSize);      return asio::error_code(reTurn::ReadError, asio::error::misc_category);    }   if(dataSize > bufferSize)    {     // Passed in buffer is not large enough     WarningLog(<< "Passed in buffer not large enough.");     return asio::error_code(reTurn::BufferTooSmall, asio::error::misc_category);    }   // Copy data to return buffer   memcpy(buffer, data, dataSize);   bufferSize = dataSize;   return errorCode;}asio::error_code TurnSocket::handleStunMessage(StunMessage& stunMessage, char* buffer, unsigned int& size, asio::ip::address* sourceAddress, unsigned short* sourcePort){   asio::error_code errorCode;   if(stunMessage.isValid())   {      if(stunMessage.mClass == StunMessage::StunClassIndication && stunMessage.mMethod == StunMessage::TurnDataMethod)      {         if(!stunMessage.mHasTurnPeerAddress || !stunMessage.mHasTurnChannelNumber)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -