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

📄 turnsocket.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
#include "TurnSocket.hxx"#include "ErrorCode.hxx"#include <boost/bind.hpp>#include <rutil/Lock.hxx>#include <rutil/WinLeakCheck.hxx>#include <rutil/Logger.hxx>#include "../ReTurnSubsystem.hxx"#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURNusing namespace std;#define UDP_RT0 100  // RTO - Estimate of Roundtrip time - 100ms is recommened for fixed line transport - the initial value should be configurable                     // Should also be calculation this on the fly#define UDP_MAX_RETRANSMITS  7       // Defined by RFC3489-bis11#define TCP_RESPONSE_TIME 7900       // Defined by RFC3489-bis11#define UDP_FINAL_REQUEST_TIME (UDP_RT0 * 16)  // Defined by RFC3489-bis11namespace reTurn {// Initialize static membersunsigned int TurnSocket::UnspecifiedLifetime = 0xFFFFFFFF;unsigned int TurnSocket::UnspecifiedBandwidth = 0xFFFFFFFF; unsigned short TurnSocket::UnspecifiedPort = 0;asio::ip::address TurnSocket::UnspecifiedIpAddress = asio::ip::address::from_string("0.0.0.0");TurnSocket::TurnSocket(const asio::ip::address& address, unsigned short port) :    mLocalBinding(StunTuple::None /* Set properly by sub class */, address, port),   mHaveAllocation(false),   mActiveDestination(0),   mReadTimer(mIOService),   mConnected(false){}TurnSocket::~TurnSocket(){}asio::error_code TurnSocket::requestSharedSecret(char* username, unsigned int usernameSize,                                 char* password, unsigned int passwordSize){   asio::error_code errorCode;   resip::Lock lock(mMutex);   // Should we check here if TLS and deny?   // Ensure Connected   if(!mConnected)   {      return asio::error_code(reTurn::NotConnected, asio::error::misc_category);    }   // Form Shared Secret request   StunMessage request;   request.createHeader(StunMessage::StunClassRequest, StunMessage::SharedSecretMethod);   // Get Response   StunMessage* response = sendRequestAndGetResponse(request, errorCode);   if(response == 0)   {      return errorCode;   }   // Check if success or not   if(response->mHasErrorCode)   {      errorCode = asio::error_code(response->mErrorCode.errorClass * 100 + response->mErrorCode.number, asio::error::misc_category);      delete response;      return errorCode;   }   // Copy username and password to callers buffer - checking sizes first   if(!response->mHasUsername || !response->mHasPassword)   {      WarningLog(<< "Stun response message for SharedSecretRequest is missing username and/or password!");      errorCode = asio::error_code(reTurn::MissingAuthenticationAttributes, asio::error::misc_category);        delete response;      return errorCode;   }   if(response->mUsername->size() > usernameSize || response->mPassword->size() > passwordSize)   {      WarningLog( << "Stun response message for SharedSecretRequest contains data that is too large to return!");      errorCode = asio::error_code(reTurn::BufferTooSmall, asio::error::misc_category);         delete response;      return errorCode;   }   // Copy username and password to passed in buffers   memcpy(username, response->mUsername->c_str(), response->mUsername->size()+1);   memcpy(password, response->mPassword->c_str(), response->mPassword->size()+1);   // All was well - return 0 errorCode   delete response;   return errorCode;}void TurnSocket::setUsernameAndPassword(const char* username, const char* password){   mUsername = username;   mPassword = password;}asio::error_code TurnSocket::bindRequest(){   asio::error_code errorCode;   resip::Lock lock(mMutex);   // Ensure Connected   if(!mConnected)   {      return asio::error_code(reTurn::NotConnected, asio::error::misc_category);    }   // Form Stun Bind request   StunMessage request;   request.createHeader(StunMessage::StunClassRequest, StunMessage::BindMethod);   if(!mUsername.empty())   {      request.mHasMessageIntegrity = true;      request.setUsername(mUsername.c_str());       request.mHmacKey = mPassword;   }   StunMessage* response = sendRequestAndGetResponse(request, errorCode);   if(response == 0)   {      return errorCode;   }   mReflexiveTuple.setTransportType(mLocalBinding.getTransportType());   if(response->mHasXorMappedAddress)   {      StunMessage::setTupleFromStunAtrAddress(mReflexiveTuple, response->mXorMappedAddress);   }   else if(response->mHasMappedAddress)  // Only look at MappedAddress if XorMappedAddress is not found - for backwards compatibility   {      StunMessage::setTupleFromStunAtrAddress(mReflexiveTuple, response->mMappedAddress);   }   // Check if success or not   if(response->mHasErrorCode)   {      errorCode = asio::error_code(response->mErrorCode.errorClass * 100 + response->mErrorCode.number, asio::error::misc_category);   }   delete response;   return errorCode;}asio::error_code TurnSocket::createAllocation(unsigned int lifetime,                             unsigned int bandwidth,                             unsigned short requestedPortProps,                              unsigned short requestedPort,                             StunTuple::TransportType requestedTransportType,                              const asio::ip::address &requestedIpAddress){   asio::error_code errorCode;   resip::Lock lock(mMutex);   // Store Allocation Properties   mRequestedLifetime = lifetime;   mRequestedBandwidth = bandwidth;   mRequestedPortProps = requestedPortProps;   mRequestedPort = requestedPort;   mRequestedTransportType = requestedTransportType;   mRequestedIpAddress = requestedIpAddress;   // Ensure Connected   if(!mConnected)   {      return asio::error_code(reTurn::NotConnected, asio::error::misc_category);    }   if(mHaveAllocation)   {      return asio::error_code(reTurn::AlreadyAllocated, asio::error::misc_category);    }   // Form Turn Allocate request   StunMessage request;   request.createHeader(StunMessage::StunClassRequest, StunMessage::TurnAllocateMethod);   if(mRequestedLifetime != UnspecifiedLifetime)   {      request.mHasTurnLifetime = true;      request.mTurnLifetime = mRequestedLifetime;   }   if(mRequestedBandwidth != UnspecifiedBandwidth)   {      request.mHasTurnBandwidth = true;      request.mTurnBandwidth = mRequestedBandwidth;   }   if(mRequestedTransportType != StunTuple::None && mRequestedTransportType != StunTuple::TLS)   {            request.mHasTurnRequestedTransport = true;      if(mRequestedTransportType == StunTuple::UDP)      {         request.mTurnRequestedTransport = StunMessage::RequestedTransportUdp;      }      else if(mRequestedTransportType == StunTuple::TCP &&              mLocalBinding.getTransportType() != StunTuple::UDP)  // Ensure client is not requesting TCP over a UDP transport      {         request.mTurnRequestedTransport = StunMessage::RequestedTransportTcp;      }      else      {         return asio::error_code(reTurn::InvalidRequestedTransport, asio::error::misc_category);       }   }   if(mRequestedIpAddress != UnspecifiedIpAddress)   {      request.mHasTurnRequestedIp = true;      StunTuple requestedIpTuple(StunTuple::None, requestedIpAddress, 0);      StunMessage::setStunAtrAddressFromTuple(request.mTurnRequestedIp, requestedIpTuple);   }   if(mRequestedPortProps != StunMessage::PortPropsNone || mRequestedPort != UnspecifiedPort)   {      request.mHasTurnRequestedPortProps = true;      request.mTurnRequestedPortProps.props = mRequestedPortProps;      request.mTurnRequestedPortProps.port = mRequestedPort;   }   request.mHasMessageIntegrity = true;   request.setUsername(mUsername.data());    request.mHmacKey = mPassword;   StunMessage* response = sendRequestAndGetResponse(request, errorCode);   if(response == 0)   {      return errorCode;   }   if(response->mHasXorMappedAddress)   {      mReflexiveTuple.setTransportType(mLocalBinding.getTransportType());      StunMessage::setTupleFromStunAtrAddress(mReflexiveTuple, response->mXorMappedAddress);   }   if(response->mHasTurnRelayAddress)   {      // Transport Type is requested type or socket type      if(request.mHasTurnRequestedTransport)      {         mRelayTuple.setTransportType(request.mHasTurnRequestedTransport == StunMessage::RequestedTransportUdp ? StunTuple::UDP : StunTuple::TCP);      }      else      {         mRelayTuple.setTransportType(mLocalBinding.getTransportType());        }      StunMessage::setTupleFromStunAtrAddress(mRelayTuple, response->mTurnRelayAddress);   }   if(response->mHasTurnLifetime)   {      mLifetime = response->mTurnLifetime;   }   if(response->mHasTurnBandwidth)   {      mBandwidth = response->mTurnBandwidth;   }   // Check if success or not   if(response->mHasErrorCode)   {      errorCode = asio::error_code(response->mErrorCode.errorClass * 100 + response->mErrorCode.number, asio::error::misc_category);      delete response;      return errorCode;   }   // All was well - return 0 errorCode   if(mLifetime != 0)   {      mHaveAllocation = true;      mAllocationRefreshTime = time(0) + ((mLifetime*5)/8);  // Allocation refresh should sent before 3/4 lifetime - use 5/8 lifetime   }   delete response;   return errorCode;}asio::error_code TurnSocket::refreshAllocation(){   asio::error_code errorCode;   resip::Lock lock(mMutex);   // Form Turn Allocate request   StunMessage request;   request.createHeader(StunMessage::StunClassRequest, StunMessage::TurnRefreshMethod);   if(mRequestedLifetime != UnspecifiedLifetime)   {      request.mHasTurnLifetime = true;      request.mTurnLifetime = mRequestedLifetime;   }   if(mRequestedBandwidth != UnspecifiedBandwidth)   {      request.mHasTurnBandwidth = true;      request.mTurnBandwidth = mRequestedBandwidth;   }   request.mHasMessageIntegrity = true;   request.setUsername(mUsername.data());    request.mHmacKey = mPassword;   StunMessage* response = sendRequestAndGetResponse(request, errorCode);   if(response == 0)   {      return errorCode;   }   // Check if success or not   if(response->mHasErrorCode)   {      if(mRequestedLifetime != 0)      {         mHaveAllocation = false;      }      errorCode = asio::error_code(response->mErrorCode.errorClass * 100 + response->mErrorCode.number, asio::error::misc_category);      delete response;      return errorCode;   }   // All was well - return 0 errorCode   if(mLifetime != 0)   {      mHaveAllocation = true;      mAllocationRefreshTime = time(0) + ((mLifetime*5)/8);  // Allocation refresh should sent before 3/4 lifetime - use 5/8 lifetime   }   else   {      mHaveAllocation = false;   }   delete response;   return errorCode;}asio::error_code TurnSocket::destroyAllocation(){   resip::Lock lock(mMutex);   if(mHaveAllocation)   {      mRequestedLifetime = 0;      mRequestedBandwidth = UnspecifiedBandwidth;      mRequestedPortProps = StunMessage::PortPropsNone;      mRequestedPort = UnspecifiedPort;      mRequestedTransportType = StunTuple::None;

⌨️ 快捷键说明

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