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

📄 udptransport.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 2 页
字号:
#if defined(HAVE_CONFIG_H)#include "resip/stack/config.hxx"#endif#include <memory>#include "resip/stack/Helper.hxx"#include "resip/stack/SendData.hxx"#include "resip/stack/SipMessage.hxx"#include "resip/stack/UdpTransport.hxx"#include "rutil/Data.hxx"#include "rutil/DnsUtil.hxx"#include "rutil/Logger.hxx"#include "rutil/Socket.hxx"#include "rutil/WinLeakCheck.hxx"#include "rutil/compat.hxx"#include "rutil/stun/Stun.hxx"#ifdef USE_SIGCOMP#include <osc/Stack.h>#include <osc/StateChanges.h>#include <osc/SigcompMessage.h>#endif#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORTusing namespace std;using namespace resip;UdpTransport::UdpTransport(Fifo<TransactionMessage>& fifo,                           int portNum,                             IpVersion version,                           StunSetting stun,                           const Data& pinterface,                           AfterSocketCreationFuncPtr socketFunc,                           Compression &compression)    : InternalTransport(fifo, portNum, version, pinterface, socketFunc, compression),     mSigcompStack(0){   InfoLog (<< "Creating UDP transport host=" << pinterface             << " port=" << portNum            << " ipv4=" << bool(version==V4) );   mTuple.setType(transport());   mFd = InternalTransport::socket(transport(), version);   mTuple.mFlowKey=mFd;   bind();#ifdef USE_SIGCOMP   if (mCompression.isEnabled())   {      DebugLog (<< "Compression enabled for transport: " << *this);      mSigcompStack = new osc::Stack(mCompression.getStateHandler());      mCompression.addCompressorsToStack(mSigcompStack);   }   else   {      DebugLog (<< "Compression disabled for transport: " << *this);   }#else   DebugLog (<< "No compression library available: " << *this);#endif}UdpTransport::~UdpTransport(){   InfoLog (<< "Shutting down " << mTuple);#ifdef USE_SIGCOMP   delete mSigcompStack;#endif}void UdpTransport::process(FdSet& fdset){   // pull buffers to send out of TxFifo   // receive datagrams from fd   // preparse and stuff into RxFifo   if (mTxFifo.messageAvailable() && fdset.readyToWrite(mFd))   {      std::auto_ptr<SendData> sendData = std::auto_ptr<SendData>(mTxFifo.getNext());      //DebugLog (<< "Sent: " <<  sendData->data);      //DebugLog (<< "Sending message on udp.");      assert( &(*sendData) );      assert( sendData->destination.getPort() != 0 );            const sockaddr& addr = sendData->destination.getSockaddr();      int expected;      int count;#ifdef USE_SIGCOMP      // If message needs to be compressed, compress it here.      if (mSigcompStack &&          sendData->sigcompId.size() > 0 &&          !sendData->isAlreadyCompressed )      {          osc::SigcompMessage *sm = mSigcompStack->compressMessage            (sendData->data.data(), sendData->data.size(),             sendData->sigcompId.data(), sendData->sigcompId.size(),             isReliable());          DebugLog (<< "Compressed message from "                    << sendData->data.size() << " bytes to "                     << sm->getDatagramLength() << " bytes");          expected = sm->getDatagramLength();          count = sendto(mFd,                          sm->getDatagramMessage(),                         sm->getDatagramLength(),                         0, // flags                         &addr, sendData->destination.length());          delete sm;      }      else#endif      {          expected = sendData->data.size();          count = sendto(mFd,                          sendData->data.data(), sendData->data.size(),                           0, // flags                         &addr, sendData->destination.length());      }            if ( count == SOCKET_ERROR )      {         int e = getErrno();         error(e);         InfoLog (<< "Failed (" << e << ") sending to " << sendData->destination);         fail(sendData->transactionId);      }      else      {         if (count != expected)         {            ErrLog (<< "UDPTransport - send buffer full" );            fail(sendData->transactionId);         }      }   }      // !jf! this may have to change - when we read a message that is too big   if ( fdset.readyToRead(mFd) )   {      //should this buffer be allocated on the stack and then copied out, as it      //needs to be deleted every time EWOULDBLOCK is encountered      // .dlb. can we determine the size of the buffer before we allocate?      // something about MSG_PEEK|MSG_TRUNC in Stevens..      // .dlb. RFC3261 18.1.1 MUST accept 65K datagrams. would have to attempt to      // adjust the UDP buffer as well...      char* buffer = MsgHeaderScanner::allocateBuffer(MaxBufferSize);            // !jf! how do we tell if it discarded bytes       // !ah! we use the len-1 trick :-(      Tuple tuple(mTuple);      socklen_t slen = tuple.length();      int len = recvfrom( mFd,                          buffer,                          MaxBufferSize,                          0 /*flags */,                          &tuple.getMutableSockaddr(),                           &slen);      if ( len == SOCKET_ERROR )      {         int err = getErrno();         if ( err != EWOULDBLOCK  )         {            error( err );         }      }      if (len == 0 || len == SOCKET_ERROR)      {         delete[] buffer;          buffer=0;         return;      }      if (len+1 >= MaxBufferSize)      {         InfoLog(<<"Datagram exceeded max length "<<MaxBufferSize);         delete [] buffer; buffer=0;         return;      }      //handle incoming CRLFCRLF keep-alive packets      if (len == 4 &&          strncmp(buffer, Symbols::CRLFCRLF, len) == 0)      {         delete[] buffer;         buffer = 0;         StackLog(<<"Throwing away incoming firewall keep-alive");         return;      }      // this must be a STUN response (or garbage)      if (buffer[0] == 1 && buffer[1] == 1 && ipVersion() == V4)      {         resip::Lock lock(myMutex);         StunMessage resp;         memset(&resp, 0, sizeof(StunMessage));               if (stunParseMessage(buffer, len, resp, false))         {            in_addr sin_addr;#if defined(WIN32)            sin_addr.S_un.S_addr = htonl(resp.mappedAddress.ipv4.addr);#else            sin_addr.s_addr = htonl(resp.mappedAddress.ipv4.addr);#endif            mStunMappedAddress = Tuple(sin_addr,resp.mappedAddress.ipv4.port, UDP);            mStunSuccess = true;         }         delete[] buffer;         buffer = 0;         return;      }      // this must be a STUN request (or garbage)      if (buffer[0] == 0 && buffer[1] == 1 && ipVersion() == V4)      {         bool changePort = false;         bool changeIp = false;                  StunAddress4 myAddr;         const sockaddr_in& bi = (const sockaddr_in&)boundInterface();         myAddr.addr = ntohl(bi.sin_addr.s_addr);         myAddr.port = ntohs(bi.sin_port);                  StunAddress4 from; // packet source         const sockaddr_in& fi = (const sockaddr_in&)tuple.getSockaddr();         from.addr = ntohl(fi.sin_addr.s_addr);         from.port = ntohs(fi.sin_port);                  StunMessage resp;         StunAddress4 dest;         StunAtrString hmacPassword;           hmacPassword.sizeValue = 0;                  StunAddress4 secondary;         secondary.port = 0;         secondary.addr = 0;                  bool ok = stunServerProcessMsg( buffer, len, // input buffer                                         from,  // packet source                                         secondary, // not used                                         myAddr, // address to fill into response                                         myAddr, // not used                                         &resp, // stun response                                         &dest, // where to send response                                         &hmacPassword, // not used                                         &changePort, // not used                                         &changeIp, // not used                                         false ); // logging                  if (ok)         {            DebugLog(<<"Got UDP STUN keepalive. Sending response...");            char* response = new char[STUN_MAX_MESSAGE_SIZE];            int rlen = stunEncodeMessage( resp,                                           response,                                           STUN_MAX_MESSAGE_SIZE,                                           hmacPassword,

⌨️ 快捷键说明

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