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

📄 turnasyncsocket.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
            handleStunMessage(*stunMsg);            delete stunMsg;         }         else         {            RemotePeer* remotePeer = mChannelManager.findRemotePeerByServerToClientChannel(channelNumber);            if(remotePeer)            {               data->offset(4);  // move buffer start past framing for callback               if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveSuccess(getSocketDescriptor(),                                                          remotePeer->getPeerTuple().getAddress(),                                                          remotePeer->getPeerTuple().getPort(),                                                          data);            }            else            {               WarningLog(<< "TurnAsyncSocket::handleReceivedData: receive channel data for non-existing channel - discarding!");            }         }      }      else  // size <= 4      {         WarningLog(<< "TurnAsyncSocket::handleReceivedData: not enought data received for framed message - discarding!");         if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveFailure(getSocketDescriptor(), asio::error_code(reTurn::FrameError, asio::error::misc_category));               }   }   else   {      // mTurnFraming is disabled - message could be a Stun Message if first byte is 0 or 1      if((*data)[0] == 0 || (*data)[0] == 1)      {         StunMessage* stunMsg = new StunMessage(mLocalBinding,                                                 StunTuple(mLocalBinding.getTransportType(), mAsyncSocketBase.getConnectedAddress(), mAsyncSocketBase.getConnectedPort()),                                                 &(*data)[0], data->size());         if(stunMsg->isValid())         {            handleStunMessage(*stunMsg);            delete stunMsg;            return;         }         delete stunMsg;      }      // Not a stun message so assume normal data      if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveSuccess(getSocketDescriptor(),                                                    address,                                                    port,                                                    data);   }}asio::error_code TurnAsyncSocket::handleStunMessage(StunMessage& stunMessage){   asio::error_code errorCode;   if(stunMessage.isValid())   {      if(!stunMessage.checkMessageIntegrity(mHmacKey))      {         WarningLog(<< "TurnAsyncSocket::handleStunMessage: Stun message integrity is bad!");         return asio::error_code(reTurn::BadMessageIntegrity, asio::error::misc_category);      }      // Request is authenticated, process it      switch(stunMessage.mClass)      {       case StunMessage::StunClassRequest:         switch (stunMessage.mMethod)          {         case StunMessage::BindMethod:            errorCode = handleBindRequest(stunMessage);            break;         case StunMessage::SharedSecretMethod:         case StunMessage::TurnAllocateMethod:         case StunMessage::TurnRefreshMethod:         default:            // These requests are not handled by a client            StunMessage* response = new StunMessage();            response->mClass = StunMessage::StunClassErrorResponse;            response->setErrorCode(400, "Invalid Request Method");              // Copy over TransactionId            response->mHeader.magicCookieAndTid = stunMessage.mHeader.magicCookieAndTid;            sendStunMessage(response);            break;         }         break;      case StunMessage::StunClassIndication:         switch (stunMessage.mMethod)          {         case StunMessage::TurnDataMethod:             errorCode = handleDataInd(stunMessage);            break;         case StunMessage::TurnChannelConfirmationMethod:            errorCode = handleChannelConfirmation(stunMessage);            break;                 case StunMessage::BindMethod:            // A Bind indication is simply a keepalive with no response required            break;         case StunMessage::TurnSendMethod:  // Don't need to handle these - only sent by client, never received         default:            // Unknown indication - just ignore            break;         }         break;         case StunMessage::StunClassSuccessResponse:      case StunMessage::StunClassErrorResponse:      {         // First check if this response if for an active request         RequestMap::iterator it = mActiveRequestMap.find(stunMessage.mHeader.magicCookieAndTid);         if(it == mActiveRequestMap.end())         {            // Stray response - dropping            return asio::error_code(reTurn::StrayResponse, asio::error::misc_category);         }         else         {            it->second->stopTimer();            // If a realm and nonce attributes are present and the response is a 401 or 438 (Nonce Expired),             // then re-issue request with new auth attributes            if(stunMessage.mHasRealm &&               stunMessage.mHasNonce &&               stunMessage.mHasErrorCode &&                stunMessage.mErrorCode.errorClass == 4 &&               ((stunMessage.mErrorCode.number == 1 && mHmacKey.empty()) ||  // Note if 401 error then ensure we haven't already tried once - if we've tried then mHmacKey will be populated               stunMessage.mErrorCode.number == 38))            {               mNonce = *stunMessage.mNonce;               mRealm = *stunMessage.mRealm;               MD5Stream r;               r << mUsername << ":" << mRealm << ":" << mPassword;               mHmacKey = r.getHex();               // Create a new transaction - by starting with old request               StunMessage* newRequest = it->second->mRequestMessage;               it->second->mRequestMessage = 0;  // clear out pointer in mActiveRequestMap so that it will not be deleted               mActiveRequestMap.erase(it);               newRequest->createHeader(newRequest->mClass, newRequest->mMethod);  // updates TID               newRequest->mHasMessageIntegrity = true;               newRequest->setUsername(mUsername.c_str());                newRequest->mHmacKey = mHmacKey;               newRequest->setRealm(mRealm.c_str());               newRequest->setNonce(mNonce.c_str());               sendStunMessage(newRequest);               return errorCode;            }                      mActiveRequestMap.erase(it);         }         switch (stunMessage.mMethod)          {         case StunMessage::BindMethod:            errorCode = handleBindResponse(stunMessage);            break;         case StunMessage::SharedSecretMethod:            errorCode = handleSharedSecretResponse(stunMessage);            break;         case StunMessage::TurnAllocateMethod:            errorCode = handleAllocateResponse(stunMessage);            break;         case StunMessage::TurnRefreshMethod:            errorCode = handleRefreshResponse(stunMessage);            break;         default:            // Unknown method - just ignore            break;         }      }      break;      default:         // Illegal message class - ignore         break;      }   }   else   {      WarningLog(<< "TurnAsyncSocket::handleStunMessage: Read Invalid StunMsg.");      return asio::error_code(reTurn::ErrorParsingMessage, asio::error::misc_category);   }   return errorCode;}asio::error_codeTurnAsyncSocket::handleDataInd(StunMessage& stunMessage){   if(!stunMessage.mHasTurnPeerAddress || !stunMessage.mHasTurnChannelNumber)   {      // Missing RemoteAddress or ChannelNumber attribute      WarningLog(<< "TurnAsyncSocket::handleDataInd: DataInd missing attributes.");      return asio::error_code(reTurn::MissingAttributes, asio::error::misc_category);   }   StunTuple remoteTuple;   remoteTuple.setTransportType(mRelayTransportType);   StunMessage::setTupleFromStunAtrAddress(remoteTuple, stunMessage.mTurnPeerAddress);   RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(remoteTuple);   if(!remotePeer)   {      // Remote Peer not found - discard data      WarningLog(<< "TurnAsyncSocket::handleDataInd: Data received from unknown RemotePeer " << remoteTuple << " - discarding");      return asio::error_code(reTurn::UnknownRemoteAddress, asio::error::misc_category);   }   if(remotePeer->getServerToClientChannel() != 0 && remotePeer->getServerToClientChannel() != stunMessage.mTurnChannelNumber)   {      // Mismatched channel number      WarningLog(<< "TurnAsyncSocket::handleDataInd: Channel number received in DataInd (" << (int)stunMessage.mTurnChannelNumber << ") does not match existing number for RemotePeer (" << (int)remotePeer->getServerToClientChannel() << ").");      return asio::error_code(reTurn::InvalidChannelNumberReceived, asio::error::misc_category);   }   if(!remotePeer->isServerToClientChannelConfirmed())   {      remotePeer->setServerToClientChannel(stunMessage.mTurnChannelNumber);      remotePeer->setServerToClientChannelConfirmed();      mChannelManager.addRemotePeerServerToClientChannelLookup(remotePeer);   }   if(mLocalBinding.getTransportType() == StunTuple::UDP)   {      // If UDP, then send TurnChannelConfirmationInd      StunMessage* channelConfirmationInd = createNewStunMessage(StunMessage::StunClassIndication, StunMessage::TurnChannelConfirmationMethod, false);      channelConfirmationInd->mHasTurnPeerAddress = true;      channelConfirmationInd->mTurnPeerAddress = stunMessage.mTurnPeerAddress;      channelConfirmationInd->mHasTurnChannelNumber = true;      channelConfirmationInd->mTurnChannelNumber = stunMessage.mTurnChannelNumber;      // send channelConfirmationInd to local client      sendStunMessage(channelConfirmationInd);   }   if(stunMessage.mHasTurnData)   {      boost::shared_ptr<DataBuffer> data(new DataBuffer(stunMessage.mTurnData->data(), stunMessage.mTurnData->size()));      if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveSuccess(getSocketDescriptor(),          remoteTuple.getAddress(),          remoteTuple.getPort(),          data);   }   return asio::error_code();}asio::error_codeTurnAsyncSocket::handleChannelConfirmation(StunMessage &stunMessage){   if(!stunMessage.mHasTurnPeerAddress || !stunMessage.mHasTurnChannelNumber)   {      // Missing RemoteAddress or ChannelNumber attribute      WarningLog(<< "TurnAsyncSocket::handleChannelConfirmation: DataInd missing attributes.");      return asio::error_code(reTurn::MissingAttributes, asio::error::misc_category);   }   StunTuple remoteTuple;   remoteTuple.setTransportType(mRelayTransportType);   StunMessage::setTupleFromStunAtrAddress(remoteTuple, stunMessage.mTurnPeerAddress);   RemotePeer* remotePeer = mChannelManager.findRemotePeerByClientToServerChannel(stunMessage.mTurnChannelNumber);   if(!remotePeer)   {      // Remote Peer not found - discard      WarningLog(<< "TurnAsyncSocket::handleChannelConfirmation: Received ChannelConfirmationInd for unknown channel (" << stunMessage.mTurnChannelNumber << ") - discarding");      return asio::error_code(reTurn::InvalidChannelNumberReceived, asio::error::misc_category);   }   if(remotePeer->getPeerTuple() != remoteTuple)   {      // Mismatched remote address      WarningLog(<< "TurnAsyncSocket::handleChannelConfirmation: RemoteAddress associated with channel (" << remotePeer->getPeerTuple() << ") does not match ChannelConfirmationInd (" << remoteTuple << ").");      return asio::error_code(reTurn::UnknownRemoteAddress, asio::error::misc_category);   }   remotePeer->setClientToServerChannelConfirmed();   return asio::error_code();}asio::error_code TurnAsyncSocket::handleSharedSecretResponse(StunMessage& stunMessage){   if(stunMessage.mClass == StunMessage::StunClassSuccessResponse)   {      // Copy username and password to callers buffer - checking sizes first      if(!stunMessage.mHasUsername || !stunMessage.mHasPassword)      {         WarningLog(<< "TurnAsyncSocket::handleSharedSecretResponse: Stun response message for SharedSecretRequest is missing username and/or password!");         if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category));         return asio::error_code(MissingAttributes, asio::error::misc_category);      }      if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretSuccess(getSocketDescriptor(), stunMessage.mUsername->c_str(), stunMessage.mUsername->size(),                                                                             stunMessage.mPassword->c_str(), stunMessage.mPassword->size());   }   else   {      // Check if success or not      if(stunMessage.mHasErrorCode)      {         if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretFailure(getSocketDescriptor(), asio::error_code(stunMessage.mErrorCode.errorClass * 100 + stunMessage.mErrorCode.number, asio::error::misc_category));      }      else      {         if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category));         return asio::error_code(MissingAttributes, asio::error::misc_category);      }   }   return asio::error_code();}asio::error_codeTurnAsyncSocket::handleBindRequest(StunMessage& stunMessage){   // Note: handling of BindRequest is not fully backwards compatible with RFC3489 - it is inline with bis13   StunMessage* response = new StunMessage();   // form the outgoing message   response->mClass = StunMessage::StunClassSuccessResponse;   response->mMethod = StunMessage::BindMethod;   // Copy over TransactionId   response->mHeader.magicCookieAndTid = stunMessage.mHeader.magicCookieAndTid;   // Add XOrMappedAddress to response    response->mHasXorMappedAddress = true;   StunMessage::setStunAtrAddressFromTuple(response->mXorMappedAddress, stunMessage.mRemoteTuple);   // send bindResponse to local client   sendStunMessage(response);   return asio::error_code();}asio::error_code TurnAsyncSocket::handleBindResponse(StunMessage& stunMessage){   if(stunMessage.mClass == StunMessage::StunClassSuccessResponse)   {      StunTuple reflexiveTuple;      reflexiveTuple.setTransportType(mLocalBinding.getTransportType());      if(stunMessage.mHasXorMappedAddress)      {         StunMessage::setTupleFromStunAtrAddress(reflexiveTuple, stunMessage.mXorMappedAddress);      }      else if(stunMessage.mHasMappedAddress)  // Only look at MappedAddress if XorMappedAddress is not found - for backwards compatibility      {         StunMessage::setTupleFromStunAtrAddress(reflexiveTuple, stunMessage.mMappedAddress);      }      else      {         if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category));         return asio::error_code(MissingAttributes, asio::error::misc_category);      }      if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindSuccess(getSocketDescriptor(), reflexiveTuple);   }   else   {      // Check if success or not      if(stunMessage.mHasErrorCode)      {         if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindFailure(getSocketDescriptor(), asio::error_code(stunMessage.mErrorCode.errorClass * 100 + stunMessage.mErrorCode.number, asio::error::misc_category));      }      else      {         if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category));         return asio::error_code(MissingAttributes, asio::error::misc_category);      }   }   return asio::error_code();}asio::error_code TurnAsyncSocket::handleAllocateResponse(StunMessage& stunMessage){   if(stunMessage.mClass == StunMessage::StunClassSuccessResponse)   {      StunTuple reflexiveTuple;      StunTuple relayTuple;      if(stunMessage.mHasXorMappedAddress)      {         reflexiveTuple.setTransportType(mLocalBinding.getTransportType());         StunMessage::setTupleFromStunAtrAddress(reflexiveTuple, stunMessage.mXorMappedAddress);      }      if(stunMessage.mHasTurnRelayAddress)      {         relayTuple.setTransportType(mRelayTransportType);         StunMessage::setTupleFromStunAtrAddress(relayTuple, stunMessage.mTurnRelayAddress);      }      if(stunMessage.mHasTurnLifetime)      {         mLifetime = stunMessage.mTurnLifetime;      }      else      {         mLifetime = 0;      }      // All was well - return 0 errorCode      if(mLifetime != 0)      {         mHaveAllocation = true;         startAllocationTimer();         if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationSuccess(getSocketDescriptor(), reflexiveTuple, relayTuple, mLifetime, stunMessage.mHasTurnBandwidth ? stunMessage.mTurnBandwidth : 0);      }      else      {         if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category));

⌨️ 快捷键说明

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