Socket.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2004 Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2005 Novell, Inc. All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 *  - Redistributions of source code must retain the above copyright notice,
00009 *    this list of conditions and the following disclaimer.
00010 *
00011 *  - Redistributions in binary form must reproduce the above copyright notice,
00012 *    this list of conditions and the following disclaimer in the documentation
00013 *    and/or other materials provided with the distribution.
00014 *
00015 *  - Neither the name of Vintela, Inc., Novell, Inc., nor the names of its
00016 *    contributors may be used to endorse or promote products derived from this
00017 *    software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc., Novell, Inc., OR THE 
00023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 *******************************************************************************/
00031 
00032 
00038 #include "blocxx/BLOCXX_config.h"
00039 #include "blocxx/Socket.hpp"
00040 #include "blocxx/UnnamedPipe.hpp"
00041 #include "blocxx/Assertion.hpp"
00042 #include "blocxx/MutexLock.hpp"
00043 #include "blocxx/SSLException.hpp"
00044 #include "blocxx/Exception.hpp"
00045 #include "blocxx/IOException.hpp"
00046 #include "blocxx/ExceptionIds.hpp"
00047 #include "blocxx/SocketImpl.hpp"
00048 #include "blocxx/SSLSocketImpl.hpp"
00049 #include <errno.h>
00050 
00051 
00052 namespace BLOCXX_NAMESPACE
00053 {
00054 
00055 BLOCXX_DEFINE_EXCEPTION_WITH_ID(Socket);
00056 BLOCXX_DEFINE_EXCEPTION_WITH_ID(SocketTimeout);
00057 
00058 Socket::ShutDownMechanism_t Socket::s_shutDownMechanism = 0;
00059 
00061 Socket::Socket()
00062    : m_impl(new SocketImpl)
00063 {
00064 }
00066 Socket::Socket(const SSLClientCtxRef& sslCtx)
00067 {
00068    if (sslCtx)
00069    {
00070 #ifndef BLOCXX_NO_SSL
00071       m_impl = SocketBaseImplRef(new SSLSocketImpl(sslCtx));
00072 #else
00073       BLOCXX_THROW(SSLException, "Not built with SSL");
00074 #endif // #ifndef BLOCXX_NO_SSL
00075    }
00076    else
00077    {
00078       m_impl = SocketBaseImplRef(new SocketImpl);
00079    }
00080 }
00081 
00083 Socket::Socket(SocketHandle_t fd,
00084    SocketAddress::AddressType addrType, SocketFlags::ESSLFlag isSSL)
00085 {
00086    if (isSSL == SocketFlags::E_SSL)
00087    {
00088 #ifndef BLOCXX_NO_SSL
00089       m_impl = SocketBaseImplRef(new SSLSocketImpl(fd, addrType));
00090 #else
00091       BLOCXX_THROW(SSLException, "Not built with SSL");
00092 #endif // #ifndef BLOCXX_NO_SSL
00093    }
00094    else
00095    {
00096       m_impl = SocketBaseImplRef(new SocketImpl(fd, addrType));
00097    }
00098 }
00100 // Used by ServerSocket2::accept()
00101 Socket::Socket(SocketHandle_t fd,
00102    SocketAddress::AddressType addrType, const SSLServerCtxRef& sslCtx)
00103 {
00104    if (sslCtx)
00105    {
00106 #ifndef BLOCXX_NO_SSL
00107       m_impl = SocketBaseImplRef(new SSLSocketImpl(fd, addrType, sslCtx));
00108 #else
00109       BLOCXX_THROW(SSLException, "Not built with SSL");
00110 #endif // #ifndef BLOCXX_NO_SSL
00111    }
00112    else
00113    {
00114       m_impl = SocketBaseImplRef(new SocketImpl(fd, addrType));
00115    }
00116 }
00118 Socket::Socket(const SocketAddress& addr, SocketFlags::ESSLFlag isSSL)
00119 {
00120    if (isSSL == SocketFlags::E_SSL)
00121    {
00122 #ifndef BLOCXX_NO_SSL
00123       m_impl = SocketBaseImplRef(new SSLSocketImpl(addr));
00124 #else
00125       BLOCXX_THROW(SSLException, "Not built with SSL");
00126 #endif // #ifndef BLOCXX_NO_SSL
00127    }
00128    else
00129    {
00130       m_impl = SocketBaseImplRef(new SocketImpl(addr));
00131    }
00132 }
00133 static bool b_gotShutDown = false;
00134 static Mutex shutdownMutex;
00136 // STATIC
00137 void
00138 Socket::shutdownAllSockets()
00139 {
00140    MutexLock mlock(shutdownMutex);
00141 
00142    BLOCXX_ASSERT(s_shutDownMechanism != 0);
00143    if (!s_shutDownMechanism)
00144    {
00145       return;
00146    }
00147 
00148    b_gotShutDown = true;
00149 #if defined(BLOCXX_WIN32)
00150    ::SetEvent(s_shutDownMechanism);
00151 #else
00152    if (s_shutDownMechanism->writeString("die!") == -1)
00153    {
00154       BLOCXX_THROW_ERRNO_MSG(IOException, "Failed writing to socket shutdown pipe");
00155    }
00156 #endif
00157 }
00159 // STATIC
00160 void
00161 Socket::createShutDownMechanism()
00162 {
00163    MutexLock mlock(shutdownMutex);
00164    if (!s_shutDownMechanism)
00165    {
00166 #if defined(BLOCXX_WIN32)
00167       s_shutDownMechanism = ::CreateEvent(0, TRUE, FALSE, 0);
00168       BLOCXX_ASSERT(s_shutDownMechanism != 0);
00169 #else
00170       s_shutDownMechanism = UnnamedPipe::createUnnamedPipe();
00171       s_shutDownMechanism->setBlocking(UnnamedPipe::E_NONBLOCKING);
00172 #endif
00173       b_gotShutDown = false;
00174    }
00175 }
00177 // STATIC
00178 void
00179 Socket::deleteShutDownMechanism()
00180 {
00181    MutexLock mlock(shutdownMutex);
00182    if (s_shutDownMechanism)
00183    {
00184 #if defined(BLOCXX_WIN32)
00185       ::CloseHandle(s_shutDownMechanism);
00186 #endif
00187       s_shutDownMechanism = 0;
00188    }
00189 }
00190 #ifndef BLOCXX_NO_SSL
00191 SSL*
00192 Socket::getSSL() const
00193 {
00194    IntrusiveReference<SSLSocketImpl> sslsock = m_impl.cast_to<SSLSocketImpl>(); 
00195    if (!sslsock)
00196    {
00197       return 0; 
00198    }
00199    return sslsock->getSSL(); 
00200 }
00201 
00203 bool
00204 Socket::peerCertVerified() const
00205 {
00206     IntrusiveReference<SSLSocketImpl> sslsock = m_impl.cast_to<SSLSocketImpl>(); 
00207     if (!sslsock)
00208     {
00209             return false; 
00210     }
00211     return sslsock->peerCertVerified(); 
00212 }
00213 #endif
00214 
00215 } // end namespace BLOCXX_NAMESPACE
00216 

Generated on Fri Jun 16 15:39:09 2006 for blocxx by  doxygen 1.4.6