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

📄 dtlstransport.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 2 页
字号:
#ifdef USE_DTLS#if defined(HAVE_CONFIG_H)  #include "resip/stack/config.hxx"#endif#include <memory>#ifndef RESIP_COMPAT_HXX#include "rutil/compat.hxx"#endif#ifndef RESIP_DATA_HXX#include "rutil/Data.hxx"#endif#ifndef RESIP_DNSUTIL_HXX#include "rutil/DnsUtil.hxx"#endif#ifndef RESIP_SOCKET_HXX#include "rutil/Socket.hxx"#endif#ifndef RESIP_LOGGER_HXX#include "rutil/Logger.hxx"#endif#ifndef RESIP_SIPMESSAGE_HXX#include "resip/stack/SipMessage.hxx"#endif#ifndef RESIP_HELPER_HXX#include "resip/stack/Helper.hxx"#endif#ifndef RESIP_SECURITY_HXX#include "resip/stack/Security.hxx"#endif#ifndef RESIP_DTLSMESSAGE_HXX#include "resip/stack/DtlsMessage.hxx"#endif#ifndef RESIP_DTLSTRANSPORT_HXX#include "resip/stack/DtlsTransport.hxx"#endif#include "rutil/WinLeakCheck.hxx"#include <openssl/e_os2.h>#include <openssl/evp.h>#include <openssl/crypto.h>#include <openssl/err.h>#include <openssl/pem.h>#include <openssl/pkcs7.h>#include <openssl/x509v3.h>#include <openssl/ssl.h>#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;DtlsTransport::DtlsTransport(Fifo<TransactionMessage>& fifo,                             int portNum,                             IpVersion version,                             const Data& interfaceObj,                             Security& security,                             const Data& sipDomain,                             Compression& compression)                             : UdpTransport( fifo, portNum, version,                                  StunDisabled, interfaceObj, 0, compression ),                               mTimer( mHandshakePending ),                               mSecurity( &security ),                               mDomain(sipDomain){   setTlsDomain(sipDomain);      InfoLog ( << "Creating DTLS transport host=" << interfaceObj              << " port=" << portNum             << " ipv4=" << version ) ;   mTuple.setType( transport() );   mClientCtx = SSL_CTX_new( DTLSv1_client_method() ) ;   mServerCtx = SSL_CTX_new( DTLSv1_server_method() ) ;   assert( mClientCtx ) ;   assert( mServerCtx ) ;   mDummyBio = BIO_new( BIO_s_mem() ) ;   assert( mDummyBio ) ;   mSendData = NULL ;   /* trying to read from this BIO always returns retry */   BIO_set_mem_eof_return( mDummyBio, -1 ) ;}DtlsTransport::~DtlsTransport(){   DebugLog (<< "Shutting down " << mTuple);   while(mDtlsConnections.begin() != mDtlsConnections.end())   {       _cleanupConnectionState(mDtlsConnections.begin()->second, mDtlsConnections.begin()->first);   }          SSL_CTX_free(mClientCtx);mClientCtx=0;     SSL_CTX_free(mServerCtx);mServerCtx=0;     BIO_free( mDummyBio) ;}voidDtlsTransport::_read( FdSet& fdset ){   //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...   unsigned int bufferLen = UdpTransport::MaxBufferSize + 5 ;   char* buffer = new char[ bufferLen ] ;   unsigned char *pt = new unsigned char[ bufferLen ] ;   SSL *ssl ;   BIO *rbio ;   BIO *wbio ;      // !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,                       UdpTransport::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 >= UdpTransport::MaxBufferSize )   {      InfoLog (<<"Datagram exceeded max length "<<UdpTransport::MaxBufferSize ) ;      delete [] buffer ; buffer = 0 ;      return ;   }   //DebugLog ( << "UDP Rcv : " << len << " b" );   //DebugLog ( << Data(buffer, len).escaped().c_str());      /* begin SSL stuff */   struct sockaddr peer = tuple.getMutableSockaddr() ;   ssl = mDtlsConnections[ *((struct sockaddr_in *)&peer) ] ;   /*     * If we don't have a binding for this peer,    * then we're a server.    */   if ( ssl == NULL )   {      ssl = SSL_new( mServerCtx ) ;      assert( ssl ) ;      SSL_set_accept_state( ssl ) ;      X509 *cert = mSecurity->getDomainCert( mDomain ) ;      EVP_PKEY *pkey = mSecurity->getDomainKey( mDomain ) ;      if( !cert )      {         Data error = Data("Could not load certifiacte for domain: ")              + mDomain;         throw Security::Exception( error,__FILE__, __LINE__ ) ;      }      if( !pkey )      {         Data error = Data("Could not load private key for domain: ")              + mDomain;         throw Security::Exception( error,__FILE__, __LINE__ ) ;      }      assert( cert ) ;      assert( pkey ) ;      if( ! SSL_use_certificate( ssl, cert ) )      {         throw Security::Exception( "SSL_use_certificate failed",                                   __FILE__, __LINE__ ) ;      }      if ( ! SSL_use_PrivateKey( ssl, pkey ) )         throw Security::Exception( "SSL_use_PrivateKey failed.",                                   __FILE__, __LINE__ ) ;      wbio = BIO_new_dgram( mFd, BIO_NOCLOSE ) ;      assert( wbio ) ;      BIO_dgram_set_peer( wbio, &peer ) ;      SSL_set_bio( ssl, NULL, wbio ) ;      /* remember this connection */      mDtlsConnections[ *((struct sockaddr_in *)&peer) ] = ssl ;   }   rbio = BIO_new_mem_buf( buffer, len ) ;   BIO_set_mem_eof_return( rbio, -1 ) ;   ssl->rbio = rbio ;   len = SSL_read( ssl, pt, UdpTransport::MaxBufferSize ) ;   int err = SSL_get_error( ssl, len ) ;   /* done with the rbio */   BIO_free( ssl->rbio ) ;   ssl->rbio = mDummyBio ;   delete [] buffer ;   buffer = 0 ;   if ( len <= 0 )   {      switch( err )      {         case SSL_ERROR_NONE:            break ;         case SSL_ERROR_SSL:            break ;         case SSL_ERROR_WANT_READ:            break ;         case SSL_ERROR_WANT_WRITE:            break ;         case SSL_ERROR_SYSCALL:            break ;            /* connection closed */         case SSL_ERROR_ZERO_RETURN:            _cleanupConnectionState( ssl, *((struct sockaddr_in *)&peer) ) ;            break ;         case SSL_ERROR_WANT_CONNECT:            break ;         case SSL_ERROR_WANT_ACCEPT:            break ;         default:            break ;      }   }   if ( len <= 0 )       return ;   if ( SSL_in_init( ssl ) )      mTimer.add( ssl, DtlsReceiveTimeout ) ;#ifdef USE_SIGCOMP   osc::StateChanges *sc = 0;#endif   if ((pt[0] & 0xf8) == 0xf8)   {      if(!mCompression.isEnabled())      {        InfoLog(<< "Discarding unexpected SigComp message");        delete [] pt;        return;      }#ifdef USE_SIGCOMP      unsigned char *newPt = new unsigned char[ bufferLen ] ;      size_t uncompressedLength =        mSigcompStack->uncompressMessage(pt, len,                                         newPt, UdpTransport::MaxBufferSize,                                         sc);      DebugLog (<< "Unompressed message from "                << len << " bytes to "                 << uncompressedLength << " bytes");      osc::SigcompMessage *nack = mSigcompStack->getNack();      if (nack)      {        mTxFifo.add(new SendData(tuple,                                 Data(nack->getDatagramMessage(),                                      nack->getDatagramLength()),                                 Data::Empty,                                 Data::Empty,                                 true)                   );        delete nack;      }      delete[] buffer;      buffer = newBuffer;      len = uncompressedLength;#endif   }   SipMessage* message = new SipMessage(this);      // set the received from information into the received= parameter in the   // via      // It is presumed that UDP Datagrams are arriving atomically and that   // each one is a unique SIP message         // Save all the info where this message came from   tuple.transport = this ;   message->setSource( tuple ) ;   //DebugLog (<< "Received from: " << tuple);      // Tell the SipMessage about this datagram buffer.   message->addBuffer( (char *)pt ) ;      mMsgHeaderScanner.prepareForMessage( message ) ;      char *unprocessedCharPtr ;   if (mMsgHeaderScanner.scanChunk( (char *)pt,                                    len,                                    &unprocessedCharPtr ) !=       MsgHeaderScanner::scrEnd)   {      DebugLog( << "Scanner rejecting datagram as unparsable / fragmented from "                 << tuple ) ;      DebugLog( << Data( pt, len ) ) ;      delete message ;      message = 0 ;      return ;

⌨️ 快捷键说明

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