reSIProcate/stack  9694
DtlsTransport.hxx
Go to the documentation of this file.
00001 
00002 #if defined(HAVE_CONFIG_H)
00003   #include "config.h"
00004 #endif
00005 
00006 #if !defined(RESIP_DTLSTRANSPORT_HXX)
00007 #define RESIP_DTLSTRANSPORT_HXX
00008 
00009 #ifdef USE_DTLS
00010 
00011 #ifndef RESIP_UDPTRANSPORT_HXX
00012 #include "resip/stack/UdpTransport.hxx"
00013 #endif
00014 
00015 #ifndef RESIP_TIMERQUEUE_HXX
00016 #include "resip/stack/TimerQueue.hxx"
00017 #endif
00018 
00019 #ifndef RESIP_SENDDATA_HXX
00020 #include "resip/stack/SendData.hxx"
00021 #endif
00022 
00023 #ifndef RESIP_HEAPINSTANCECOUNTER_HXX
00024 #include "rutil/HeapInstanceCounter.hxx"
00025 #endif
00026 
00027 #ifndef RESIP_HASHMAP_HXX
00028 #include "rutil/HashMap.hxx"
00029 #endif
00030 
00031 #include <map>
00032 #include <openssl/ssl.h>
00033 
00034 #include "resip/stack/Compression.hxx"
00035 
00036 namespace resip
00037 {
00038 
00039 class Security;
00040 class TransactionMessage;
00041 class UdpTransport;
00042 class DtlsMessage;
00043 
00044 class DtlsTransport : public UdpTransport
00045 {
00046 #if  defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310))  // !slg! not sure if this works on __INTEL_COMPILER 
00047    struct sockaddr_in_hash_compare
00048    {
00049       enum { bucket_size = 4, min_buckets = 8 };
00050 
00051       size_t operator()(const struct sockaddr_in& sock) const 
00052       { 
00053           return sock.sin_addr.s_addr; 
00054       }
00055       bool operator()(const struct sockaddr_in& s1, 
00056                       const struct sockaddr_in& s2) const
00057       {
00058          if ( (s1.sin_addr.s_addr < s2.sin_addr.s_addr) ||
00059               ( (s1.sin_addr.s_addr == s2.sin_addr.s_addr ) &&
00060                 ( s1.sin_port < s2.sin_port) ) )
00061          {
00062              return 1;
00063          }
00064          else
00065          {
00066             return 0;
00067          }
00068       }
00069    };
00070 #elif defined(HASH_MAP_NAMESPACE)
00071    struct addr_hash
00072    {
00073       size_t operator()( const struct sockaddr_in sock ) const
00074       {
00075          return sock.sin_addr.s_addr ;
00076       }            
00077    };
00078      
00079    struct addr_cmp
00080    { 
00081       bool operator()(const struct sockaddr_in& s1, 
00082                       const struct sockaddr_in& s2) const
00083       {
00084          if ( ( s1.sin_addr.s_addr == s2.sin_addr.s_addr ) &&
00085               ( s1.sin_port == s2.sin_port) )
00086          {
00087             return 1;
00088          }
00089          else
00090          {
00091             return 0;
00092          }
00093       }
00094    };
00095 #else
00096    struct addr_less
00097    { 
00098       bool operator()(const struct sockaddr_in& s1, 
00099                       const struct sockaddr_in& s2) const
00100       {
00101          if ( (s1.sin_addr.s_addr < s2.sin_addr.s_addr) ||
00102               ( (s1.sin_addr.s_addr == s2.sin_addr.s_addr ) &&
00103                 ( s1.sin_port < s2.sin_port) ) )
00104          {
00105              return 1;
00106          }
00107          else
00108          {
00109             return 0;
00110          }
00111       }
00112    };
00113 #endif
00114 
00115    public:
00116       RESIP_HeapCount(DtlsTransport);
00117       // Specify which udp port to use for send and receive
00118       // interface can be an ip address or dns name. If it is an ip address,
00119       // only bind to that interface.
00120       DtlsTransport(Fifo<TransactionMessage>& fifo,
00121                     int portNum,
00122                     IpVersion version,
00123                     const Data& interfaceObj,
00124                     Security& security,
00125                     const Data& sipDomain,
00126                     AfterSocketCreationFuncPtr socketFunc = 0,
00127                     Compression &compression = Compression::Disabled);
00128       virtual  ~DtlsTransport();
00129 
00130       void process(FdSet& fdset);
00131       bool isReliable() const { return false; }
00132       bool isDatagram() const { return true; }
00133       TransportType transport() const { return DTLS; }
00134       virtual void buildFdSet( FdSet& fdset);
00135 
00136       static const unsigned long DtlsReceiveTimeout = 250000 ;
00137 
00138    private:
00139 
00140 #if  defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310))
00141       typedef HashMap<struct sockaddr_in, 
00142                       SSL*, 
00143                       DtlsTransport::sockaddr_in_hash_compare> DtlsConnectionMap;
00144 #elif defined(HASH_MAP_NAMESPACE)
00145       typedef HashMap<struct sockaddr_in, 
00146                       SSL*, 
00147                       DtlsTransport::addr_hash, 
00148                       DtlsTransport::addr_cmp> DtlsConnectionMap ;
00149 #else
00150       typedef std::map<struct sockaddr_in, 
00151                       SSL*, 
00152                       DtlsTransport::addr_less> DtlsConnectionMap ;
00153 #endif
00154 
00155       SSL_CTX             *mClientCtx ;
00156       SSL_CTX             *mServerCtx ;
00157       MsgHeaderScanner    mMsgHeaderScanner;
00158       static const int    MaxBufferSize;
00159       Fifo<DtlsMessage>   mHandshakePending ;
00160       DtlsTimerQueue      mTimer ;
00161       Security*           mSecurity ;
00162       DtlsConnectionMap   mDtlsConnections ;  /* IP addr/port -> transport */
00163       unsigned char       mDummyBuf[ 4 ] ;
00164       BIO*                mDummyBio ;
00165       const Data          mDomain;
00166 
00167       SendData            *mSendData ;/* Data that was unqueued from mTxFifo, 
00168                                        * but unable to send because a handshake
00169                                        * was in progress 
00170                                        */
00171       
00172       void _read( FdSet& fdset ) ;
00173       void _write( FdSet& fdset ) ;
00174       void _doHandshake() ;
00175       void _cleanupConnectionState( SSL *ssl, struct sockaddr_in peer ) ;
00176 
00177       void _mapDebug( const char *where, const char *action, SSL *ssl ) ;
00178       void _printSock( const struct sockaddr_in *sock ) ;
00179 };
00180 
00181 }
00182 
00183 #endif /* USE_DTLS */
00184 
00185 #endif /* ! RESIP_DTLSTRANSPORT_HXX */
00186 
00187 /* ====================================================================
00188  * The Vovida Software License, Version 1.0 
00189  * 
00190  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00191  * 
00192  * Redistribution and use in source and binary forms, with or without
00193  * modification, are permitted provided that the following conditions
00194  * are met:
00195  * 
00196  * 1. Redistributions of source code must retain the above copyright
00197  *    notice, this list of conditions and the following disclaimer.
00198  * 
00199  * 2. Redistributions in binary form must reproduce the above copyright
00200  *    notice, this list of conditions and the following disclaimer in
00201  *    the documentation and/or other materials provided with the
00202  *    distribution.
00203  * 
00204  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00205  *    and "Vovida Open Communication Application Library (VOCAL)" must
00206  *    not be used to endorse or promote products derived from this
00207  *    software without prior written permission. For written
00208  *    permission, please contact vocal@vovida.org.
00209  *
00210  * 4. Products derived from this software may not be called "VOCAL", nor
00211  *    may "VOCAL" appear in their name, without prior written
00212  *    permission of Vovida Networks, Inc.
00213  * 
00214  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00215  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00216  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00217  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00218  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00219  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00220  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00221  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00222  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00223  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00224  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00225  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00226  * DAMAGE.
00227  * 
00228  * ====================================================================
00229  * 
00230  * This software consists of voluntary contributions made by Vovida
00231  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00232  * Inc.  For more information on Vovida Networks, Inc., please see
00233  * <http://www.vovida.org/>.
00234  *
00235  */