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

📄 dtlstransport.cxx

📁 一个著名的SIP协议栈
💻 CXX
📖 第 1 页 / 共 2 页
字号:
   }
   
   // no pp error
   int used = unprocessedCharPtr - (char *)pt ;

   if ( used < len )
   {
      // body is present .. add it up.
      // NB. The Sip Message uses an overlay (again)
      // for the body. It ALSO expects that the body
      // will be contiguous (of course).
      // it doesn't need a new buffer in UDP b/c there
      // will only be one datagram per buffer. (1:1 strict)
      
      message->setBody( (char *)pt + used, len - used ) ;
      //DebugLog(<<"added " << len-used << " byte body");
   }
   
   if ( ! basicCheck( *message ) )
   {
      delete message ; // cannot use it, so, punt on it...
      // basicCheck queued any response required
      message = 0 ;
      return ;
   }
   
   stampReceived( message) ;

#ifdef USE_SIGCOMP
      if (mCompression.isEnabled() && sc)
      {
        const Via &via = message->header(h_Vias).front();
        if (message->isRequest())
        {
          // For requests, the compartment ID is read out of the
          // top via header field; if not present, we use the
          // TCP connection for identification purposes.
          if (via.exists(p_sigcompId))
          {
            Data compId = via.param(p_sigcompId);
            mSigcompStack->provideCompartmentId(
                             sc, compId.data(), compId.size());
          }
          else
          {
            mSigcompStack->provideCompartmentId(sc, this, sizeof(this));
          }
        }
        else
        {
          // For responses, the compartment ID is supposed to be
          // the same as the compartment ID of the request. We
          // *could* dig down into the transaction layer to try to
          // figure this out, but that's a royal pain, and a rather
          // severe layer violation. In practice, we're going to ferret
          // the ID out of the the Via header field, which is where we
          // squirreled it away when we sent this request in the first place.
          Data compId = via.param(p_branch).getSigcompCompartment();
          mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size());
        }

      }
#endif
   
   mStateMachineFifo.add( message ) ;
}

void DtlsTransport::_write( FdSet& fdset )
{
   SSL *ssl ;
   BIO *wBio ;
   int retry = 0 ;

   SendData *sendData ;
   if ( mSendData != NULL )
       sendData = mSendData ;
   else
       sendData = mTxFifo.getNext() ;

   //DebugLog (<< "Sent: " <<  sendData->data);
   //DebugLog (<< "Sending message on udp.");
   
   assert( &(*sendData) );
   assert( sendData->destination.getPort() != 0 );
   
   sockaddr peer = sendData->destination.getSockaddr();
   
   ssl = mDtlsConnections[ *((struct sockaddr_in *)&peer) ] ;

   /* If we don't have a binding, then we're a client */
   if ( ssl == NULL )
   {
      ssl = SSL_new( mClientCtx ) ;
      assert( ssl ) ;

      SSL_set_connect_state( ssl ) ;

      wBio = BIO_new_dgram( mFd, BIO_NOCLOSE ) ;
      assert( wBio ) ;
      
      BIO_dgram_set_peer( wBio, &peer) ;

      /* the real rbio will be set by _read */
      SSL_set_bio( ssl, mDummyBio, wBio ) ;

      /* we should be ready to take this out if the 
       * connection fails later */
      mDtlsConnections [ *((struct sockaddr_in *)&peer) ] = ssl ;
   }

   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 = SSL_Write(ssl,
                         sm->getDatagramMessage(),
                         sm->getDatagramLength());
       delete sm;
   }
   else
#endif
   {
      expected = sendData->data.size();

      count = SSL_write(ssl, sendData->data.data(), 
                        sendData->data.size());
   }

   /* 
    * all reads go through _read, so the most likely result during a handshake 
    * will be SSL_ERROR_WANT_READ 
    */

   if ( count <= 0 )
   {
      /* cache unqueued data */
      mSendData = sendData ; 

      int err = SSL_get_error( ssl, count ) ;
      switch( err )
      {
         case SSL_ERROR_NONE:
            break;
         case SSL_ERROR_SSL:
            break;
         case SSL_ERROR_WANT_READ:
            retry = 1 ;
            break;
         case SSL_ERROR_WANT_WRITE:         
             retry = 1 ;
             fdset.setWrite(mFd);
            break;
         case SSL_ERROR_SYSCALL:
            {
               int e = getErrno();
               error(e);
               InfoLog (<< "Failed (" << e << ") sending to " 
                        << sendData->destination);
               fail(sendData->transactionId);
               break;
            }
         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 ;
      }
   }
   else
   {
      mSendData = NULL ;
   }

   /* 
    * ngm: is sendData deleted by a higher layer?  Seems to be the case after 
    * checking with UdpTransport
    */
   
   if ( ! retry && count != int(sendData->data.size()) )
   {
      ErrLog (<< "UDPTransport - send buffer full" );
      fail(sendData->transactionId);
   }
}

void
DtlsTransport::_doHandshake( void )
{
   DtlsMessage *msg = mHandshakePending.getNext() ;
   SSL *ssl = msg->getSsl() ;

   delete msg ;

   int ret = SSL_do_handshake( ssl ) ;

   switch( ret )
   {
     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;
         case SSL_ERROR_ZERO_RETURN:
            break;
         case SSL_ERROR_WANT_CONNECT:
            break;
         case SSL_ERROR_WANT_ACCEPT:
            break;
         default:
            break ;
   }
}

void 
DtlsTransport::process(FdSet& fdset)
{
   // pull buffers to send out of TxFifo
   // receive datagrams from fd
   // preparse and stuff into RxFifo

   mTimer.process() ;

   while ( mHandshakePending.messageAvailable() )
      _doHandshake() ;

   if ( ( mSendData != NULL || mTxFifo.messageAvailable() )
       && fdset.readyToWrite( mFd ) )
      _write( fdset ) ;
   
   // !jf! this may have to change - when we read a message that is too big
   if ( fdset.readyToRead(mFd) )
      _read( fdset ) ;
}


void 
DtlsTransport::buildFdSet( FdSet& fdset )
{
   fdset.setRead(mFd);
    
   if ( mSendData != NULL || mTxFifo.messageAvailable() )
   {
     fdset.setWrite(mFd);
   }
}

void
DtlsTransport::_cleanupConnectionState( SSL *ssl, struct sockaddr_in peer )
{
   /* 
    * SSL_free decrements the ref-count for mDummyBio by 1, so
    * add 1 to the ref-count to make sure it does not get free'd
    */
   CRYPTO_add( &mDummyBio->references, 1, CRYPTO_LOCK_BIO ) ;
   SSL_free( ssl ) ;
   mDtlsConnections.erase( peer ) ;
}

void
DtlsTransport::_mapDebug( const char *where, const char *action, SSL *ssl )
{
   fprintf( stderr, "%s: %s\t%p\n", where, action, ssl ) ;
   fprintf( stderr, "map sizet = %d\n", mDtlsConnections.size() ) ;
}

void
DtlsTransport::_printSock( const struct sockaddr_in *sock )
{
   fprintf( stderr, "addr = %s\t port = %d\n", inet_ntoa( sock->sin_addr ), 
            ntohs( sock->sin_port ) ) ;
}

#endif /* USE_DTLS */

/* ====================================================================
 * The Vovida Software License, Version 1.0 
 * 
 * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
 *    and "Vovida Open Communication Application Library (VOCAL)" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact vocal@vovida.org.
 *
 * 4. Products derived from this software may not be called "VOCAL", nor
 *    may "VOCAL" appear in their name, without prior written
 *    permission of Vovida Networks, Inc.
 * 
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by Vovida
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
 * Inc.  For more information on Vovida Networks, Inc., please see
 * <http://www.vovida.org/>.
 *
 */

⌨️ 快捷键说明

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