00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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
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
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
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 }
00216