summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSL.cpp56
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSL.h2
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSLClient.cpp12
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSLServer.cpp12
4 files changed, 52 insertions, 30 deletions
diff --git a/cpp/src/Ice/SslConnectionOpenSSL.cpp b/cpp/src/Ice/SslConnectionOpenSSL.cpp
index 4b20df70f60..1502e6d2d5b 100644
--- a/cpp/src/Ice/SslConnectionOpenSSL.cpp
+++ b/cpp/src/Ice/SslConnectionOpenSSL.cpp
@@ -145,20 +145,44 @@ IceSecurity::Ssl::OpenSSL::Connection::renegotiate()
int
IceSecurity::Ssl::OpenSSL::Connection::initialize(int timeout)
{
- HandshakeSentinel handshakeSentinel(_handshakeFlag);
-
ICE_METHOD_INV("OpenSSL::Connection::initialize()");
- int retCode;
-
- if (!handshakeSentinel.ownHandshake())
- {
- // We don't own the handshake, we can't go any further.
- retCode = -1;
- }
- else
+ int retCode = 0;
+
+ while (true)
{
- retCode = init(timeout);
+ // One lucky thread will get the honor of carrying out the hanshake,
+ // if there is one to perform. The HandshakeSentinel effectively
+ // establishes a first-come, first-serve policy. One thread will own
+ // the handshake, and the others will either return rejected to the
+ // caller (who will figure out what to do with them) OR wait until
+ // our lead thread is done. Then, the shuffle begins again.
+ // Eventually, all threads will filter through.
+
+ HandshakeSentinel handshakeSentinel(_handshakeFlag);
+
+ if (!handshakeSentinel.ownHandshake())
+ {
+ if (timeout >= 0)
+ {
+ // We should return immediately here - do not block,
+ // leave it to the caller to figure this out.
+ retCode = -1;
+ break;
+ }
+ else
+ {
+ // We will wait here - blocking IO is being used.
+ IceUtil::Mutex::Lock sync(_handshakeWaitMutex);
+ }
+ }
+ else
+ {
+ // Perform our init(), then leave.
+ IceUtil::Mutex::Lock sync(_handshakeWaitMutex);
+ retCode = init(timeout);
+ break;
+ }
}
ICE_METHOD_RET("OpenSSL::Connection::initialize()");
@@ -447,16 +471,19 @@ IceSecurity::Ssl::OpenSSL::Connection::readSSL(Buffer& buf, int timeout)
int bytesPending;
int bytesRead;
+ int initReturn = 0;
+
// We keep reading until we're done.
while (buf.i != buf.b.end())
{
// Ensure we're initialized.
- int initReturn = initialize(timeout);
+ initReturn = initialize(timeout);
+/////
if (initReturn == -1)
{
- // Handshake underway, we should just return with what we've got (even if that's nothing).
- break;
+ // Handshake underway, timeout immediately, easy way to deal with this.
+ throw TimeoutException(__FILE__, __LINE__);
}
if (initReturn == 0)
@@ -464,6 +491,7 @@ IceSecurity::Ssl::OpenSSL::Connection::readSSL(Buffer& buf, int timeout)
// Retry the initialize call
continue;
}
+/////
// initReturn must be > 0, so we're okay to try a write
diff --git a/cpp/src/Ice/SslConnectionOpenSSL.h b/cpp/src/Ice/SslConnectionOpenSSL.h
index df956c789f9..8404cc78330 100644
--- a/cpp/src/Ice/SslConnectionOpenSSL.h
+++ b/cpp/src/Ice/SslConnectionOpenSSL.h
@@ -175,6 +175,8 @@ protected:
Buffer _inBuffer;
::IceUtil::Mutex _inBufferMutex;
+ ::IceUtil::Mutex _handshakeWaitMutex;
+
TraceLevelsPtr _traceLevels;
LoggerPtr _logger;
diff --git a/cpp/src/Ice/SslConnectionOpenSSLClient.cpp b/cpp/src/Ice/SslConnectionOpenSSLClient.cpp
index 88a1fc0547b..093854fb46d 100644
--- a/cpp/src/Ice/SslConnectionOpenSSLClient.cpp
+++ b/cpp/src/Ice/SslConnectionOpenSSLClient.cpp
@@ -259,19 +259,15 @@ IceSecurity::Ssl::OpenSSL::ClientConnection::write(Buffer& buf, int timeout)
}
#endif
+ int initReturn = 0;
+
// We keep reading until we're done
while (buf.i != buf.b.end())
{
// Ensure we're initialized.
- int initReturn = initialize(timeout);
-
- if (initReturn == -1)
- {
- // Handshake underway, we should just return with what we've got (even if that's nothing).
- break;
- }
+ initReturn = initialize(timeout);
- if (initReturn == 0)
+ if (initReturn <= 0)
{
// Retry the initialize call
continue;
diff --git a/cpp/src/Ice/SslConnectionOpenSSLServer.cpp b/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
index 3cd05384efc..a2df6549699 100644
--- a/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
+++ b/cpp/src/Ice/SslConnectionOpenSSLServer.cpp
@@ -282,19 +282,15 @@ IceSecurity::Ssl::OpenSSL::ServerConnection::write(Buffer& buf, int timeout)
}
#endif
+ int initReturn = 0;
+
// We keep writing until we're done.
while (buf.i != buf.b.end())
{
// Ensure we're initialized.
- int initReturn = initialize(timeout);
-
- if (initReturn == -1)
- {
- // Handshake underway, we should just return with what we've got (even if that's nothing).
- break;
- }
+ initReturn = initialize(timeout);
- if (initReturn == 0)
+ if (initReturn <= 0)
{
// Retry the initialize call
continue;